Path: blob/master/3rdparty/openexr/IlmImf/ImfCheckedArithmetic.h
16337 views
///////////////////////////////////////////////////////////////////////////1//2// Copyright (c) 2009, Industrial Light & Magic, a division of Lucas3// Digital Ltd. LLC4//5// All rights reserved.6//7// Redistribution and use in source and binary forms, with or without8// modification, are permitted provided that the following conditions are9// met:10// * Redistributions of source code must retain the above copyright11// notice, this list of conditions and the following disclaimer.12// * Redistributions in binary form must reproduce the above13// copyright notice, this list of conditions and the following disclaimer14// in the documentation and/or other materials provided with the15// distribution.16// * Neither the name of Industrial Light & Magic nor the names of17// its contributors may be used to endorse or promote products derived18// from this software without specific prior written permission.19//20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31//32///////////////////////////////////////////////////////////////////////////3334#ifndef INCLUDED_IMF_CHECKED_ARITHMETIC_H35#define INCLUDED_IMF_CHECKED_ARITHMETIC_H3637//-----------------------------------------------------------------------------38//39// Integer arithmetic operations that throw exceptions40// on overflow, underflow or division by zero.41//42//-----------------------------------------------------------------------------4344#include <limits>45#include <IexMathExc.h>4647namespace Imf {4849template <bool b> struct StaticAssertionFailed;50template <> struct StaticAssertionFailed <true> {};5152#define IMF_STATIC_ASSERT(x) \53do {StaticAssertionFailed <x> staticAssertionFailed;} while (false)545556template <class T>57T58uiMult (T a, T b)59{60//61// Unsigned integer multiplication62//6364IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&65std::numeric_limits<T>::is_integer);6667if (a > 0 && b > std::numeric_limits<T>::max() / a)68throw Iex::OverflowExc ("Integer multiplication overflow.");6970return a * b;71}727374template <class T>75T76uiDiv (T a, T b)77{78//79// Unsigned integer division80//8182IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&83std::numeric_limits<T>::is_integer);8485if (b == 0)86throw Iex::DivzeroExc ("Integer division by zero.");8788return a / b;89}909192template <class T>93T94uiAdd (T a, T b)95{96//97// Unsigned integer addition98//99100IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&101std::numeric_limits<T>::is_integer);102103if (a > std::numeric_limits<T>::max() - b)104throw Iex::OverflowExc ("Integer addition overflow.");105106return a + b;107}108109110template <class T>111T112uiSub (T a, T b)113{114//115// Unsigned integer subtraction116//117118IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&119std::numeric_limits<T>::is_integer);120121if (a < b)122throw Iex::UnderflowExc ("Integer subtraction underflow.");123124return a - b;125}126127128template <class T>129size_t130checkArraySize (T n, size_t s)131{132//133// Verify that the size, in bytes, of an array with n elements134// of size s can be computed without overflowing:135//136// If computing137//138// size_t (n) * s139//140// would overflow, then throw an Iex::OverflowExc exception.141// Otherwise return142//143// size_t (n).144//145146IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&147std::numeric_limits<T>::is_integer);148149IMF_STATIC_ASSERT (sizeof (T) <= sizeof (size_t));150151if (size_t (n) > std::numeric_limits<size_t>::max() / s)152throw Iex::OverflowExc ("Integer multiplication overflow.");153154return size_t (n);155}156157158} // namespace Imf159160#endif161162163