BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface software
safe.hpp
Go to the documentation of this file.
1 #pragma once
3 #include <fc/reflect/reflect.hpp>
4 
5 #include <limits>
6 
7 namespace fc {
8 
19  template<typename T>
20  struct safe
21  {
22  T value = 0;
23 
24  template<typename O>
25  safe( O o ):value(o){}
26  safe(){}
27  safe( const safe& o ):value(o.value){}
28 
29  static constexpr safe min()
30  {
31  return std::numeric_limits<T>::min();
32  }
33  static constexpr safe max()
34  {
35  return std::numeric_limits<T>::max();
36  }
37 
38  friend safe operator + ( const safe& a, const safe& b )
39  {
40  if( b.value > 0 && a.value > (std::numeric_limits<T>::max() - b.value) ) FC_CAPTURE_AND_THROW( overflow_exception, (a)(b) );
41  if( b.value < 0 && a.value < (std::numeric_limits<T>::min() - b.value) ) FC_CAPTURE_AND_THROW( underflow_exception, (a)(b) );
42  return safe( a.value + b.value );
43  }
44  friend safe operator - ( const safe& a, const safe& b )
45  {
46  if( b.value > 0 && a.value < (std::numeric_limits<T>::min() + b.value) ) FC_CAPTURE_AND_THROW( underflow_exception, (a)(b) );
47  if( b.value < 0 && a.value > (std::numeric_limits<T>::max() + b.value) ) FC_CAPTURE_AND_THROW( overflow_exception, (a)(b) );
48  return safe( a.value - b.value );
49  }
50 
51  friend safe operator * ( const safe& a, const safe& b )
52  {
53  if( a.value > 0 )
54  {
55  if( b.value > 0 )
56  {
57  if( a.value > (std::numeric_limits<T>::max() / b.value) ) FC_CAPTURE_AND_THROW( overflow_exception, (a)(b) );
58  }
59  else
60  {
61  if( b.value < (std::numeric_limits<T>::min() / a.value) ) FC_CAPTURE_AND_THROW( underflow_exception, (a)(b) );
62  }
63  }
64  else
65  {
66  if( b.value > 0 )
67  {
68  if( a.value < (std::numeric_limits<T>::min() / b.value) ) FC_CAPTURE_AND_THROW( underflow_exception, (a)(b) );
69  }
70  else
71  {
72  if( a.value != 0 && b.value < (std::numeric_limits<T>::max() / a.value) ) FC_CAPTURE_AND_THROW( overflow_exception, (a)(b) );
73  }
74  }
75 
76  return safe( a.value * b.value );
77  }
78 
79  friend safe operator / ( const safe& a, const safe& b )
80  {
81  if( b.value == 0 ) FC_CAPTURE_AND_THROW( divide_by_zero_exception, (a)(b) );
82  if( a.value == std::numeric_limits<T>::min() && b.value == -1 ) FC_CAPTURE_AND_THROW( overflow_exception, (a)(b) );
83  return safe( a.value / b.value );
84  }
85  friend safe operator % ( const safe& a, const safe& b )
86  {
87  if( b.value == 0 ) FC_CAPTURE_AND_THROW( divide_by_zero_exception, (a)(b) );
88  if( a.value == std::numeric_limits<T>::min() && b.value == -1 ) FC_CAPTURE_AND_THROW( overflow_exception, (a)(b) );
89  return safe( a.value % b.value );
90  }
91 
93  {
94  if( value == min() ) FC_CAPTURE_AND_THROW( overflow_exception, (*this) );
95  return safe( -value );
96  }
97 
98  safe& operator += ( const safe& b )
99  {
100  value = (*this + b).value;
101  return *this;
102  }
103  safe& operator -= ( const safe& b )
104  {
105  value = (*this - b).value;
106  return *this;
107  }
108  safe& operator *= ( const safe& b )
109  {
110  value = (*this * b).value;
111  return *this;
112  }
113  safe& operator /= ( const safe& b )
114  {
115  value = (*this / b).value;
116  return *this;
117  }
118  safe& operator %= ( const safe& b )
119  {
120  value = (*this % b).value;
121  return *this;
122  }
123 
125  {
126  *this += 1;
127  return *this;
128  }
130  {
131  safe bak = *this;
132  *this += 1;
133  return bak;
134  }
135 
137  {
138  *this -= 1;
139  return *this;
140  }
142  {
143  safe bak = *this;
144  *this -= 1;
145  return bak;
146  }
147 
148  friend bool operator == ( const safe& a, const safe& b )
149  {
150  return a.value == b.value;
151  }
152  friend bool operator == ( const safe& a, const T& b )
153  {
154  return a.value == b;
155  }
156  friend bool operator == ( const T& a, const safe& b )
157  {
158  return a == b.value;
159  }
160 
161  friend bool operator < ( const safe& a, const safe& b )
162  {
163  return a.value < b.value;
164  }
165  friend bool operator < ( const safe& a, const T& b )
166  {
167  return a.value < b;
168  }
169  friend bool operator < ( const T& a, const safe& b )
170  {
171  return a < b.value;
172  }
173 
174  friend bool operator > ( const safe& a, const safe& b )
175  {
176  return a.value > b.value;
177  }
178  friend bool operator > ( const safe& a, const T& b )
179  {
180  return a.value > b;
181  }
182  friend bool operator > ( const T& a, const safe& b )
183  {
184  return a > b.value;
185  }
186 
187  friend bool operator != ( const safe& a, const safe& b )
188  {
189  return !(a == b);
190  }
191  friend bool operator != ( const safe& a, const T& b )
192  {
193  return !(a == b);
194  }
195  friend bool operator != ( const T& a, const safe& b )
196  {
197  return !(a == b);
198  }
199 
200  friend bool operator <= ( const safe& a, const safe& b )
201  {
202  return !(a > b);
203  }
204  friend bool operator <= ( const safe& a, const T& b )
205  {
206  return !(a > b);
207  }
208  friend bool operator <= ( const T& a, const safe& b )
209  {
210  return !(a > b);
211  }
212 
213  friend bool operator >= ( const safe& a, const safe& b )
214  {
215  return !(a < b);
216  }
217  friend bool operator >= ( const safe& a, const T& b )
218  {
219  return !(a < b);
220  }
221  friend bool operator >= ( const T& a, const safe& b )
222  {
223  return !(a < b);
224  }
225  };
226 
227 }
228 
229 FC_REFLECT_TEMPLATE( (typename T), safe<T>, (value) )
safe & operator/=(const safe &b)
Definition: safe.hpp:113
friend safe operator+(const safe &a, const safe &b)
Definition: safe.hpp:38
#define FC_CAPTURE_AND_THROW(EXCEPTION_TYPE,...)
Definition: exception.hpp:357
friend bool operator==(const safe &a, const safe &b)
Definition: safe.hpp:148
safe(O o)
Definition: safe.hpp:25
safe()
Definition: safe.hpp:26
Defines types and macros used to provide reflection.
friend safe operator*(const safe &a, const safe &b)
Definition: safe.hpp:51
friend safe operator/(const safe &a, const safe &b)
Definition: safe.hpp:79
friend bool operator>=(const safe &a, const safe &b)
Definition: safe.hpp:213
friend bool operator!=(const safe &a, const safe &b)
Definition: safe.hpp:187
safe operator++(int)
Definition: safe.hpp:129
() file_not_found_exception() parse_error_exception() invalid_arg_exception() invalid_operation_exception() key_not_found_exception() bad_cast_exception() out_of_range_exception() canceled_exception() assert_exception() eof_exception() unknown_host_exception() null_optional() aes_exception() overflow_exception() underflow_exception(divide_by_zero_exception)) namespace detail
Definition: exception.cpp:46
friend bool operator<=(const safe &a, const safe &b)
Definition: safe.hpp:200
friend bool operator>(const safe &a, const safe &b)
Definition: safe.hpp:174
safe & operator--()
Definition: safe.hpp:136
safe(const safe &o)
Definition: safe.hpp:27
static constexpr safe min()
Definition: safe.hpp:29
safe & operator-=(const safe &b)
Definition: safe.hpp:103
Defines exception&#39;s used by fc.
static constexpr safe max()
Definition: safe.hpp:33
safe & operator+=(const safe &b)
Definition: safe.hpp:98
Definition: api.hpp:15
#define FC_REFLECT_TEMPLATE(TEMPLATE_ARGS, TYPE, MEMBERS)
Definition: reflect.hpp:390
safe & operator++()
Definition: safe.hpp:124
safe operator-() const
Definition: safe.hpp:92
friend safe operator%(const safe &a, const safe &b)
Definition: safe.hpp:85
friend bool operator<(const safe &a, const safe &b)
Definition: safe.hpp:161
safe operator--(int)
Definition: safe.hpp:141
safe & operator*=(const safe &b)
Definition: safe.hpp:108
T value
Definition: safe.hpp:22
safe & operator%=(const safe &b)
Definition: safe.hpp:118