ManaPlus
mseprimitives.h
Go to the documentation of this file.
1 
2 // Copyright (c) 2015 Noah Lopez
3 // Use, modification, and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 #ifndef MSEPRIMITIVES_H
8 #define MSEPRIMITIVES_H
9 
10 #include <assert.h>
11 #include <climits> // ULONG_MAX
12 #include <limits> // std::numeric_limits
13 #include <stdexcept> // primitives_range_error
14 
15 /*compiler specific defines*/
16 #ifdef _MSC_VER
17 #if (1700 > _MSC_VER)
18 #define MSVC2010_COMPATIBLE 1
19 #endif /*(1700 > _MSC_VER)*/
20 #if (1900 > _MSC_VER)
21 #define MSVC2013_COMPATIBLE 1
22 #endif /*(1900 > _MSC_VER)*/
23 #if (2000 > _MSC_VER)
24 #define MSVC2015_COMPATIBLE 1
25 #endif /*(1900 > _MSC_VER)*/
26 #else /*_MSC_VER*/
27 #if (defined(__GNUC__) || defined(__GNUG__))
28 #define GPP_COMPATIBLE 1
29 #if ((5 > __GNUC__) && (!defined(__clang__)))
30 #define GPP4P8_COMPATIBLE 1
31 #endif /*((5 > __GNUC__) && (!defined(__clang__)))*/
32 #endif /*(defined(__GNUC__) || defined(__GNUG__))*/
33 #endif /*_MSC_VER*/
34 
35 #ifdef MSE_SAFER_SUBSTITUTES_DISABLED
36 #define MSE_PRIMITIVES_DISABLED
37 #endif /*MSE_SAFER_SUBSTITUTES_DISABLED*/
38 
39 #if defined(MSVC2013_COMPATIBLE) || defined(MSVC2010_COMPATIBLE)
40 #define MSE_CONSTEXPR
41 #else // defined(MSVC2013_COMPATIBLE) || defined(MSVC2010_COMPATIBLE)
42 #define MSE_CONSTEXPR constexpr
43 #endif // defined(MSVC2013_COMPATIBLE) || defined(MSVC2010_COMPATIBLE)
44 
45 #ifdef MSVC2015_COMPATIBLE
46 #ifndef MSE_FORCE_PRIMITIVE_ASSIGN_RANGE_CHECK_ENABLED
47 /* msvc2015's incomplete support for "constexpr" means that range checks that should be done at compile time would
48 be done at run time, at significant cost. So by default we disable range checks upon assignment. */
49 #define MSE_PRIMITIVE_ASSIGN_RANGE_CHECK_DISABLED 1
50 #endif // !MSE_FORCE_PRIMITIVE_ASSIGN_RANGE_CHECK_ENABLED
51 #endif // MSVC2015_COMPATIBLE
52 
53 
54 #ifdef MSE_CUSTOM_THROW_DEFINITION
55 #include <iostream>
56 #define MSE_THROW(x) MSE_CUSTOM_THROW_DEFINITION(x)
57 #else // MSE_CUSTOM_THROW_DEFINITION
58 #define MSE_THROW(x) throw(x)
59 #endif // MSE_CUSTOM_THROW_DEFINITION
60 
61 
62 #ifndef MSE_CINT_BASE_INTEGER_TYPE
63 #if SIZE_MAX <= ULONG_MAX
64 #define MSE_CINT_BASE_INTEGER_TYPE long int
65 #else // SIZE_MAX <= ULONG_MAX
66 #define MSE_CINT_BASE_INTEGER_TYPE long long int
67 #endif // SIZE_MAX <= ULONG_MAX
68 #endif // !MSE_CINT_BASE_INTEGER_TYPE
69 
70 
71 namespace mse {
72 
73  class primitives_range_error : public std::range_error {
74  public:
75  using std::range_error::range_error;
76  };
77 
78  /* When the mse primitive replacements are "disabled" they lose their default initialization and may cause problems for
79  code that relies on it. */
80 #ifdef MSE_PRIMITIVES_DISABLED
81  typedef bool CBool;
83  typedef size_t CSize_t;
84  static size_t as_a_size_t(CSize_t n) { return (n); }
85 #else /*MSE_PRIMITIVES_DISABLED*/
86 
87 #ifndef NDEBUG
88 #ifndef MSE_SUPPRESS_CHECK_USE_BEFORE_SET
89 #define MSE_CHECK_USE_BEFORE_SET
90 #endif // !MSE_SUPPRESS_CHECK_USE_BEFORE_SET
91 #endif // !NDEBUG
92 
93  /* This class is just meant to act like the "bool" type, except that it has a default intialization value (false). */
94  class CBool {
95  public:
96  // Constructs zero.
97  CBool() : m_val(false) {}
98 
99  // Copy constructor
100  CBool(const CBool &x) : m_val(x.m_val) { note_value_assignment(); };
101 
102  // Assignment operator
103  CBool& operator=(const CBool &x) { note_value_assignment(); m_val = x.m_val; return (*this); }
104 
105  // Constructors from primitive boolean types
106  CBool(bool x) { note_value_assignment(); m_val = x; }
107 
108  // Casts to primitive boolean types
109  operator bool() const { assert_initialized(); return m_val; }
110 
111  CBool& operator |=(const CBool &x) { assert_initialized(); m_val |= x.m_val; return (*this); }
112  CBool& operator &=(const CBool &x) { assert_initialized(); m_val &= x.m_val; return (*this); }
113  CBool& operator ^=(const CBool &x) { assert_initialized(); m_val ^= x.m_val; return (*this); }
114 
115  bool m_val;
116 
117 #ifdef MSE_CHECK_USE_BEFORE_SET
118  void note_value_assignment() { m_initialized = true; }
119  void assert_initialized() const { assert(m_initialized); }
120  bool m_initialized = false;
121 #else // MSE_CHECK_USE_BEFORE_SET
122  void note_value_assignment() {}
123  void assert_initialized() const {}
124 #endif // MSE_CHECK_USE_BEFORE_SET
125  };
126 
127 
128  template<typename _TDestination, typename _TSource>
130  return (
131  ((std::numeric_limits<_TSource>::is_signed == std::numeric_limits<_TDestination>::is_signed)
132  && (std::numeric_limits<_TSource>::digits > std::numeric_limits<_TDestination>::digits))
133  || ((std::numeric_limits<_TSource>::is_signed != std::numeric_limits<_TDestination>::is_signed)
134  && ((std::numeric_limits<_TSource>::is_signed && (std::numeric_limits<_TSource>::digits > (1 + std::numeric_limits<_TDestination>::digits)))
135  || ((!std::numeric_limits<_TSource>::is_signed) && ((1 + std::numeric_limits<_TSource>::digits) > std::numeric_limits<_TDestination>::digits))
136  )
137  )
138  );
139  }
140  template<typename _TDestination, typename _TSource>
142  return (
143  (std::numeric_limits<_TSource>::is_signed && (!std::numeric_limits<_TDestination>::is_signed))
144  || (std::numeric_limits<_TSource>::is_signed && (std::numeric_limits<_TSource>::digits > std::numeric_limits<_TDestination>::digits))
145  );
146  }
147 
148  template<typename _TDestination, typename _TSource>
149  void g_assign_check_range(const _TSource &x) {
150 #ifndef MSE_PRIMITIVE_ASSIGN_RANGE_CHECK_DISABLED
151  /* This probably needs to be cleaned up. But at the moment this should be mostly compile time complexity. And
152  as is it avoids "signed/unsigned" mismatch warnings. */
153  MSE_CONSTEXPR const bool rhs_can_exceed_upper_bound = sg_can_exceed_upper_bound<_TDestination, _TSource>();
154  MSE_CONSTEXPR const bool rhs_can_exceed_lower_bound = sg_can_exceed_lower_bound<_TDestination, _TSource>();
155  MSE_CONSTEXPR const bool can_exceed_bounds = rhs_can_exceed_upper_bound || rhs_can_exceed_lower_bound;
156  if (can_exceed_bounds) {
157  if (rhs_can_exceed_upper_bound) {
158  if (x > _TSource(std::numeric_limits<_TDestination>::max())) {
159  MSE_THROW(primitives_range_error("range error - value to be assigned is out of range of the target (integer) type"));
160  }
161  }
162  if (rhs_can_exceed_lower_bound) {
163  /* We're assuming that std::numeric_limits<>::lowest() will never be greater than zero. */
164  if (0 > x) {
165  if (0 == std::numeric_limits<_TDestination>::lowest()) {
166  MSE_THROW(primitives_range_error("range error - value to be assigned is out of range of the target (integer) type"));
167  }
168  else if (x < _TSource(std::numeric_limits<_TDestination>::lowest())) {
169  MSE_THROW(primitives_range_error("range error - value to be assigned is out of range of the target (integer) type"));
170  }
171  }
172  }
173  }
174 #endif // !MSE_PRIMITIVE_ASSIGN_RANGE_CHECK_DISABLED
175  }
176 
177  /* The CInt and CSize_t classes are meant to substitute for standard "int" and "size_t" types. The differences between
178  the standard types and these classes are that the classes have a default intialization value (zero), and the
179  classes, as much as possible, try to prevent the problematic behaviour of (possibly negative) signed integers
180  being cast (inadvertently) to the unsigned size_t type. For example, the expression (0 > (int)5 - (size_t)7) evaluates
181  (unintuitively) to false, whereas the expression (0 > (CInt)5 - (CSize_t)7) evaluates to true. Also, the classes do
182  some range checking. For example, the code "CSize_t s = -2;" will throw an exception. */
183  template<typename _Ty>
184  class TIntBase1 {
185  public:
186  // Constructs zero.
187  TIntBase1() : m_val(0) {}
188 
189  // Copy constructor
190  TIntBase1(const TIntBase1 &x) : m_val(x.m_val) { note_value_assignment(); };
191 
192  // Constructors from primitive integer types
193  explicit TIntBase1(_Ty x) { note_value_assignment(); m_val = x; }
194 
195  template<typename _Tz>
196  void assign_check_range(const _Tz &x) {
197  note_value_assignment();
198  g_assign_check_range<_Ty, _Tz>(x);
199  }
200 
201  _Ty m_val;
202 
203 #ifdef MSE_CHECK_USE_BEFORE_SET
204  void note_value_assignment() { m_initialized = true; }
205  void assert_initialized() const { assert(m_initialized); }
206  bool m_initialized = false;
207 #else // MSE_CHECK_USE_BEFORE_SET
208  void note_value_assignment() {}
209  void assert_initialized() const {}
210 #endif // MSE_CHECK_USE_BEFORE_SET
211  };
212 
213  class CInt : public TIntBase1<MSE_CINT_BASE_INTEGER_TYPE> {
214  public:
217 
218  // Constructs zero.
219  CInt() : _Myt() {}
220 
221  // Copy constructor
222  CInt(const CInt &x) : _Myt(x) {};
223  CInt(const _Myt &x) : _Myt(x) {};
224 
225  // Assignment operator
226  CInt& operator=(const CInt &x) { (*this).note_value_assignment(); m_val = x.m_val; return (*this); }
227  //CInt& operator=(const _Ty &x) { (*this).note_value_assignment(); m_val = x; return (*this); }
228 
229  CInt& operator=(long long x) { assign_check_range<long long>(x); m_val = static_cast<_Ty>(x); return (*this); }
230  CInt& operator=(long x) { assign_check_range<long>(x); m_val = static_cast<_Ty>(x); return (*this); }
231  CInt& operator=(int x) { assign_check_range<int>(x); m_val = static_cast<_Ty>(x); return (*this); }
232  CInt& operator=(short x) { assign_check_range<short>(x); m_val = static_cast<_Ty>(x); return (*this); }
233  CInt& operator=(char x) { assign_check_range<char>(x); m_val = static_cast<_Ty>(x); return (*this); }
234  CInt& operator=(size_t x) { assign_check_range<size_t>(x); m_val = static_cast<_Ty>(x); return (*this); }
235  //CInt& operator=(CSize_t x) { assign_check_range<size_t>(x.as_a_size_t()); m_val = x.as_a_size_t(); return (*this); }
236  /* We would have liked to have assignment operators for the unsigned primitive integer types, but one of them could
237  potentially clash with the size_t assignment operator. */
238  //CInt& operator=(unsigned long long x) { assign_check_range<unsigned long long>(x); m_val = static_cast<_Ty>(x); return (*this); }
239  //CInt& operator=(unsigned long x) { assign_check_range<unsigned long>(x); m_val = static_cast<_Ty>(x); return (*this); }
240  //CInt& operator=(unsigned int x) { assign_check_range<unsigned int>(x); m_val = static_cast<_Ty>(x); return (*this); }
241  //CInt& operator=(unsigned short x) { assign_check_range<unsigned short>(x); m_val = static_cast<_Ty>(x); return (*this); }
242  //CInt& operator=(unsigned char x) { assign_check_range<unsigned char>(x); m_val = static_cast<_Ty>(x); return (*this); }
243 
244  // Constructors from primitive integer types
245  //CInt(_Ty x) { m_val = x; }
246  CInt(long long x) { assign_check_range<long long>(x); m_val = static_cast<_Ty>(x); }
247  CInt(long x) { assign_check_range< long>(x); m_val = static_cast<_Ty>(x); }
248  CInt(int x) { assign_check_range<int>(x); m_val = static_cast<_Ty>(x); }
249  CInt(short x) { assign_check_range<short>(x); m_val = static_cast<_Ty>(x); }
250  CInt(char x) { assign_check_range<char>(x); m_val = static_cast<_Ty>(x); }
251  CInt(size_t x) { assign_check_range<size_t>(x); m_val = static_cast<_Ty>(x); }
252  //CInt(CSize_t x) { assign_check_range<size_t>(x.as_a_size_t()); m_val = x.as_a_size_t(); }
253  /* We would have liked to have constructors for the unsigned primitive integer types, but one of them could
254  potentially clash with the size_t constructor. */
255  //CInt(unsigned long long x) { assign_check_range<unsigned long long>(x); m_val = static_cast<_Ty>(x); }
256  //CInt(unsigned long x) { assign_check_range<unsigned long>(x); m_val = static_cast<_Ty>(x); }
257  //CInt(unsigned int x) { assign_check_range<unsigned int>(x); m_val = static_cast<_Ty>(x); }
258  //CInt(unsigned short x) { assign_check_range<unsigned short>(x); m_val = static_cast<_Ty>(x); }
259  //CInt(unsigned char x) { assign_check_range<unsigned char>(x); m_val = static_cast<_Ty>(x); }
260 
261  // Casts to primitive integer types
262  operator _Ty() const { (*this).assert_initialized(); return m_val; }
263 
264  CInt operator ~() const { (*this).assert_initialized(); return CInt(~m_val); }
265  CInt& operator |=(const CInt &x) { (*this).assert_initialized(); m_val |= x.m_val; return (*this); }
266  CInt& operator &=(const CInt &x) { (*this).assert_initialized(); m_val &= x.m_val; return (*this); }
267  CInt& operator ^=(const CInt &x) { (*this).assert_initialized(); m_val ^= x.m_val; return (*this); }
268 
269  CInt operator -() const { (*this).assert_initialized(); return CInt(-m_val); }
270  CInt& operator +=(const CInt &x) { (*this).assert_initialized(); m_val += x.m_val; return (*this); }
271  CInt& operator -=(const CInt &x) { (*this).assert_initialized(); m_val -= x.m_val; return (*this); }
272  CInt& operator *=(const CInt &x) { (*this).assert_initialized(); m_val *= x.m_val; return (*this); }
273  CInt& operator /=(const CInt &x) { (*this).assert_initialized(); m_val /= x.m_val; return (*this); }
274  CInt& operator %=(const CInt &x) { (*this).assert_initialized(); m_val %= x.m_val; return (*this); }
275  CInt& operator >>=(const CInt &x) { (*this).assert_initialized(); m_val >>= x.m_val; return (*this); }
276  CInt& operator <<=(const CInt &x) { (*this).assert_initialized(); m_val <<= x.m_val; return (*this); }
277 
278  CInt operator +(const CInt &x) const { (*this).assert_initialized(); return CInt(m_val + x.m_val); }
279  CInt operator +(long long x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
280  CInt operator +(long x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
281  CInt operator +(int x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
282  CInt operator +(short x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
283  CInt operator +(char x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
284  CInt operator +(size_t x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
285  //CInt operator +(CSize_t x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
286 
287  CInt operator -(const CInt &x) const { (*this).assert_initialized(); return CInt(m_val - x.m_val); }
288  CInt operator -(long long x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
289  CInt operator -(long x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
290  CInt operator -(int x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
291  CInt operator -(short x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
292  CInt operator -(char x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
293  CInt operator -(size_t x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
294  //CInt operator -(CSize_t x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
295 
296  CInt operator *(const CInt &x) const { (*this).assert_initialized(); return CInt(m_val * x.m_val); }
297  CInt operator *(long long x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
298  CInt operator *(long x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
299  CInt operator *(int x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
300  CInt operator *(short x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
301  CInt operator *(char x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
302  CInt operator *(size_t x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
303  //CInt operator *(CSize_t x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
304 
305  CInt operator /(const CInt &x) const { (*this).assert_initialized(); return CInt(m_val / x.m_val); }
306  CInt operator /(long long x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
307  CInt operator /(long x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
308  CInt operator /(int x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
309  CInt operator /(short x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
310  CInt operator /(char x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
311  CInt operator /(size_t x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
312  //CInt operator /(CSize_t x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
313 
314  bool operator <(const CInt &x) const { (*this).assert_initialized(); return (m_val < x.m_val); }
315  bool operator <(long long x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
316  bool operator <(long x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
317  bool operator <(int x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
318  bool operator <(short x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
319  bool operator <(char x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
320  bool operator <(size_t x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
321  //bool operator <(CSize_t x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
322 
323  bool operator >(const CInt &x) const { (*this).assert_initialized(); return (m_val > x.m_val); }
324  bool operator >(long long x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
325  bool operator >(long x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
326  bool operator >(int x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
327  bool operator >(short x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
328  bool operator >(char x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
329  bool operator >(size_t x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
330  //bool operator >(CSize_t x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
331 
332  bool operator <=(const CInt &x) const { (*this).assert_initialized(); return (m_val <= x.m_val); }
333  bool operator <=(long long x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
334  bool operator <=(long x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
335  bool operator <=(int x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
336  bool operator <=(short x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
337  bool operator <=(char x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
338  bool operator <=(size_t x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
339  //bool operator <=(CSize_t x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
340 
341  bool operator >=(const CInt &x) const { (*this).assert_initialized(); return (m_val >= x.m_val); }
342  bool operator >=(long long x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
343  bool operator >=(long x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
344  bool operator >=(int x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
345  bool operator >=(short x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
346  bool operator >=(char x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
347  bool operator >=(size_t x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
348  //bool operator >=(CSize_t x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
349 
350  bool operator ==(const CInt &x) const { (*this).assert_initialized(); return (m_val == x.m_val); }
351  bool operator ==(long long x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
352  bool operator ==(long x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
353  bool operator ==(int x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
354  bool operator ==(short x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
355  bool operator ==(char x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
356  bool operator ==(size_t x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
357  //bool operator ==(CSize_t x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
358 
359  bool operator !=(const CInt &x) const { (*this).assert_initialized(); return (m_val != x.m_val); }
360  bool operator !=(long long x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
361  bool operator !=(long x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
362  bool operator !=(int x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
363  bool operator !=(short x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
364  bool operator !=(char x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
365  bool operator !=(size_t x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
366  //bool operator !=(CSize_t x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
367 
368  // INCREMENT/DECREMENT OPERATORS
369  CInt& operator ++() { (*this).assert_initialized(); m_val++; return (*this); }
370  CInt operator ++(int) {
371  (*this).assert_initialized();
372  CInt tmp(*this); // copy
373  operator++(); // pre-increment
374  return tmp; // return old value
375  }
376  CInt& operator --() {
377  (*this).assert_initialized();
378  if (0 <= std::numeric_limits<_Ty>::lowest()) {
379  (*this).assert_initialized();
380  (*this) = (*this) - 1; return (*this);
381  }
382  else {
383  (*this).assert_initialized();
384  m_val--; return (*this);
385  }
386  }
387  CInt operator --(int) {
388  (*this).assert_initialized();
389  CInt tmp(*this); // copy
390  operator--(); // pre-decrement
391  return tmp; // return old value
392  }
393 
394  //_Ty m_val;
395  };
396 }
397 
398 namespace std {
399 #ifndef _THROW0
400 #define _THROW0()
401 #endif // !_THROW0
402 #ifndef _STCONS
403 #define _STCONS(ty, name, val) static constexpr ty name = static_cast<ty>(val)
404 #endif // !_STCONS
405 
406  template<> class numeric_limits<mse::CInt> { // limits for type int
407  public:
409 
410  static constexpr _Ty(min)() _THROW0()
411  { // return minimum value
412  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::min();
413  }
414  static constexpr _Ty(max)() _THROW0()
415  { // return maximum value
416  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max();
417  }
418  static constexpr _Ty lowest() _THROW0()
419  { // return most negative value
420  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::lowest();
421  }
422  static constexpr _Ty epsilon() _THROW0()
423  { // return smallest effective increment from 1.0
424  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::epsilon();
425  }
427  { // return largest rounding error
428  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::round_error();
429  }
430  static constexpr _Ty denorm_min() _THROW0()
431  { // return minimum denormalized value
432  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::denorm_min();
433  }
434  static constexpr _Ty infinity() _THROW0()
435  { // return positive infinity
436  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::infinity();
437  }
438  static constexpr _Ty quiet_NaN() _THROW0()
439  { // return non-signaling NaN
440  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::quiet_NaN();
441  }
443  { // return signaling NaN
444  return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::signaling_NaN();
445  }
446  _STCONS(float_denorm_style, has_denorm, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_denorm);
447  _STCONS(bool, has_denorm_loss, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_denorm_loss);
448  _STCONS(bool, has_infinity, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_infinity);
449  _STCONS(bool, has_quiet_NaN, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_quiet_NaN);
450  _STCONS(bool, has_signaling_NaN, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_signaling_NaN);
451  _STCONS(bool, is_bounded, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_bounded);
452  _STCONS(bool, is_exact, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_exact);
453  _STCONS(bool, is_iec559, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_iec559);
454  _STCONS(bool, is_integer, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_integer);
455  _STCONS(bool, is_modulo, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_modulo);
456  _STCONS(bool, is_signed, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_signed);
457  _STCONS(bool, is_specialized, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_specialized);
458  _STCONS(bool, tinyness_before, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::tinyness_before);
459  _STCONS(bool, traps, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::traps);
460  _STCONS(float_round_style, round_style, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::round_style);
461  _STCONS(int, digits, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::digits);
462  _STCONS(int, digits10, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::digits10);
463  _STCONS(int, max_digits10, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max_digits10);
464  _STCONS(int, max_exponent, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max_exponent);
465  _STCONS(int, max_exponent10, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max_exponent10);
466  _STCONS(int, min_exponent, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::min_exponent);
467  _STCONS(int, min_exponent10, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::min_exponent10);
468  _STCONS(int, radix, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::radix);
469  };
470 }
471 
472 namespace mse {
473  class CSize_t;
474  static size_t as_a_size_t(CSize_t n);
475 
476  /* Note that CSize_t does not have a default conversion to size_t. This is by design. Use the as_a_size_t() member
477  function to get a size_t when necessary. */
478  class CSize_t : public TIntBase1<size_t> {
479  public:
480  typedef size_t _Ty;
483 
484  // Constructs zero.
485  CSize_t() : _Myt() {}
486 
487  // Copy constructor
488  CSize_t(const CSize_t &x) : _Myt(x) {};
489  CSize_t(const _Myt &x) : _Myt(x) {};
490 
491  // Assignment operator
492  CSize_t& operator=(const CSize_t &x) { m_val = x.m_val; return (*this); }
493  //CSize_t& operator=(const _Ty &x) { m_val = x; return (*this); }
494 
495  CSize_t& operator=(long long x) { assign_check_range<long long>(x); m_val = static_cast<_Ty>(x); return (*this); }
496  CSize_t& operator=(long x) { assign_check_range<long>(x); m_val = static_cast<_Ty>(x); return (*this); }
497  CSize_t& operator=(int x) { assign_check_range<int>(x); m_val = static_cast<_Ty>(x); return (*this); }
498  CSize_t& operator=(short x) { assign_check_range<short>(x); m_val = static_cast<_Ty>(x); return (*this); }
499  CSize_t& operator=(char x) { assign_check_range<char>(x); m_val = static_cast<_Ty>(x); return (*this); }
500  CSize_t& operator=(size_t x) { assign_check_range<size_t>(x); m_val = static_cast<_Ty>(x); return (*this); }
501  CSize_t& operator=(CInt x) { assign_check_range<MSE_CINT_BASE_INTEGER_TYPE>(x); m_val = static_cast<_Ty>(x); return (*this); }
502  /* We would have liked to have assignment operators for the unsigned primitive integer types, but one of them could
503  potentially clash with the size_t assignment operator. */
504  //CSize_t& operator=(unsigned long long x) { assign_check_range<unsigned long long>(x); m_val = static_cast<_Ty>(x); return (*this); }
505  //CSize_t& operator=(unsigned long x) { assign_check_range<unsigned long>(x); m_val = static_cast<_Ty>(x); return (*this); }
506  //CSize_t& operator=(unsigned int x) { assign_check_range<unsigned int>(x); m_val = static_cast<_Ty>(x); return (*this); }
507  //CSize_t& operator=(unsigned short x) { assign_check_range<unsigned short>(x); m_val = static_cast<_Ty>(x); return (*this); }
508  //CSize_t& operator=(unsigned char x) { assign_check_range<unsigned char>(x); m_val = static_cast<_Ty>(x); return (*this); }
509 
510  // Constructors from primitive integer types
511  //explicit CSize_t(_Ty x) { m_val = x; }
512  explicit CSize_t(long long x) { assign_check_range<long long>(x); m_val = static_cast<_Ty>(x); }
513  explicit CSize_t(long x) { assign_check_range< long>(x); m_val = static_cast<_Ty>(x); }
514  explicit CSize_t(int x) { assign_check_range<int>(x); m_val = static_cast<_Ty>(x); }
515  explicit CSize_t(short x) { assign_check_range<short>(x); m_val = static_cast<_Ty>(x); }
516  explicit CSize_t(char x) { assign_check_range<char>(x); m_val = static_cast<_Ty>(x); }
517  CSize_t(size_t x) { assign_check_range<size_t>(x); m_val = static_cast<_Ty>(x); }
518  /*explicit */CSize_t(CInt x) { assign_check_range<MSE_CINT_BASE_INTEGER_TYPE>(x); m_val = static_cast<_Ty>(x); }
519  /* We would have liked to have constructors for the unsigned primitive integer types, but one of them could
520  potentially clash with the size_t constructor. */
521  //explicit CSize_t(unsigned long long x) { assign_check_range<unsigned long long>(x); m_val = static_cast<_Ty>(x); }
522  //explicit CSize_t(unsigned long x) { assign_check_range<unsigned long>(x); m_val = static_cast<_Ty>(x); }
523  //explicit CSize_t(unsigned int x) { assign_check_range<unsigned int>(x); m_val = static_cast<_Ty>(x); }
524  //explicit CSize_t(unsigned short x) { assign_check_range<unsigned short>(x); m_val = static_cast<_Ty>(x); }
525  //explicit CSize_t(unsigned char x) { assign_check_range<unsigned char>(x); m_val = static_cast<_Ty>(x); }
526 
527  // Casts to primitive integer types
528  operator CInt() const { (*this).assert_initialized(); return CInt(m_val); }
529 #ifndef MSVC2010_COMPATIBLE
530  explicit operator size_t() const { (*this).assert_initialized(); return (m_val); }
531 #endif /*MSVC2010_COMPATIBLE*/
532  //size_t as_a_size_t() const { (*this).assert_initialized(); return m_val; }
533 
534  CSize_t operator ~() const { (*this).assert_initialized(); return (~m_val); }
535  CSize_t& operator |=(const CSize_t &x) { (*this).assert_initialized(); m_val |= x.m_val; return (*this); }
536  CSize_t& operator &=(const CSize_t &x) { (*this).assert_initialized(); m_val &= x.m_val; return (*this); }
537  CSize_t& operator ^=(const CSize_t &x) { (*this).assert_initialized(); m_val ^= x.m_val; return (*this); }
538 
539  CInt operator -() const { (*this).assert_initialized(); /* Should unsigned types even support this opperator? */
540  return (-(CInt(m_val)));
541  }
542  CSize_t& operator +=(const CSize_t &x) { (*this).assert_initialized(); m_val += x.m_val; return (*this); }
543  CSize_t& operator -=(const CSize_t &x) {
544  (*this).assert_initialized();
545  //assert(0 <= std::numeric_limits<_Ty>::lowest());
546  if (x.m_val > m_val) {
547  MSE_THROW(primitives_range_error("range error - value to be assigned is out of range of the target (integer) type"));
548  }
549  m_val -= x.m_val; return (*this);
550  }
551  CSize_t& operator *=(const CSize_t &x) { (*this).assert_initialized(); m_val *= x.m_val; return (*this); }
552  CSize_t& operator /=(const CSize_t &x) { (*this).assert_initialized(); m_val /= x.m_val; return (*this); }
553  CSize_t& operator %=(const CSize_t &x) { (*this).assert_initialized(); m_val %= x.m_val; return (*this); }
554  CSize_t& operator >>=(const CSize_t &x) { (*this).assert_initialized(); m_val >>= x.m_val; return (*this); }
555  CSize_t& operator <<=(const CSize_t &x) { (*this).assert_initialized(); m_val <<= x.m_val; return (*this); }
556 
557  CSize_t operator +(const CSize_t &x) const { (*this).assert_initialized(); return (m_val + x.m_val); }
558  CInt operator +(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) + x); }
559  CInt operator +(long long x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
560  CInt operator +(long x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
561  CInt operator +(int x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
562  CInt operator +(short x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
563  CInt operator +(char x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); }
564  CSize_t operator +(size_t x) const { (*this).assert_initialized(); return ((*this) + CSize_t(x)); }
565 
566  CInt operator -(const CSize_t &x) const { (*this).assert_initialized(); return (CInt(m_val) - CInt(x.m_val)); }
567  CInt operator -(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) - x); }
568  CInt operator -(long long x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
569  CInt operator -(long x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
570  CInt operator -(int x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
571  CInt operator -(short x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
572  CInt operator -(char x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); }
573  CInt operator -(size_t x) const { (*this).assert_initialized(); return ((*this) - CSize_t(x)); }
574 
575  CSize_t operator *(const CSize_t &x) const { (*this).assert_initialized(); return (m_val * x.m_val); }
576  CInt operator *(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) * x); }
577  CInt operator *(long long x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
578  CInt operator *(long x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
579  CInt operator *(int x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
580  CInt operator *(short x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
581  CInt operator *(char x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); }
582  CSize_t operator *(size_t x) const { (*this).assert_initialized(); return ((*this) * CSize_t(x)); }
583 
584  CSize_t operator /(const CSize_t &x) const { (*this).assert_initialized(); return (m_val / x.m_val); }
585  CInt operator /(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) / x); }
586  CInt operator /(long long x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
587  CInt operator /(long x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
588  CInt operator /(int x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
589  CInt operator /(short x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
590  CInt operator /(char x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); }
591  CSize_t operator /(size_t x) const { (*this).assert_initialized(); return ((*this) / CSize_t(x)); }
592 
593  bool operator <(const CSize_t &x) const { (*this).assert_initialized(); return (m_val < x.m_val); }
594  bool operator <(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) < x); }
595  bool operator <(long long x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
596  bool operator <(long x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
597  bool operator <(int x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
598  bool operator <(short x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
599  bool operator <(char x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); }
600  bool operator <(size_t x) const { (*this).assert_initialized(); return ((*this) < CSize_t(x)); }
601 
602  bool operator >(const CSize_t &x) const { (*this).assert_initialized(); return (m_val > x.m_val); }
603  bool operator >(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) > x); }
604  bool operator >(long long x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
605  bool operator >(long x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
606  bool operator >(int x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
607  bool operator >(short x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
608  bool operator >(char x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); }
609  bool operator >(size_t x) const { (*this).assert_initialized(); return ((*this) > CSize_t(x)); }
610 
611  bool operator <=(const CSize_t &x) const { (*this).assert_initialized(); return (m_val <= x.m_val); }
612  bool operator <=(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) <= x); }
613  bool operator <=(long long x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
614  bool operator <=(long x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
615  bool operator <=(int x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
616  bool operator <=(short x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
617  bool operator <=(char x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); }
618  bool operator <=(size_t x) const { (*this).assert_initialized(); return ((*this) <= CSize_t(x)); }
619 
620  bool operator >=(const CSize_t &x) const { (*this).assert_initialized(); return (m_val >= x.m_val); }
621  bool operator >=(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) >= x); }
622  bool operator >=(long long x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
623  bool operator >=(long x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
624  bool operator >=(int x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
625  bool operator >=(short x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
626  bool operator >=(char x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); }
627  bool operator >=(size_t x) const { (*this).assert_initialized(); return ((*this) >= CSize_t(x)); }
628 
629  bool operator ==(const CSize_t &x) const { (*this).assert_initialized(); return (m_val == x.m_val); }
630  bool operator ==(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) == x); }
631  bool operator ==(long long x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
632  bool operator ==(long x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
633  bool operator ==(int x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
634  bool operator ==(short x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
635  bool operator ==(char x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); }
636  bool operator ==(size_t x) const { (*this).assert_initialized(); return ((*this) == CSize_t(x)); }
637 
638  bool operator !=(const CSize_t &x) const { (*this).assert_initialized(); return (m_val != x.m_val); }
639  bool operator !=(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) != x); }
640  bool operator !=(long long x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
641  bool operator !=(long x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
642  bool operator !=(int x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
643  bool operator !=(short x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
644  bool operator !=(char x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); }
645  bool operator !=(size_t x) const { (*this).assert_initialized(); return ((*this) != CSize_t(x)); }
646 
647  // INCREMENT/DECREMENT OPERATORS
648  CSize_t& operator ++() { (*this).assert_initialized(); m_val++; return (*this); }
649  CSize_t operator ++(int) { (*this).assert_initialized();
650  CSize_t tmp(*this); // copy
651  operator++(); // pre-increment
652  return tmp; // return old value
653  }
654  CSize_t& operator --() { (*this).assert_initialized();
655  if (0 <= std::numeric_limits<_Ty>::lowest()) { (*this).assert_initialized();
656  (*this) = (*this) - 1; return (*this);
657  }
658  else { (*this).assert_initialized();
659  m_val--; return (*this);
660  }
661  }
662  CSize_t operator --(int) { (*this).assert_initialized();
663  CSize_t tmp(*this); // copy
664  operator--(); // pre-decrement
665  return tmp; // return old value
666  }
667 
668  //_Ty m_val;
669 
670  friend size_t as_a_size_t(CSize_t n);
671  };
672  size_t as_a_size_t(CSize_t n) { n.assert_initialized(); return n.m_val; }
673 }
674 
675 namespace std {
676 #ifndef _THROW0
677 #define _THROW0()
678 #endif // !_THROW0
679 #ifndef _STCONS
680 #define _STCONS(ty, name, val) static constexpr ty name = (ty)(val)
681 #endif // !_STCONS
682 
683  template<> class numeric_limits<mse::CSize_t> { // limits for type int
684  public:
685  typedef size_t _Ty;
686 
687  static constexpr _Ty(min)() _THROW0()
688  { // return minimum value
689  return numeric_limits<size_t>::min();
690  }
691  static constexpr _Ty(max)() _THROW0()
692  { // return maximum value
693  return numeric_limits<size_t>::max();
694  }
695  static constexpr _Ty lowest() _THROW0()
696  { // return most negative value
697  return numeric_limits<size_t>::lowest();
698  }
699  static constexpr _Ty epsilon() _THROW0()
700  { // return smallest effective increment from 1.0
701  return numeric_limits<size_t>::epsilon();
702  }
704  { // return largest rounding error
705  return numeric_limits<size_t>::round_error();
706  }
707  static constexpr _Ty denorm_min() _THROW0()
708  { // return minimum denormalized value
709  return numeric_limits<size_t>::denorm_min();
710  }
711  static constexpr _Ty infinity() _THROW0()
712  { // return positive infinity
713  return numeric_limits<size_t>::infinity();
714  }
715  static constexpr _Ty quiet_NaN() _THROW0()
716  { // return non-signaling NaN
717  return numeric_limits<size_t>::quiet_NaN();
718  }
720  { // return signaling NaN
721  return numeric_limits<size_t>::signaling_NaN();
722  }
723  _STCONS(float_denorm_style, has_denorm, numeric_limits<size_t>::has_denorm);
724  _STCONS(bool, has_denorm_loss, numeric_limits<size_t>::has_denorm_loss);
725  _STCONS(bool, has_infinity, numeric_limits<size_t>::has_infinity);
726  _STCONS(bool, has_quiet_NaN, numeric_limits<size_t>::has_quiet_NaN);
727  _STCONS(bool, has_signaling_NaN, numeric_limits<size_t>::has_signaling_NaN);
728  _STCONS(bool, is_bounded, numeric_limits<size_t>::is_bounded);
729  _STCONS(bool, is_exact, numeric_limits<size_t>::is_exact);
730  _STCONS(bool, is_iec559, numeric_limits<size_t>::is_iec559);
731  _STCONS(bool, is_integer, numeric_limits<size_t>::is_integer);
732  _STCONS(bool, is_modulo, numeric_limits<size_t>::is_modulo);
733  _STCONS(bool, is_signed, numeric_limits<size_t>::is_signed);
734  _STCONS(bool, is_specialized, numeric_limits<size_t>::is_specialized);
735  _STCONS(bool, tinyness_before, numeric_limits<size_t>::tinyness_before);
736  _STCONS(bool, traps, numeric_limits<size_t>::traps);
737  _STCONS(float_round_style, round_style, numeric_limits<size_t>::round_style);
738  _STCONS(int, digits, numeric_limits<size_t>::digits);
739  _STCONS(int, digits10, numeric_limits<size_t>::digits10);
740  _STCONS(int, max_digits10, numeric_limits<size_t>::max_digits10);
741  _STCONS(int, max_exponent, numeric_limits<size_t>::max_exponent);
742  _STCONS(int, max_exponent10, numeric_limits<size_t>::max_exponent10);
743  _STCONS(int, min_exponent, numeric_limits<size_t>::min_exponent);
744  _STCONS(int, min_exponent10, numeric_limits<size_t>::min_exponent10);
745  _STCONS(int, radix, numeric_limits<size_t>::radix);
746  };
747 }
748 
749 namespace mse {
750 
751  inline CInt operator+(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); rhs.assert_initialized(); return CSize_t(lhs) + rhs; }
752  inline CSize_t operator+(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) + rhs; }
753  inline CInt operator+(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) + rhs; }
754  inline CInt operator+(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) + as_a_size_t(rhs); }
755  inline CInt operator+(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs + as_a_size_t(rhs); }
756  inline CInt operator-(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) - rhs; }
757  inline CInt operator-(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) - rhs; }
758  inline CInt operator-(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) - rhs; }
759  inline CInt operator-(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) - as_a_size_t(rhs); }
760  inline CInt operator-(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs - as_a_size_t(rhs); }
761  inline CInt operator*(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) * rhs; }
762  inline CSize_t operator*(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) * rhs; }
763  inline CInt operator*(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) * rhs; }
764  inline CInt operator*(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) * as_a_size_t(rhs); }
765  inline CInt operator*(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs * as_a_size_t(rhs); }
766  inline CInt operator/(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) / rhs; }
767  inline CSize_t operator/(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) / rhs; }
768  inline CInt operator/(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) / rhs; }
769  inline CInt operator/(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) / as_a_size_t(rhs); }
770  inline CInt operator/(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs / as_a_size_t(rhs); }
771 
772  inline bool operator<(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) < rhs; }
773  inline bool operator<(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) < rhs; }
774  inline bool operator<(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) < rhs; }
775  inline bool operator<(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) < as_a_size_t(rhs); }
776  inline bool operator<(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) < rhs; }
777  inline bool operator<(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) < as_a_size_t(rhs); }
778  inline bool operator<(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs < as_a_size_t(rhs); }
779  inline bool operator>(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) > rhs; }
780  inline bool operator>(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) > rhs; }
781  inline bool operator>(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) > rhs; }
782  inline bool operator>(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) > as_a_size_t(rhs); }
783  inline bool operator>(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) > rhs; }
784  inline bool operator>(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) > as_a_size_t(rhs); }
785  inline bool operator>(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs > as_a_size_t(rhs); }
786  inline bool operator<=(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) <= rhs; }
787  inline bool operator<=(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) <= rhs; }
788  inline bool operator<=(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) <= rhs; }
789  inline bool operator<=(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) <= as_a_size_t(rhs); }
790  inline bool operator<=(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) <= rhs; }
791  inline bool operator<=(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) <= as_a_size_t(rhs); }
792  inline bool operator<=(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs <= as_a_size_t(rhs); }
793  inline bool operator>=(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) >= rhs; }
794  inline bool operator>=(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) >= rhs; }
795  inline bool operator>=(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) >= rhs; }
796  inline bool operator>=(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) >= as_a_size_t(rhs); }
797  inline bool operator>=(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) >= rhs; }
798  inline bool operator>=(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) >= as_a_size_t(rhs); }
799  inline bool operator>=(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs >= as_a_size_t(rhs); }
800  inline bool operator==(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) == rhs; }
801  inline bool operator==(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) == rhs; }
802  inline bool operator==(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) == rhs; }
803  inline bool operator==(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) == as_a_size_t(rhs); }
804  inline bool operator==(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) == rhs; }
805  inline bool operator==(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) == as_a_size_t(rhs); }
806  inline bool operator==(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs == as_a_size_t(rhs); }
807  inline bool operator!=(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) != rhs; }
808  inline bool operator!=(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) != rhs; }
809  inline bool operator!=(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) != rhs; }
810  inline bool operator!=(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) != as_a_size_t(rhs); }
811  inline bool operator!=(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) != rhs; }
812  inline bool operator!=(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) != as_a_size_t(rhs); }
813  inline bool operator!=(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs != as_a_size_t(rhs); }
814 #endif /*MSE_PRIMITIVES_DISABLED*/
815 
816  static void s_type_test1() {
817 #ifdef MSE_SELF_TESTS
818  CInt i1(3);
819  CInt i2 = 5;
820  CInt i3;
821  i3 = 7;
822  CInt i4 = i1 + i2;
823  i4 = i1 + 17;
824  i4 = 19 + i1;
825  i4 += i2;
826  i4 -= 23;
827  i4++;
828  CBool b1 = (i1 < i2);
829  b1 = (i1 < 17);
830  b1 = (19 < i1);
831  b1 = (i1 == i2);
832  b1 = (i1 == 17);
833  b1 = (19 == i1);
834 
835  CSize_t szt1(3);
836  CSize_t szt2 = 5;
837  CSize_t szt3;
838  szt3 = 7;
839  CSize_t szt4 = szt1 + szt2;
840  szt4 = szt1 + 17;
841  szt4 = 19 + szt1;
842  CInt i11 = 19 + szt1;
843  szt4 += szt2;
844  szt4 -= 23;
845  szt4++;
846 #ifndef MSVC2010_COMPATIBLE
847  size_t szt5 = size_t(szt4);
848 #endif /*MSVC2010_COMPATIBLE*/
849  bool b3 = (szt1 < szt2);
850  b3 = (szt1 < 17);
851  b3 = (19 < szt1);
852  CBool b2 = (19 < szt1);
853  b3 = (szt1 == szt2);
854  b3 = (szt1 == 17);
855  b3 = (19 == szt1);
856  CBool b4 = (b1 < b2);
857  b4 = (b1 == b2);
858  b4 = (b1 > b3);
859  b4 = (b3 >= b1);
860  b4 = (b3 == b1);
861  b4 = (b1 && b2);
862  b4 = (b1 || b3);
863  b4 = (b3 && b1);
864  b4 |= b1;
865  b4 &= b3;
866 #endif // MSE_SELF_TESTS
867  }
868 }
869 
870 #undef MSE_THROW
871 
872 #endif /*ndef MSEPRIMITIVES_H*/
CInt(short x)
bool operator!=(size_t lhs, const CInt &rhs)
static constexpr _Ty round_error()
static constexpr bool sg_can_exceed_upper_bound()
#define MSE_THROW(x)
Definition: mseprimitives.h:58
static constexpr _Ty infinity()
CSize_t(CInt x)
CInt(const _Myt &x)
CInt & operator=(const CInt &x)
static void s_type_test1()
TIntBase1(const TIntBase1 &x)
bool operator>(size_t lhs, const CInt &rhs)
static constexpr _Ty infinity()
static constexpr bool sg_can_exceed_lower_bound()
static constexpr _Ty quiet_NaN()
CSize_t & operator=(long long x)
#define constexpr
Definition: localconsts.h:47
static constexpr _Ty round_error()
static constexpr _Ty denorm_min()
CInt & operator=(char x)
CSize_t & operator=(const CSize_t &x)
void assign_check_range(const _Tz &x)
CSize_t(short x)
CInt(long x)
static constexpr _Ty denorm_min()
CInt & operator=(long long x)
static constexpr _Ty epsilon()
CInt(long long x)
#define _STCONS(ty, name, val)
bool operator<=(size_t lhs, const CInt &rhs)
bool operator<(size_t lhs, const CInt &rhs)
void assert_initialized() const
CSize_t & operator=(size_t x)
bool operator>=(size_t lhs, const CInt &rhs)
CInt(char x)
CSize_t & operator=(char x)
CInt operator-(size_t lhs, const CInt &rhs)
static constexpr _Ty epsilon()
static constexpr _Ty signaling_NaN()
CSize_t & operator=(long x)
#define _THROW0()
static constexpr _Ty signaling_NaN()
CSize_t(const CSize_t &x)
void note_value_assignment()
CSize_t & operator=(short x)
CSize_t & operator=(CInt x)
CInt(const CInt &x)
CInt operator*(size_t lhs, const CInt &rhs)
CInt operator/(size_t lhs, const CInt &rhs)
CSize_t & operator=(int x)
static constexpr _Ty lowest()
long int _Ty
CInt(int x)
CSize_t(long long x)
TIntBase1< _Ty > _Myt
CInt & operator=(int x)
CBool(bool x)
#define MSE_CINT_BASE_INTEGER_TYPE
Definition: mseprimitives.h:64
TIntBase1< _Ty > _Myt
void note_value_assignment()
int _T_signed_primitive_integer_type
bool operator==(size_t lhs, const CInt &rhs)
void g_assign_check_range(const _TSource &x)
CInt & operator=(long x)
void assert_initialized() const
CInt operator+(size_t lhs, const CInt &rhs)
CSize_t(long x)
CBool & operator=(const CBool &x)
CSize_t(char x)
CSize_t(size_t x)
static constexpr _Ty quiet_NaN()
CSize_t(const _Myt &x)
#define MSE_CONSTEXPR
Definition: mseprimitives.h:42
CInt(size_t x)
static size_t as_a_size_t(CSize_t n)
CBool(const CBool &x)
CInt & operator=(short x)
CInt & operator=(size_t x)