• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2009, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // *       Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // *       Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // *       Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34 
35 #ifndef INCLUDED_IMF_CHECKED_ARITHMETIC_H
36 #define INCLUDED_IMF_CHECKED_ARITHMETIC_H
37 
38 //-----------------------------------------------------------------------------
39 //
40 //	Integer arithmetic operations that throw exceptions
41 //      on overflow, underflow or division by zero.
42 //
43 //-----------------------------------------------------------------------------
44 
45 #include <limits>
46 #include <IexMathExc.h>
47 
48 namespace Imf {
49 
50 template <bool b> struct StaticAssertionFailed;
51 template <> struct StaticAssertionFailed <true> {};
52 
53 #define IMF_STATIC_ASSERT(x) \
54     do {StaticAssertionFailed <x> staticAssertionFailed;} while (false)
55 
56 
57 template <class T>
58 T
59 uiMult (T a, T b)
60 {
61     //
62     // Unsigned integer multiplication
63     //
64 
65     IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&
66                         std::numeric_limits<T>::is_integer);
67 
68     if (a > 0 && b > std::numeric_limits<T>::max() / a)
69         throw Iex::OverflowExc ("Integer multiplication overflow.");
70 
71     return a * b;
72 }
73 
74 
75 template <class T>
76 T
77 uiDiv (T a, T b)
78 {
79     //
80     // Unsigned integer division
81     //
82 
83     IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&
84                         std::numeric_limits<T>::is_integer);
85 
86     if (b == 0)
87         throw Iex::DivzeroExc ("Integer division by zero.");
88 
89     return a / b;
90 }
91 
92 
93 template <class T>
94 T
95 uiAdd (T a, T b)
96 {
97     //
98     // Unsigned integer addition
99     //
100 
101     IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&
102                         std::numeric_limits<T>::is_integer);
103 
104     if (a > std::numeric_limits<T>::max() - b)
105         throw Iex::OverflowExc ("Integer addition overflow.");
106 
107     return a + b;
108 }
109 
110 
111 template <class T>
112 T
113 uiSub (T a, T b)
114 {
115     //
116     // Unsigned integer subtraction
117     //
118 
119     IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&
120                         std::numeric_limits<T>::is_integer);
121 
122     if (a < b)
123         throw Iex::UnderflowExc ("Integer subtraction underflow.");
124 
125     return a - b;
126 }
127 
128 
129 template <class T>
130 size_t
131 checkArraySize (T n, size_t s)
132 {
133     //
134     // Verify that the size, in bytes, of an array with n elements
135     // of size s can be computed without overflowing:
136     //
137     // If computing
138     //
139     //      size_t (n) * s
140     //
141     // would overflow, then throw an Iex::OverflowExc exception.
142     // Otherwise return
143     //
144     //      size_t (n).
145     //
146 
147     IMF_STATIC_ASSERT (!std::numeric_limits<T>::is_signed &&
148                         std::numeric_limits<T>::is_integer);
149 
150     IMF_STATIC_ASSERT (sizeof (T) <= sizeof (size_t));
151 
152     if (size_t (n) > std::numeric_limits<size_t>::max() / s)
153         throw Iex::OverflowExc ("Integer multiplication overflow.");
154 
155     return size_t (n);
156 }
157 
158 
159 } // namespace Imf
160 
161 #endif
162