-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSnugInt.h
320 lines (292 loc) · 10.7 KB
/
SnugInt.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/*
Copyright 2019 Stephen Tafoya <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef PROJECT_SNUGINT_H
#define PROJECT_SNUGINT_H
#include <exception>
#include <iostream>
#include <limits>
/**
* \brief SnugInt class for safe Integer operations
*
* \details
* A class designed to be used in conjunction with integral types to validate unsafe operations
* using precondition checks. This class should be used in a try catch structure as it will throw exceptions
* using the exception library.
*
* \details
* - This class only accepts Integral types
*
* \details
* - Assignment for the class accepts all types but requires the type to be a Duck Type of integrals
*
* \section <b>Exceptions:</b>
* <br>The following exceptions are supported
* \code
*SnugInt_Addition_Overflow_Exception
* called when overflow during addition is preditcted
*
*SnugInt_Addition_Underflow_Exception
* called when undeflow during addition is predicted
*
*SnugInt_Subtraction_Overflow_Exception
* called when overflow during subtraction is predicted
*
*SnugInt_Subtraction_Underflow_Exception
* called when underflow during subtraction is predicted
*
*SnugInt_Multiplication_Overflow_Exception
* called when overflow during multiplication is predicted
*
*SnugInt_Multiplication_Underflow_Exception
* called when underflow during multiplication is predicted
*
*SnugInt_Size_Mismatch_Exception
* called when a size mismatch during assignment is detected
*
*SnugInt_Type_Mismatch_Exception
* called when an unsupported type is used during assignment
* \endcode
*
* \section <b>Example Usage:</b>
* \code
*try
*{ // perform the operation
* SnugInt<unsigned int> si1 = 1;
* SnugInt<unsigned int> si2 = 10;
* si1 = si1 - si2;
*} catch (std::exception& e)
*{
* // handle the exception
*}
* \endcode
* @tparam Type integer to do operations with
*
* \author Stephen Tafoya
* \date 3/10/2019
*/
template <class Type>
class SnugInt
{
static_assert(std::is_integral<Type>::value, "SnugInt must be an integral");
public:
// Constructors
SnugInt();
SnugInt(const SnugInt<Type> &other);
template<class T> SnugInt(const T &item);
// Assignment Operators
SnugInt& operator = (const SnugInt& other);
SnugInt& operator = (const Type& other);
SnugInt& operator += (const SnugInt& other);
SnugInt& operator += (const Type& other);
// Accessor Operators
Type getValue() { return value; };
// Mathematical Operators (SnugInt, SnugInt)
template<class T> friend SnugInt<T> operator+(const SnugInt<T>& left, const SnugInt<T>& right);
template<class T> friend SnugInt<T> operator-(const SnugInt<T>& left, const SnugInt<T>& right);
template<class T> friend SnugInt<T> operator*(const SnugInt<T>& left, const SnugInt<T>& right);
template<class T> friend SnugInt<T> operator/(const SnugInt<T>& left, const SnugInt<T>& right);
// Mathematical Operators (SnugInt, T)
template<class T> friend SnugInt<T> operator+(const SnugInt<T>& left, const T& right);
template<class T> friend SnugInt<T> operator-(const SnugInt<T>& left, const T& right);
template<class T> friend SnugInt<T> operator*(const SnugInt<T>& left, const T& right);
template<class T> friend SnugInt<T> operator/(const SnugInt<T>& left, const T& right);
// Mathematical Operators (T, SnugInt)
template<class T> friend SnugInt<T> operator+(const T& left, const SnugInt<T>& right);
template<class T> friend SnugInt<T> operator-(const T& left, const SnugInt<T>& right);
template<class T> friend SnugInt<T> operator*(const T& left, const SnugInt<T>& right);
template<class T> friend SnugInt<T> operator/(const T& left, const SnugInt<T>& right);
// Incremental & Decremental Operators
SnugInt& operator++();
const SnugInt operator++( int );
SnugInt& operator--();
const SnugInt operator--( int );
// Comparison Operators (SnugInt, SnugInt)
template<class T> friend bool operator< (const SnugInt<T>& left, const SnugInt<T>& right);
template<class T> friend bool operator> (const SnugInt<T>& left, const SnugInt<T>& right);
template<class T> friend bool operator==(const SnugInt<T>& left, const SnugInt<T>& right);
template<class T> friend bool operator!=(const SnugInt<T>& left, const SnugInt<T>& right);
template<class T> friend bool operator>=(const SnugInt<T>& left, const SnugInt<T>& right);
template<class T> friend bool operator<=(const SnugInt<T>& left, const SnugInt<T>& right);
// Comparison Operators (SnugInt, T)
template<class T> friend bool operator< (const SnugInt<T>& left, const T& right);
template<class T> friend bool operator> (const SnugInt<T>& left, const T& right);
template<class T> friend bool operator==(const SnugInt<T>& left, const T& right);
template<class T> friend bool operator!=(const SnugInt<T>& left, const T& right);
template<class T> friend bool operator>=(const SnugInt<T>& left, const T& right);
template<class T> friend bool operator<=(const SnugInt<T>& left, const T& right);
// Comparison Operators (T, SnugInt)
template<class T> friend bool operator< (const T& left, const SnugInt<T>& right);
template<class T> friend bool operator> (const T& left, const SnugInt<T>& right);
template<class T> friend bool operator==(const T& left, const SnugInt<T>& right);
template<class T> friend bool operator!=(const T& left, const SnugInt<T>& right);
template<class T> friend bool operator>=(const T& left, const SnugInt<T>& right);
template<class T> friend bool operator<=(const T& left, const SnugInt<T>& right);
// Stream Operators
template <class T> friend std::ostream& operator<<(std::ostream &os, const SnugInt<T>& data);
template <class T> friend std::istream& operator>>(std::istream &is, const SnugInt<T>& data);
private:
Type value; /**< stored value for Type */
Type max; /**< max possible size for Type */
Type min; /**< min possible size for Type */
// Static Precondition Safe Methods
static SnugInt SafeAdd(const SnugInt& left, const SnugInt& right);
static SnugInt SafeSub(const SnugInt& left, const SnugInt& right);
static SnugInt SafeMult(const SnugInt& left, const SnugInt& right);
static SnugInt SafeDiv(const SnugInt& left, const SnugInt& right);
};
/**
* \brief SnugInt Exception Addition Overflow
*
* \details
* This exception is thrown when a SnugInt operation detects there will be overflow from addition
* \details
* Throws this error to prevent overflow
*
* \author Stephen Tafoya
* \date 3/8/2019
*/
class SnugInt_Addition_Overflow_Exception: public std::exception
{
const char* what() const noexcept override
{
return "SnugInt addition operation prevented, OVERFLOW would have occurred";
}
} snugint_add_overflow;
/**
* \brief SnugInt Exception Addition Underflow
*
* \details
* This exception is thrown when a SnugInt operation detects there will be underflow from addition
* \details
* Throws this error to prevent underflow
*
* \author Stephen Tafoya
* \date 3/12/2019
*/
class SnugInt_Addition_Underflow_Exception: public std::exception
{
const char* what() const noexcept override
{
return "SnugInt addition operation prevented, UNDERFLOW would have occurred";
}
} snugint_add_underflow;
/**
* \brief SnugInt Exception Subtraction Overflow
*
* \details
* This exception is thrown when a SnugInt operation detects there will be overflow from subtraction
* \details
* Throws this error to prevent overflow
*
* \author Stephen Tafoya
* \date 3/8/2019
*/
class SnugInt_Subtraction_Overflow_Exception: public std::exception
{
const char* what() const noexcept override
{
return "SnugInt subtraction operation prevented, OVERFLOW would have occurred";
}
} snugint_sub_overflow;
/**
* \brief SnugInt Exception Subtraction Underflow
*
* \details
* This exception is thrown when a SnugInt operation detects there will be underflow from subtraction
* \details
* Throws this error to prevent underflow
*
* \author Stephen Tafoya
* \date 3/8/2019
*/
class SnugInt_Subtraction_Underflow_Exception: public std::exception
{
const char* what() const noexcept override
{
return "SnugInt subtraction operation prevented, UNDERFLOW would have occurred";
}
} snugint_sub_underflow;
/**
* \brief SnugInt Exception Multiplication Overflow
*
* \details
* This exception is thrown when a SnugInt operation detects there will be overflow from multiplication
* \details
* Throws this error to prevent overflow
*
* \author Stephen Tafoya
* \date 3/8/2019
*/
class SnugInt_Multiplication_Overflow_Exception: public std::exception
{
const char* what() const noexcept override
{
return "SnugInt multiplication operation prevented, OVERFLOW would have occurred";
}
} snugint_mult_overflow;
/**
* \brief SnugInt Exception Multiplication Underflow
*
* \details
* This exception is thrown when a SnugInt operation detects there will be underflow from multiplication
* \details
* Throws this error to prevent underflow
*
* \author Stephen Tafoya
* \date 3/8/2019
*/
class SnugInt_Multiplication_Underflow_Exception: public std::exception
{
const char* what() const noexcept override
{
return "SnugInt multiplication operation prevented, UNDERFLOW would have occurred";
}
} snugint_mult_underflow;
/**
* \brief SnugInt Exception Type Size Mismatch
*
* \details
* This exception is thrown when a SnugInt detects a value that will not fit
* \details
* Throws this error to prevent unpredictable behavior
*
* \author Stephen Tafoya
* \date 3/8/2019
*/
class SnugInt_Size_Mismatch_Exception: public std::exception
{
const char* what() const noexcept override
{
return "SnugInt Size Mismatch, Operation Failure";
}
} snugint_size_mismatch;
/**
* \brief SnugInt Exception Type Mismatch
*
* \details
* This exception is thrown when a SnugInt detects an incompatible type
* \details
* Throws this error to prevent unpredictable behavior
*
* \author Stephen Tafoya
* \date 3/8/2019
*/
class SnugInt_Type_Mismatch_Exception: public std::exception
{
const char* what() const noexcept override
{
return "SnugInt Type Mismatch, Operation Failure";
}
} snugint_type_mismatch;
#include "SnugInt.tpp"
#endif //PROJECT_SNUGINT_H