Evo C++ Library v0.5.1
type.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_type_h
9 #define INCL_evo_type_h
10 
11 #include "impl/container.h"
12 
13 namespace evo {
16 
18 
24 #define EVO_MIN(A, B) ((B) < (A) ? (B) : (A))
25 
31 #define EVO_MAX(A, B) ((B) > (A) ? (B) : (A))
32 
34 
73 template<class T> class SafeBool {
74 protected:
76  typedef void (SafeBool::*SafeBoolType)() const;
77  void This_type_does_not_support_this_comparison() const { }
80 public:
82  SafeBool() { }
84  SafeBool(const SafeBool&) { }
92  operator SafeBoolType() const
93  { return (!(static_cast<const T*>(this))->operator!() ? &SafeBool::This_type_does_not_support_this_comparison : 0); }
94 };
95 
97 template<typename T, typename U> bool operator==(const SafeBool<T>& l, const SafeBool<U>& r)
98  { l.This_type_does_not_support_this_comparison(); return false; }
99 template<typename T, typename U> bool operator!=(const SafeBool<T>& l, const SafeBool<U>& r)
100  { l.This_type_does_not_support_this_comparison(); return false; }
104 namespace impl {
105  struct SafeBoolTestCov : SafeBool<SafeBoolTestCov> {
106  void test()
107  { This_type_does_not_support_this_comparison(); }
108  };
109 }
112 
118 template<class T>
119 class Nullable : public SafeBool<Nullable<T> > {
120 public:
121  typedef void EvoNullableType;
122 
124  Nullable() : value_((T)0), null_(true)
125  { }
126 
130  Nullable(const Nullable<T>& src) : value_(src.value_), null_(src.null_)
131  { }
132 
136  Nullable(ValNull) : value_((T)0), null_(true) {
137  }
138 
142  Nullable(T num) : value_(num), null_(false)
143  { }
144 
150  { null_ = src.null_; value_ = src.value_; return *this; }
151 
157  { null_ = false; value_ = value; return *this; }
158 
165  { null_ = true; value_ = (T)0; return *this; }
166 
170  bool operator!() const
171  { return (null_ || value_ == (T)0); }
172 
177  bool operator==(const Nullable<T>& val) const
178  { return (null_ ? val.null_ : !val.null_ && value_ == val.value_); }
179 
186  bool operator==(T val) const
187  { return (null_ ? false : value_ == val); }
188 
193  bool operator!=(const Nullable<T>& val) const
194  { return (null_ ? !val.null_ : val.null_ || value_ != val.value_); }
195 
202  bool operator!=(T val) const
203  { return (null_ ? true : value_ != val); }
204 
211  bool operator<(const Nullable<T>& val) const
212  { return (null_ ? !val.null_ : value_ < val.value_); }
213 
220  bool operator<(T val) const
221  { return (null_ ? true : value_ < val); }
222 
229  bool operator<=(const Nullable<T>& val) const
230  { return (null_ ? true : (val.null_ ? false : value_ <= val.value_)); }
231 
238  bool operator<=(T val) const
239  { return (null_ ? true : value_ <= val); }
240 
247  bool operator>(const Nullable<T>& val) const
248  { return (null_ ? false : (val.null_ ? true : value_ > val.value_)); }
249 
256  bool operator>(T val) const
257  { return (null_ ? false : value_ > val); }
258 
265  bool operator>=(const Nullable<T>& val) const
266  { return (null_ ? val.null_ : (val.null_ ? true : value_ >= val.value_)); }
267 
274  bool operator>=(T val) const
275  { return (null_ ? false : value_ >= val); }
276 
281  int compare(const Nullable<T>& val) const {
282  if (null_) {
283  if (val.null_)
284  return 0;
285  return -1;
286  } else if (val.null_)
287  return 1;
288  return (value_ == val.value_ ? 0 : (value_ < val.value_ ? -1 : 1));
289  }
290 
297  int compare(T val) const {
298  if (null_)
299  return -1;
300  return (value_ == val ? 0 : (value_ < val ? -1 : 1));
301  }
302 
306  const T& operator*() const
307  { return value_; }
308 
313  { return value_; }
314 
318  bool null() const
319  { return null_; }
320 
324  bool valid() const
325  { return !null_; }
326 
330  const T& value() const
331  { return value_; }
332 
336  T& value()
337  { return value_; }
338 
342  Nullable<T>& set()
343  { null_ = true; value_ = (T)0; return *this; }
344 
349  Nullable<T>& set(const Nullable<T>& src)
350  { null_ = src.null_; value_ = src.value_; return *this; }
351 
356  Nullable<T>& set(T src)
357  { null_ = false; value_ = src; return *this; }
358 
366  T& denull() {
367  if (null_)
368  null_ = false;
369  return value_;
370  }
371 
372 private:
373  T value_;
374  bool null_;
375 };
376 
377 // Specialized for minimum size
379 template<> class Nullable<bool> : public SafeBool<Nullable<bool> > {
380 public:
381  Nullable()
382  { value_ = (uchar)nvNULL; }
383  Nullable(const Nullable<bool>& src)
384  { value_ = src.value_; }
385  Nullable(bool val)
386  { value_ = (uchar)(val ? nvTRUE : nvFALSE); }
387  Nullable<bool>& operator=(const Nullable<bool>& src)
388  { value_ = src.value_; return *this; }
389  Nullable<bool>& operator=(bool val)
390  { value_ = (uchar)(val ? nvTRUE : nvFALSE); return *this; }
391  Nullable<bool>& operator=(ValNull)
392  { value_ = (uchar)nvNULL; return *this; }
393 
394  bool operator!() const
395  { return (value_ != (uchar)nvTRUE); }
396  bool operator==(const Nullable<bool>& val) const
397  { return (value_ == val.value_); }
398  bool operator==(bool val) const
399  { return (value_ != (uchar)nvNULL && val == (value_ == (uchar)nvTRUE)); }
400  bool operator!=(const Nullable<bool>& val) const
401  { return (value_ != val.value_); }
402  bool operator!=(bool val) const
403  { return (value_ == (uchar)nvNULL || val != (value_ == (uchar)nvTRUE)); }
404 
405  bool operator<(const Nullable<bool>& val) const
406  { return (value_ < val.value_); }
407  bool operator<(bool val) const
408  { return (value_ < (uchar)(val ? nvTRUE : nvFALSE)); }
409  bool operator<=(const Nullable<bool>& val) const
410  { return (value_ <= val.value_); }
411  bool operator<=(bool val) const
412  { return (value_ <= (uchar)(val ? nvTRUE : nvFALSE)); }
413  bool operator>(const Nullable<bool>& val) const
414  { return (value_ > val.value_); }
415  bool operator>(bool val) const
416  { return (value_ > (uchar)(val ? nvTRUE : nvFALSE)); }
417  bool operator>=(const Nullable<bool>& val) const
418  { return (value_ >= val.value_); }
419  bool operator>=(bool val) const
420  { return (value_ >= (uchar)(val ? nvTRUE : nvFALSE)); }
421 
422  int compare(const Nullable<bool>& val) const
423  { return (value_ == val.value_ ? 0 : (value_ < val.value_ ? -1 : 1)); }
424 
425  const bool operator*() const
426  { return (value_ == (uchar)nvTRUE); }
427 
428  bool null() const
429  { return (value_ == (uchar)nvNULL); }
430  bool valid() const
431  { return (value_ != (uchar)nvNULL); }
432  const bool value() const
433  { return (value_ == (uchar)nvTRUE); }
434 
435  Nullable<bool>& set()
436  { value_ = (uchar)nvNULL; return *this; }
437  Nullable<bool>& set(const Nullable<bool>& src)
438  { value_ = src.value_; return *this; }
439  Nullable<bool>& set(bool val)
440  { value_ = (uchar)(val ? nvTRUE : nvFALSE); return *this; }
441 
442  bool denull() {
443  if (value_ == nvNULL) {
444  value_ = nvFALSE;
445  return false;
446  }
447  return (value_ == nvTRUE);
448  }
449 
450 private:
451  enum NullableValue {
452  nvNULL=0,
453  nvFALSE,
454  nvTRUE
455  };
456 
457  uchar value_;
458 };
468 template<class T> inline bool operator==(T val1, const Nullable<T>& val2)
469  { return val2 == val1; }
470 
478 template<class T> inline bool operator!=(T val1, const Nullable<T>& val2)
479  { return val2 != val1; }
480 
488 template<class T> inline bool operator<(T val1, const Nullable<T>& val2)
489  { return val2 > val1; }
490 
498 template<class T> inline bool operator<=(T val1, const Nullable<T>& val2)
499  { return val2 >= val1; }
500 
508 template<class T> inline bool operator>(T val1, const Nullable<T>& val2)
509  { return val2 < val1; }
510 
518 template<class T> inline bool operator>=(T val1, const Nullable<T>& val2)
519  { return val2 <= val1; }
520 
522 
568 struct Bool : public Nullable<bool> {
569  typedef bool Type;
570 
571  static const int BYTES = sizeof(bool);
572  static const int BITS = 1;
573 
576  { }
577 
581  Bool(const Bool& val) : Nullable<bool>(val)
582  { }
583 
587  Bool(bool val) : Nullable<bool>(val)
588  { }
589 
594  Bool& operator=(const Bool& val)
595  { Nullable<bool>::operator=(val); return *this; }
596 
601  Bool& operator=(bool val)
602  { Nullable<bool>::operator=(val); return *this; }
603 
608  { Nullable<bool>::set(); return *this; }
609 };
610 
612 
678 template<class T>
679 struct CharT : public Nullable<T> {
680  typedef CharT<T> This;
681  typedef T Type;
682 
683  static const int BYTES = sizeof(T);
684  static const int BITS = BYTES * CHAR_BIT;
685 
702  enum Category {
703  cNONE=0,
710  cALPHA_L
711  };
712 
725  enum Digit {
726  dNONE=0,
730  dOCTAL
731  };
732 
735  { }
736 
740  CharT(const CharT<T>& val) : Nullable<T>(val)
741  { }
742 
746  CharT(T val) : Nullable<T>(val)
747  { }
748 
754  { Nullable<T>::operator=(val); return *this; }
755 
760  CharT<T>& operator=(char val)
761  { Nullable<T>::operator=(val); return *this; }
762 
767  { Nullable<T>::set(); return *this; }
768 };
769 
775 struct Char : public CharT<char> {
782  static Category category(char ch) {
783  const char chmap[128] = {
784  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // 0-15
785  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
786  1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 32-47
787  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, // 48-63
788  2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 64-79
789  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, // 80-95
790  2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 96-111
791  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 0 // 112-127
792  };
793  return (Category)((uchar)ch < 128 ? chmap[(uint)ch] : 0);
794  }
795 
802  static Digit digit(char ch) {
803  const char chmap[128] = {
804  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
805  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
806  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
807  4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 0, 0, 0, 0, 0, 0, // 48-63
808  0, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64-79
809  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 80-95
810  0, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96-111
811  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 // 112-127
812  };
813  return (Digit)((uchar)ch < 128 ? chmap[(uint)ch] : 0);
814  }
815 
820  static bool isspace(char ch)
821  { return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); }
822 
827  static bool isupper(char ch)
828  { return (ch >= 'A' && ch <= 'Z'); }
829 
834  static bool islower(char ch)
835  { return (ch >= 'a' && ch <= 'z'); }
836 
841  static bool isalpha(char ch)
842  { return ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')); }
843 
848  static bool isalnum(char ch)
849  { return ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')); }
850 
855  static bool isdigit(char ch)
856  { return (ch >= '0' && ch <= '9'); }
857 
860  { }
861 
865  Char(const Char& val) : CharT<char>(val)
866  { }
867 
871  Char(char val) : CharT<char>(val)
872  { }
873 
878  Char& operator=(const Char& val)
879  { Nullable<char>::operator=(val); return *this; }
880 
885  Char& operator=(char val)
886  { Nullable<char>::operator=(val); return *this; }
887 
892  { Nullable<char>::set(); return *this; }
893 };
894 
896 
898 namespace impl {
899  template<int IntSize> struct IntMaxLen { };
900  // Max string length by int size in bytes, including either sign or hex/oct prefix (0x/0), but not both
901  template<> struct IntMaxLen<1> { static const int value = 4; };
902  template<> struct IntMaxLen<2> { static const int value = 7; };
903  template<> struct IntMaxLen<4> { static const int value = 12; };
904  template<> struct IntMaxLen<8> { static const int value = 23; };
905 }
908 
910 // Disable constant truncation MSVC warnings for constants using bit manipulation
911 #if defined(_MSC_VER)
912  #pragma warning(push)
913  #pragma warning(disable:4309)
914 #endif
915 
979 template<class T>
980 struct IntegerT : public Nullable<T> {
981  typedef IntegerT<T> This;
982  typedef T Type;
983 
984  static const bool SIGN = IsSigned<T>::value;
985  static const int BYTES = sizeof(T);
986  static const int BITS = sizeof(T) * 8;
987  static const int MAXSTRLEN = impl::IntMaxLen<sizeof(T)>::value;
988 
989  static const int BITS_MINUS_1 = BITS - 1;
990  static const T RBIT = 0x01;
991  static const T LBIT = RBIT << BITS_MINUS_1;
992  static const T ZERO = 0;
993  static const T ALLBITS = T(~ZERO);
994 
995  static const T MIN = (SIGN ? LBIT : 0);
996  static const T MAX = (SIGN ? ~LBIT : ALLBITS);
997 
1004  static int maxlen(int base=10) {
1005  // Note: Newer compilers (gcc 4.9.2) give c++11 'narrowing conversion' warnings if 'values' are smaller than int, casting doesn't fix
1006  if (base >= 100)
1007  base -= 100;
1008  assert( base > 1 );
1009  assert( base <= 36 );
1010  static const int n = (SIGN ? 1 : 0);
1011  static const int VALUES[] = {
1012  digits(MAX,2)+n, digits(MAX,3)+n, digits(MAX,4)+n, digits(MAX,5)+n, digits(MAX,6)+n,
1013  digits(MAX,7)+n, digits(MAX,8)+1, digits(MAX,9)+n, digits(MAX,10)+n, digits(MAX,11)+n,
1014  digits(MAX,12)+n, digits(MAX,13)+n, digits(MAX,14)+n, digits(MAX,15)+n, digits(MAX,16)+n+1,
1015  digits(MAX,17)+n, digits(MAX,18)+n, digits(MAX,19)+n, digits(MAX,20)+n, digits(MAX,21)+n,
1016  digits(MAX,22)+n, digits(MAX,23)+n, digits(MAX,24)+n, digits(MAX,25)+n, digits(MAX,26)+n,
1017  digits(MAX,27)+n, digits(MAX,28)+n, digits(MAX,29)+n, digits(MAX,30)+n, digits(MAX,31)+n,
1018  digits(MAX,32)+n, digits(MAX,33)+n, digits(MAX,34)+n, digits(MAX,35)+n, digits(MAX,36)+n
1019  };
1020  return VALUES[base-2];
1021  }
1022 
1028  static int digits(T num, int base=10) {
1029  if (base >= 100)
1030  base -= 100;
1031  assert( base > 1 );
1032  assert( base < 100 );
1033  int result = 0;
1034  if (num == 0)
1035  result = 1;
1036  else {
1037  if (num < 0)
1038  ++result;
1039  while (num != 0) {
1040  num /= (int8)base;
1041  ++result;
1042  }
1043  }
1044  return result;
1045  }
1046 
1049  { }
1050 
1054  IntegerT(const IntegerT<T>& val) : Nullable<T>(val)
1055  { }
1056 
1060  IntegerT(T val) : Nullable<T>(val)
1061  { }
1062 
1068  { Nullable<T>::operator=(val); return *this; }
1069 
1075  { Nullable<T>::operator=(val); return *this; }
1076 
1081  { Nullable<T>::set(); return *this; }
1082 
1083  using Nullable<T>::value;
1084 
1089  T value(T defval) const
1090  { return (Nullable<T>::null() ? defval : Nullable<T>::value()); }
1091 };
1092 
1093 #if defined(_MSC_VER)
1094  #pragma warning(pop)
1095 #endif
1096 
1103 
1110 
1117 
1124 
1131 
1138 
1145 
1152 
1159 
1166 
1173 
1180 
1187 
1194 
1201 
1208 
1210 
1212 namespace impl {
1213  template<class T> struct ConstFloatT {
1214  static T point1() { return 0.1f; }
1215  static T ten() { return 10.0f; }
1216  };
1217  template<> struct ConstFloatT<double> {
1218  static double point1() { return 0.1; }
1219  static double ten() { return 10.0; }
1220  };
1221  template<> struct ConstFloatT<ldouble> {
1222  static ldouble point1() { return 0.1L; }
1223  static ldouble ten() { return 10.0L; }
1224  };
1225 };
1226 
1290 template<class T>
1291 struct FloatT : public Nullable<T> {
1292  typedef FloatT<T> This;
1293  typedef T Type;
1294 
1295  static const bool IS = IsFloat<T>::value;
1296  static const bool SIGN = true;
1297  static const int BYTES = sizeof(T);
1298  static const int MAXDIGITS = std::numeric_limits<T>::digits10;
1299  static const bool NANOK = std::numeric_limits<T>::has_quiet_NaN;
1300 
1301  static const int MAXDIGITS_AUTO = MAXDIGITS + 15;
1302 
1306  static int maxdigits_prec(int exp, int precision) {
1307  const int BASEDIGITS = MAXDIGITS + 9;
1308  return BASEDIGITS + (exp < 0 ? -exp : exp) + precision;
1309  }
1310 
1314  static T precision() {
1315  static const T VAL = evo_pow(impl::ConstFloatT<T>::point1(), std::numeric_limits<T>::digits10);
1316  return VAL;
1317  }
1318 
1322  static T min()
1323  { return std::numeric_limits<T>::min(); }
1324 
1328  static int minexp()
1329  { return std::numeric_limits<T>::min_exponent10; }
1330 
1334  static T max()
1335  { return std::numeric_limits<T>::max(); }
1336 
1340  static int maxexp()
1341  { return std::numeric_limits<T>::max_exponent10; }
1342 
1346  static T inf()
1347  { return std::numeric_limits<T>::infinity(); }
1348 
1352  static bool inf(T num) {
1353  if (num < 0.0)
1354  num = -num;
1355  return (std::numeric_limits<T>::has_infinity && num == std::numeric_limits<T>::infinity());
1356  }
1357 
1361  static bool nan(T num)
1362  { return (num != num); }
1363 
1369  static T nan() {
1370  static const T val = (T)(NANOK ? std::numeric_limits<T>::quiet_NaN() : 0.0);
1371  return val;
1372  }
1373 
1377  static T eps()
1378  { return std::numeric_limits<T>::epsilon(); }
1379 
1388  static bool eq(T val1, T val2) {
1389  static const T EPSILON = std::numeric_limits<T>::epsilon();
1390  return ( (nan(val1) && nan(val2)) || val1 == val2 || evo_fabs(val1 - val2) <= EPSILON );
1391  }
1392 
1399  static bool eq(T val1, T val2, T eps)
1400  { return ( (nan(val1) && nan(val2)) || val1 == val2 || evo_fabs(val1 - val2) <= eps ); }
1401 
1407  static T exp10(T num, int exp) {
1408  T result = 0.0;
1409  if (exp == 0)
1410  result = num;
1411  else if (num != 0.0) {
1412  bool neg = false;
1413  if (exp < 0) {
1414  neg = true;
1415  exp = -exp;
1416  }
1417  T power = 10.0;
1418  result = 1.0;
1419  for (int bit = 1; exp != 0; bit <<= 1) {
1420  if (exp & bit) {
1421  exp ^= bit;
1422  result *= power;
1423  if (exp == 0)
1424  break;
1425  }
1426  power *= power;
1427  }
1428  result = (neg ? num / result : num * result);
1429  }
1430  return result;
1431  }
1432 
1438  static T fexp10(int& exp, T num) {
1439  bool neg = false;
1440  if (num < 0.0)
1441  { neg = true; num = -num; }
1442  exp = 0;
1443  if (!nan(num) && !inf(num) && num != 0.0) {
1444  if (num >= 1.0) {
1445  static const int BIGNUM_DIGITS = std::numeric_limits<T>::digits10;
1446  static const T BIGNUM = evo_pow(impl::ConstFloatT<T>::ten(), BIGNUM_DIGITS);
1447  while (num >= BIGNUM)
1448  { num /= BIGNUM; exp += BIGNUM_DIGITS; }
1449  while (num >= 1000.0)
1450  { num /= 1000.0; exp += 3; }
1451  do {
1452  num /= 10.0; ++exp;
1453  } while (num >= 1.0);
1454  } else {
1455  while (num < 0.001 && num > 0.0)
1456  { num *= 1000.0; exp -= 3; }
1457  if (num > 0.0) {
1458  if (num < 0.01)
1459  { num *= 100.0; exp -= 2; }
1460  else if (num < 0.1)
1461  { num *= 10.0; --exp; }
1462  }
1463  }
1464  }
1465  return (neg ? -num : num);
1466  }
1467 
1470  { }
1471 
1475  FloatT(const FloatT<T>& val) : Nullable<T>(val)
1476  { }
1477 
1481  FloatT(T val) : Nullable<T>(val)
1482  { }
1483 
1489  { Nullable<T>::operator=(val); return *this; }
1490 
1496  { Nullable<T>::operator=(val); return *this; }
1497 
1502  { Nullable<T>::set(); return *this; }
1503 
1510  bool eq1(const Nullable<T>& val) {
1511  return ( (this->null() && val.null()) ||
1512  (this->null() == val.null() && FloatT<T>::eq(this->value(), val.value())) );
1513  }
1514 
1521  bool eq1(T val)
1522  { return (!this->null() && FloatT<T>::eq(this->value(), val)); }
1523 
1524  using Nullable<T>::value;
1525 
1530  T value(T defval) const
1531  { return (Nullable<T>::null() ? defval : Nullable<T>::value()); }
1532 };
1533 
1540 
1547 
1554 
1556 
1561 template<class T, class P=T*>
1562 struct PtrBase : public SafeBool<PtrBase<T> > {
1563  typedef void EvoNullableType;
1564  typedef PtrBase<T,P> Base;
1565 
1566  P ptr_;
1567 
1573  const T& operator*() const {
1574  assert(ptr_ != NULL);
1575  return *ptr_;
1576  }
1577 
1583  T& operator*() {
1584  assert(ptr_ != NULL);
1585  return *ptr_;
1586  }
1587 
1593  const T* operator->() const {
1594  assert(ptr_ != NULL);
1595  return ptr_;
1596  }
1597 
1603  T* operator->() {
1604  assert(ptr_ != NULL);
1605  return ptr_;
1606  }
1607 
1613  const T& operator[](ulong index) const {
1614  assert(ptr_ != NULL);
1615  return ptr_[index];
1616  }
1617 
1623  T& operator[](ulong index) {
1624  assert(ptr_ != NULL);
1625  return ptr_[index];
1626  }
1627 
1631  bool operator!() const
1632  { return ptr_ == NULL; }
1633 
1638  bool operator==(const Base& ptr) const
1639  { return ptr_ == ptr.ptr_; }
1640 
1645  bool operator==(void* ptr) const
1646  { return ptr_ == ptr; }
1647 
1652  bool operator!=(const Base& ptr) const
1653  { return ptr_ != ptr.ptr_; }
1654 
1659  bool operator!=(void* ptr) const
1660  { return ptr_ != ptr; }
1661 
1666  bool operator<(const Base& ptr) const
1667  { return ptr_ < ptr.ptr_; }
1668 
1673  bool operator<(void* ptr) const
1674  { return ptr_ < ptr; }
1675 
1680  bool operator<=(const Base& ptr) const
1681  { return ptr_ <= ptr.ptr_; }
1682 
1687  bool operator<=(void* ptr) const
1688  { return ptr_ <= ptr; }
1689 
1694  bool operator>(const Base& ptr) const
1695  { return ptr_ > ptr.ptr_; }
1696 
1701  bool operator>(void* ptr) const
1702  { return ptr_ > ptr; }
1703 
1708  bool operator>=(const Base& ptr) const
1709  { return ptr_ >= ptr.ptr_; }
1710 
1715  bool operator>=(void* ptr) const
1716  { return ptr_ >= ptr; }
1717 
1721  bool null() const
1722  { return (ptr_ == NULL); }
1723 
1727  bool valid() const
1728  { return (ptr_ != NULL); }
1729 
1735  const T* ptr() const
1736  { return ptr_; }
1737 
1743  T* ptr()
1744  { return ptr_; }
1745 };
1746 
1748 
1757 template<class T, class C> struct Convert {
1762  static void set(C& dest, T value)
1763  STATIC_ASSERT_FUNC_UNUSED // Override required to support conversion
1764 
1769  static void add(C& dest, T value)
1770  STATIC_ASSERT_FUNC_UNUSED // Override required to support conversion
1771 
1785  static bool addq(C& dest, T value, typename C::Value delim)
1786  STATIC_ASSERT_FUNC_UNUSED_RET(false) // Override required to support conversion
1787 
1788 
1792  static const T& value(const T& src)
1793  STATIC_ASSERT_FUNC_UNUSED_RET(src) // Override required to support conversion
1794 };
1795 
1797 
1798 // Special type for NONE, ALL, END values -- used internally.
1800 struct EndT {
1801  // Evo sizes are unsigned, use max value
1802  operator unsigned char() const
1803  { return IntegerT<unsigned char>::MAX; }
1804  operator unsigned short() const
1805  { return IntegerT<unsigned short>::MAX; }
1806  operator unsigned int() const
1807  { return IntegerT<unsigned int>::MAX; }
1808  operator unsigned long() const
1809  { return IntegerT<unsigned long>::MAX; }
1810  operator unsigned long long() const
1812 
1813  EndT() { }
1814 };
1815 
1816 template<class T> bool operator==(T a, EndT)
1817  { return (a == IntegerT<T>::MAX); }
1818 template<class T> bool operator==(EndT, T b)
1819  { return (b == IntegerT<T>::MAX); }
1820 
1821 template<class T> bool operator!=(T a, EndT)
1822  { return (a != IntegerT<T>::MAX); }
1823 template<class T> bool operator!=(EndT, T b)
1824  { return (b != IntegerT<T>::MAX); }
1832 static const EndT NONE;
1833 
1839 static const EndT ALL;
1840 
1846 static const EndT END;
1847 
1849 
1853 #define EVO_PDEFAULT ((T*)IntegerT<std::size_t>::MAX)
1854 
1858 #define EVO_PEMPTY ((T*)1)
1859 
1863 #define EVO_PPEMPTY ((T**)1)
1864 
1866 
1867 // Implementation
1869 namespace impl {
1870  template<class T, int SZ=sizeof(T)>
1871  struct NextPow2 {
1872  static T next(T v) {
1873  T n = 1;
1874  while (n < v)
1875  n <<= 1;
1876  return n;
1877  }
1878  };
1879 
1880  template<class T> struct NextPow2<T,1> {
1881  static uint8 next(uint8 v) {
1882  --v;
1883  v |= v >> 1;
1884  v |= v >> 2;
1885  v |= v >> 4;
1886  return ++v;
1887  }
1888  };
1889  template<class T> struct NextPow2<T,2> {
1890  static uint16 next(uint16 v) {
1891  --v;
1892  v |= v >> 1;
1893  v |= v >> 2;
1894  v |= v >> 4;
1895  v |= v >> 8;
1896  return ++v;
1897  }
1898  };
1899  template<class T> struct NextPow2<T,4> {
1900  static uint32 next(uint32 v) {
1901  --v;
1902  v |= v >> 1;
1903  v |= v >> 2;
1904  v |= v >> 4;
1905  v |= v >> 8;
1906  v |= v >> 16;
1907  return ++v;
1908  }
1909  };
1910  template<class T> struct NextPow2<T,8> {
1911  static uint64 next(uint64 v) {
1912  --v;
1913  v |= v >> 1;
1914  v |= v >> 2;
1915  v |= v >> 4;
1916  v |= v >> 8;
1917  v |= v >> 16;
1918  v |= v >> 32;
1919  return ++v;
1920  }
1921  };
1922 }
1931 template<class T>
1932 inline T next_pow2(T v) {
1933  assert( !IntegerT<T>::SIGN );
1934  v += (v == 0);
1935  return impl::NextPow2<T>::next(v);
1936 }
1937 
1950 template<class Size>
1951 inline Size size_pow2(Size size, Size minsize=2) {
1952  assert( !IntegerT<Size>::SIGN );
1953  if (size <= minsize)
1954  return minsize;
1955  const Size MAX_SIZE = (std::numeric_limits<Size>::max() >> 1) + 1;
1956  if (size >= MAX_SIZE)
1957  return MAX_SIZE;
1958  return impl::NextPow2<Size>::next(size);
1959 }
1960 
1966 template<class T>
1967 inline bool is_pow2(T num)
1968  { return (num && (num & (num - 1)) == 0); }
1969 
1971 
1975 class PureBase {
1976 public:
1978  virtual ~PureBase() {
1979  }
1980 };
1981 
1983 
1984 }
1985 #endif
FloatT< T > & operator=(ValNull)
Assignment operator to set as null.
Definition: type.h:1501
const T & operator*() const
Dereference operator (const).
Definition: type.h:1573
Nullable< T > & operator=(T value)
Constructor to init with value.
Definition: type.h:156
T & max(T &a, T &b)
Returns highest of given values.
Definition: alg.h:47
FloatT()
Constructor.
Definition: type.h:1469
FloatT< long double > FloatL
Basic long-double floating-point type (long double) – see FloatT.
Definition: type.h:1553
Bool & operator=(bool val)
Assignment operator.
Definition: type.h:601
static T inf()
Get infinity value.
Definition: type.h:1346
static bool isupper(char ch)
Check whether uppercase letter (A-Z).
Definition: type.h:827
static int minexp()
Get minimum allowed exponent.
Definition: type.h:1328
T value(T defval) const
Get underlying value or given default if null.
Definition: type.h:1530
#define STATIC_ASSERT_FUNC_UNUSED
Assert a function is unused at compile-time.
Definition: meta.h:80
FloatT< T > & operator=(T val)
Assignment operator.
Definition: type.h:1495
Char(char val)
Constructor.
Definition: type.h:871
Decimal digit (0-9)
Definition: type.h:707
Bool(bool val)
Constructor.
Definition: type.h:587
Nullable(T num)
Constructor to init with num.
Definition: type.h:142
Basic boolean type.
Definition: type.h:568
static bool isspace(char ch)
Check whether whitespace character (space, tab, newline, carrige return).
Definition: type.h:820
Nullable primitive base type.
Definition: type.h:119
IntegerT< uint32 > UInt32
Basic integer type (uint32) – see IntegerT.
Definition: type.h:1200
bool operator==(void *ptr) const
Equality operator.
Definition: type.h:1645
bool null() const
Get whether null.
Definition: type.h:318
Nullable< T > & set()
Set as null.
Definition: type.h:342
Char & operator=(ValNull)
Assignment operator to set as null.
Definition: type.h:891
FloatT(const FloatT< T > &val)
Copy constructor.
Definition: type.h:1475
CharT< T > & operator=(char val)
Assignment operator.
Definition: type.h:760
PtrBase< T, P > Base
This pointer base type.
Definition: type.h:1564
CharT< T > & operator=(ValNull)
Assignment operator to set as null by passing vNULL.
Definition: type.h:766
bool null() const
Get whether pointer is null.
Definition: type.h:1721
bool operator<(void *ptr) const
Less-than operator.
Definition: type.h:1673
bool operator>=(const Base &ptr) const
Greater-than-or-equals operator.
Definition: type.h:1708
bool operator!=(void *ptr) const
Inequality operator.
Definition: type.h:1659
static T nan()
Get Not-A-Number (NaN) value.
Definition: type.h:1369
T Type
Wrapped POD type.
Definition: type.h:681
static bool eq(T val1, T val2, T eps)
Get whether values are approximately equal using given epsilon value.
Definition: type.h:1399
static Digit digit(char ch)
Get digit type for character.
Definition: type.h:802
bool operator>(const Nullable< T > &val) const
Greater than operator.
Definition: type.h:247
virtual ~PureBase()
Destructor.
Definition: type.h:1978
Basic character type (char) – see CharT.
Definition: type.h:775
FloatT< T > This
This non-POD type
Definition: type.h:1292
IntegerT< uint > UInt
Basic integer type (unsigned int) – see IntegerT.
Definition: type.h:1165
Bool(const Bool &val)
Copy constructor.
Definition: type.h:581
IntegerT< T > & operator=(const IntegerT< T > &val)
Assignment operator.
Definition: type.h:1067
Nullable(const Nullable< T > &src)
Copy constructor.
Definition: type.h:130
bool operator<=(T val) const
Less than or equal operator.
Definition: type.h:238
static bool inf(T num)
Check whether value is infinite.
Definition: type.h:1352
const T & operator[](ulong index) const
Array access operator (const).
Definition: type.h:1613
bool valid() const
Get whether pointer is valid (not null).
Definition: type.h:1727
ValNull
Unique null value type and value (vNULL).
Definition: sys.h:1096
CharT()
Constructor.
Definition: type.h:734
static int maxlen(int base=10)
Get maximum formatted length for type at base.
Definition: type.h:1004
Hexadecimal character.
Definition: type.h:728
bool operator==(const Base &ptr) const
Equality operator.
Definition: type.h:1638
T & value()
Get underlying value.
Definition: type.h:336
static int digits(T num, int base=10)
Get number of digits for given number and base.
Definition: type.h:1028
bool operator!=(const Nullable< T > &val) const
Inequality operator.
Definition: type.h:193
IntegerT< ulongl > ULongL
Basic integer type (unsigned long long) – see IntegerT.
Definition: type.h:1179
IntegerT< ushort > UShort
Basic integer type (unsigned short) – see IntegerT.
Definition: type.h:1158
bool operator<=(const Base &ptr) const
Less-than-or-equals operator.
Definition: type.h:1680
CharT< T > & operator=(const CharT< char > &val)
Assignment operator.
Definition: type.h:753
bool operator>(T val) const
Greater than operator.
Definition: type.h:256
static T eps()
Get machine epsilon.
Definition: type.h:1377
bool operator>=(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Greater-than-or-equals operator for managed pointer base and atomic pointer base. ...
Definition: atomic.h:1238
const T * ptr() const
Get current pointer (const).
Definition: type.h:1735
static int maxexp()
Get maximum allowed exponent.
Definition: type.h:1340
Char & operator=(char val)
Assignment operator.
Definition: type.h:885
T & operator*()
Dereference operator (mutable).
Definition: type.h:1583
Decimal character.
Definition: type.h:729
SafeBool()
Constructor.
Definition: type.h:82
Generic value conversion template.
Definition: type.h:1757
static bool eq(T val1, T val2)
Get whether values are approximately equal.
Definition: type.h:1388
T next_pow2(T v)
Get next power of 2 equal to or greater than given number.
Definition: type.h:1932
void EvoNullableType
Identify as nullable type.
Definition: type.h:1563
IntegerT< int64 > Int64
Basic integer type (int64) – see IntegerT.
Definition: type.h:1151
const T * operator->() const
Member access operator (const).
Definition: type.h:1593
Bool()
Constructor.
Definition: type.h:575
Basic integer type.
Definition: type.h:980
CharT< T > This
This non-POD type
Definition: type.h:680
int compare(const Nullable< T > &val) const
Comparison.
Definition: type.h:281
IntegerT< uint16 > UInt16
Basic integer type (uint16) – see IntegerT.
Definition: type.h:1193
IntegerT< ulong > ULong
Basic integer type (unsigned long) – see IntegerT.
Definition: type.h:1172
T value(T defval) const
Get underlying value or given default if null.
Definition: type.h:1089
T & operator*()
Dereference for explicit conversion to underlying type.
Definition: type.h:312
bool operator!=(T val) const
Inequality operator.
Definition: type.h:202
static T max()
Get maximum normalized value.
Definition: type.h:1334
static Category category(char ch)
Get character category.
Definition: type.h:782
bool operator<=(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Less-than-or-equals operator for managed pointer base and atomic pointer base.
Definition: atomic.h:1220
IntegerT(const IntegerT< T > &val)
Copy constructor.
Definition: type.h:1054
bool operator!() const
Negation operator checks if NULL.
Definition: type.h:1631
T & operator[](ulong index)
Array access operator (mutable).
Definition: type.h:1623
bool operator!=(const Base &ptr) const
Inequality operator.
Definition: type.h:1652
IntegerT(T val)
Constructor.
Definition: type.h:1060
static bool isdigit(char ch)
Check whether a digit (0-9).
Definition: type.h:855
static int maxdigits_prec(int exp, int precision)
Get max formatting digits with given exponent and precision, including sign and any additional chars ...
Definition: type.h:1306
static T min()
Get minimum normalized value.
Definition: type.h:1322
Nullable< T > & operator=(const Nullable< T > &src)
Assignment/Copy operator.
Definition: type.h:149
Safe bool base class.
Definition: type.h:73
bool eq1(const Nullable< T > &val)
Get whether approximately equal to given value.
Definition: type.h:1510
Symbol character (printable but not alphanumeric)
Definition: type.h:705
Category
Character category.
Definition: type.h:702
bool operator==(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Equality operator for managed pointer base and atomic pointer base.
Definition: atomic.h:1193
IntegerT< uint8 > UInt8
Basic integer type (uint8) – see IntegerT.
Definition: type.h:1186
#define STATIC_ASSERT_FUNC_UNUSED_RET(RET)
Assert a function is unused at compile-time (with return value).
Definition: meta.h:96
Nullable< T > & operator=(ValNull)
Assignment operator to set as null.
Definition: type.h:164
Bool & operator=(const Bool &val)
Assignment operator.
Definition: type.h:594
FloatT(T val)
Constructor.
Definition: type.h:1481
static const EndT END
Special integer value for indicating end of items or no item.
Definition: type.h:1846
FloatT< T > & operator=(const FloatT< T > &val)
Assignment operator.
Definition: type.h:1488
const T & operator*() const
Dereference for explicit conversion to underlying type (const).
Definition: type.h:306
static const EndT ALL
Special integer value for indicating all items or all remaining items.
Definition: type.h:1839
IntegerT< longl > LongL
Basic integer type (long long) – see IntegerT.
Definition: type.h:1123
Nullable primitive character base type.
Definition: type.h:679
static bool nan(T num)
Get whether value is Not-A-Number (NaN).
Definition: type.h:1361
Evo container foundation types and macros.
bool operator!=(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Inequality operator for managed pointer base and atomic pointer base.
Definition: atomic.h:1202
bool is_pow2(T num)
Get whether a number is a power of 2.
Definition: type.h:1967
int compare(T val) const
Comparison.
Definition: type.h:297
bool operator==(T val) const
Equality operator.
Definition: type.h:186
T Type
Wrapped POD type.
Definition: type.h:1293
void EvoNullableType
Identify as nullable type.
Definition: type.h:121
bool operator<(T val) const
Less than operator.
Definition: type.h:220
T * ptr()
Get current pointer (mutable).
Definition: type.h:1743
bool operator>=(T val) const
Greater than or equal operator.
Definition: type.h:274
bool operator<(const Base &ptr) const
Less-than operator.
Definition: type.h:1666
bool operator>=(const Nullable< T > &val) const
Greater than or equal operator.
Definition: type.h:265
Evo C++ Library namespace.
Definition: alg.h:11
IntegerT< int32 > Int32
Basic integer type (int32) – see IntegerT.
Definition: type.h:1144
static const EndT NONE
Special integer value for indicating no item or unknown item.
Definition: type.h:1832
static T exp10(T num, int exp)
Multiply number by 10 raised to exponent.
Definition: type.h:1407
IntegerT< long > Long
Basic integer type (long) – see IntegerT.
Definition: type.h:1116
bool operator>=(void *ptr) const
Greater-than-or-equals operator.
Definition: type.h:1715
Whitespace (space, tab)
Definition: type.h:704
bool operator>(void *ptr) const
Greater-than operator.
Definition: type.h:1701
T & denull()
Clears null flag and returns value reference.
Definition: type.h:366
Char & operator=(const Char &val)
Assignment operator.
Definition: type.h:878
T Type
Wrapped POD type.
Definition: type.h:982
Char(const Char &val)
Copy constructor.
Definition: type.h:865
static bool islower(char ch)
Check whether lowercase letter (a-z).
Definition: type.h:834
bool operator==(const Nullable< T > &val) const
Equality operator.
Definition: type.h:177
IntegerT< uint64 > UInt64
Basic integer type (uint64) – see IntegerT.
Definition: type.h:1207
Check if type is a floating point type.
Definition: meta.h:277
Check if integer type is unsigned.
Definition: meta.h:296
CharT(const CharT< T > &val)
Copy constructor.
Definition: type.h:740
static T fexp10(int &exp, T num)
Extract normalized base 10 mantissa and exponent from number.
Definition: type.h:1438
bool operator>(const Base &ptr) const
Greater-than operator.
Definition: type.h:1694
bool operator!() const
Negation operator returns whether null or 0.
Definition: type.h:170
P ptr_
Pointer.
Definition: type.h:1566
T * operator->()
Member access operator (mutable).
Definition: type.h:1603
Alphabet – categories greater than this are alphabetic.
Definition: type.h:708
Base 36 character.
Definition: type.h:727
bool eq1(T val)
Get whether approximately equal to given value.
Definition: type.h:1521
Digit
Character digit type.
Definition: type.h:725
Bool & operator=(ValNull)
Assignment operator to set as null.
Definition: type.h:607
bool operator<=(void *ptr) const
Less-than-or-equals operator.
Definition: type.h:1687
IntegerT< T > This
This non-POD type
Definition: type.h:981
bool valid() const
Get whether valid (not null).
Definition: type.h:324
Pure base class, i.e.
Definition: type.h:1975
Nullable()
Constructor.
Definition: type.h:124
IntegerT< int16 > Int16
Basic integer type (int16) – see IntegerT.
Definition: type.h:1137
bool operator>(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Greater-than operator for managed pointer base and atomic pointer base.
Definition: atomic.h:1229
Nullable basic floating-point base type.
Definition: type.h:1291
Alpha-numeric – categories greater than this are alphanumeric.
Definition: type.h:706
bool Type
Wrapped type (bool)
Definition: type.h:569
IntegerT()
Constructor.
Definition: type.h:1048
static bool isalnum(char ch)
Check whether alphanumeric (A-Z, a-z, 0-9).
Definition: type.h:848
const T & value() const
Get underlying value (const).
Definition: type.h:330
static bool isalpha(char ch)
Check whether alphabetic (A-Z, a-z).
Definition: type.h:841
bool operator<(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Less-than operator for managed pointer base and atomic pointer base.
Definition: atomic.h:1211
Alphabet uppercase (A-Z)
Definition: type.h:709
Base managed pointer.
Definition: type.h:1562
IntegerT< short > Short
Basic integer type (short) – see IntegerT.
Definition: type.h:1102
Char()
Constructor.
Definition: type.h:859
T & min(T &a, T &b)
Returns lowest of given values.
Definition: alg.h:26
FloatT< float > Float
Basic single-precision floating-point type (float) – see FloatT.
Definition: type.h:1539
IntegerT< T > & operator=(T val)
Assignment operator.
Definition: type.h:1074
static T precision()
Get best precision value.
Definition: type.h:1314
Size size_pow2(Size size, Size minsize=2)
Get size as power of 2.
Definition: type.h:1951
IntegerT< int > Int
Basic integer type (int) – see IntegerT.
Definition: type.h:1109
Nullable(ValNull)
Constructor to explicitly set as null.
Definition: type.h:136
IntegerT< int8 > Int8
Basic integer type (int8) – see IntegerT.
Definition: type.h:1130
CharT(T val)
Constructor.
Definition: type.h:746
FloatT< double > FloatD
Basic double-precision floating-point type (double) – see FloatT.
Definition: type.h:1546
IntegerT< T > & operator=(ValNull)
Assignment operator to set as null by passing vNULL.
Definition: type.h:1080