7 #ifndef MSEPRIMITIVES_H
8 #define MSEPRIMITIVES_H
18 #define MSVC2010_COMPATIBLE 1
21 #define MSVC2013_COMPATIBLE 1
24 #define MSVC2015_COMPATIBLE 1
27 #if (defined(__GNUC__) || defined(__GNUG__))
28 #define GPP_COMPATIBLE 1
29 #if ((5 > __GNUC__) && (!defined(__clang__)))
30 #define GPP4P8_COMPATIBLE 1
35 #ifdef MSE_SAFER_SUBSTITUTES_DISABLED
36 #define MSE_PRIMITIVES_DISABLED
39 #if defined(MSVC2013_COMPATIBLE) || defined(MSVC2010_COMPATIBLE)
42 #define MSE_CONSTEXPR constexpr
45 #ifdef MSVC2015_COMPATIBLE
46 #ifndef MSE_FORCE_PRIMITIVE_ASSIGN_RANGE_CHECK_ENABLED
49 #define MSE_PRIMITIVE_ASSIGN_RANGE_CHECK_DISABLED 1
54 #ifdef MSE_CUSTOM_THROW_DEFINITION
56 #define MSE_THROW(x) MSE_CUSTOM_THROW_DEFINITION(x)
58 #define MSE_THROW(x) throw(x)
62 #ifndef MSE_CINT_BASE_INTEGER_TYPE
63 #if SIZE_MAX <= ULONG_MAX
64 #define MSE_CINT_BASE_INTEGER_TYPE long int
66 #define MSE_CINT_BASE_INTEGER_TYPE long long int
75 using std::range_error::range_error;
80 #ifdef MSE_PRIMITIVES_DISABLED
88 #ifndef MSE_SUPPRESS_CHECK_USE_BEFORE_SET
89 #define MSE_CHECK_USE_BEFORE_SET
117 #ifdef MSE_CHECK_USE_BEFORE_SET
128 template<
typename _TDestination,
typename _TSource>
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))
140 template<
typename _TDestination,
typename _TSource>
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))
148 template<
typename _TDestination,
typename _TSource>
150 #ifndef MSE_PRIMITIVE_ASSIGN_RANGE_CHECK_DISABLED
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())) {
162 if (rhs_can_exceed_lower_bound) {
165 if (0 == std::numeric_limits<_TDestination>::lowest()) {
168 else if (
x < _TSource(std::numeric_limits<_TDestination>::lowest())) {
183 template<
typename _Ty>
195 template<
typename _Tz>
198 g_assign_check_range<_Ty, _Tz>(
x);
203 #ifdef MSE_CHECK_USE_BEFORE_SET
262 operator _Ty()
const { (*this).assert_initialized();
return 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)); }
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)); }
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)); }
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)); }
333 bool operator <=(
long long x)
const { (*this).assert_initialized();
return ((*
this) <=
CInt(
x)); }
342 bool operator >=(
long long x)
const { (*this).assert_initialized();
return ((*
this) >=
CInt(
x)); }
351 bool operator ==(
long long x)
const { (*this).assert_initialized();
return ((*
this) ==
CInt(
x)); }
360 bool operator !=(
long long x)
const { (*this).assert_initialized();
return ((*
this) !=
CInt(
x)); }
378 if (0 <= std::numeric_limits<_Ty>::lowest()) {
379 (*this).assert_initialized();
380 (*this) = (*this) - 1;
return (*
this);
383 (*this).assert_initialized();
384 m_val--;
return (*
this);
403 #define _STCONS(ty, name, val) static constexpr ty name = static_cast<ty>(val)
406 template<>
class numeric_limits<
mse::CInt> {
412 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::min();
416 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max();
420 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::lowest();
424 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::epsilon();
428 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::round_error();
432 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::denorm_min();
436 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::infinity();
440 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::quiet_NaN();
444 return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::signaling_NaN();
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);
529 #ifndef MSVC2010_COMPATIBLE
530 explicit operator size_t()
const { (*this).assert_initialized();
return (
m_val); }
549 m_val -=
x.m_val;
return (*
this);
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)); }
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)); }
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)); }
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)); }
613 bool operator <=(
long long x)
const { (*this).assert_initialized();
return ((*
this) <=
CInt(
x)); }
622 bool operator >=(
long long x)
const { (*this).assert_initialized();
return ((*
this) >=
CInt(
x)); }
631 bool operator ==(
long long x)
const { (*this).assert_initialized();
return ((*
this) ==
CInt(
x)); }
640 bool operator !=(
long long x)
const { (*this).assert_initialized();
return ((*
this) !=
CInt(
x)); }
655 if (0 <= std::numeric_limits<_Ty>::lowest()) { (*this).assert_initialized();
656 (*this) = (*this) - 1;
return (*
this);
658 else { (*this).assert_initialized();
659 m_val--;
return (*
this);
680 #define _STCONS(ty, name, val) static constexpr ty name = (ty)(val)
683 template<>
class numeric_limits<
mse::CSize_t> {
689 return numeric_limits<size_t>::min();
693 return numeric_limits<size_t>::max();
697 return numeric_limits<size_t>::lowest();
701 return numeric_limits<size_t>::epsilon();
705 return numeric_limits<size_t>::round_error();
709 return numeric_limits<size_t>::denorm_min();
713 return numeric_limits<size_t>::infinity();
717 return numeric_limits<size_t>::quiet_NaN();
721 return numeric_limits<size_t>::signaling_NaN();
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);
817 #ifdef MSE_SELF_TESTS
828 CBool b1 = (i1 < i2);
842 CInt i11 = 19 + szt1;
846 #ifndef MSVC2010_COMPATIBLE
847 size_t szt5 = size_t(szt4);
849 bool b3 = (szt1 < szt2);
852 CBool b2 = (19 < szt1);
856 CBool b4 = (b1 < b2);
CBool & operator=(const CBool &x)
CBool & operator|=(const CBool &x)
CBool & operator^=(const CBool &x)
void note_value_assignment()
CBool & operator&=(const CBool &x)
void assert_initialized() const
CInt & operator=(size_t x)
CInt & operator<<=(const CInt &x)
CInt operator+(const CInt &x) const
CInt & operator%=(const CInt &x)
CInt & operator=(short x)
CInt & operator|=(const CInt &x)
CInt & operator^=(const CInt &x)
CInt & operator*=(const CInt &x)
bool operator!=(const CInt &x) const
CInt operator*(const CInt &x) const
CInt & operator>>=(const CInt &x)
bool operator<(const CInt &x) const
bool operator<=(const CInt &x) const
CInt & operator=(const CInt &x)
bool operator==(const CInt &x) const
bool operator>(const CInt &x) const
bool operator>=(const CInt &x) const
CInt operator/(const CInt &x) const
CInt & operator=(long long x)
CInt & operator&=(const CInt &x)
CInt & operator-=(const CInt &x)
CInt & operator/=(const CInt &x)
CInt & operator+=(const CInt &x)
CSize_t operator/(const CSize_t &x) const
CSize_t & operator|=(const CSize_t &x)
CSize_t & operator%=(const CSize_t &x)
CSize_t & operator=(char x)
CSize_t & operator+=(const CSize_t &x)
CSize_t & operator=(short x)
bool operator<=(const CSize_t &x) const
CSize_t & operator<<=(const CSize_t &x)
CSize_t & operator=(const CSize_t &x)
CSize_t & operator=(int x)
CSize_t operator+(const CSize_t &x) const
CSize_t & operator=(size_t x)
bool operator==(const CSize_t &x) const
bool operator!=(const CSize_t &x) const
bool operator>(const CSize_t &x) const
CSize_t operator*(const CSize_t &x) const
CSize_t & operator=(long x)
CSize_t(const CSize_t &x)
CSize_t & operator=(long long x)
CSize_t & operator>>=(const CSize_t &x)
int _T_signed_primitive_integer_type
CSize_t & operator^=(const CSize_t &x)
friend size_t as_a_size_t(CSize_t n)
CSize_t & operator&=(const CSize_t &x)
bool operator<(const CSize_t &x) const
CSize_t & operator*=(const CSize_t &x)
CSize_t & operator/=(const CSize_t &x)
CSize_t operator~() const
CSize_t & operator-=(const CSize_t &x)
bool operator>=(const CSize_t &x) const
CSize_t & operator=(CInt x)
void assert_initialized() const
TIntBase1(const TIntBase1 &x)
void assign_check_range(const _Tz &x)
void note_value_assignment()
static constexpr _Ty round_error()
static constexpr _Ty lowest()
static constexpr _Ty signaling_NaN()
static constexpr _Ty denorm_min()
static constexpr _Ty epsilon()
static constexpr _Ty quiet_NaN()
static constexpr _Ty infinity()
static constexpr _Ty infinity()
static constexpr _Ty lowest()
static constexpr _Ty signaling_NaN()
static constexpr _Ty epsilon()
static constexpr _Ty round_error()
static constexpr _Ty denorm_min()
static constexpr _Ty quiet_NaN()
#define MSE_CINT_BASE_INTEGER_TYPE
#define _STCONS(ty, name, val)
static size_t as_a_size_t(CSize_t n)
void g_assign_check_range(const _TSource &x)
bool operator!=(size_t lhs, const CInt &rhs)
bool operator<=(size_t lhs, const CInt &rhs)
constexpr static bool sg_can_exceed_upper_bound()
constexpr static bool sg_can_exceed_lower_bound()
bool operator>=(size_t lhs, const CInt &rhs)
CInt operator-(size_t lhs, const CInt &rhs)
bool operator==(size_t lhs, const CInt &rhs)
static void s_type_test1()
bool operator<(size_t lhs, const CInt &rhs)
bool operator>(size_t lhs, const CInt &rhs)
CInt operator*(size_t lhs, const CInt &rhs)
CInt operator+(size_t lhs, const CInt &rhs)
CInt operator/(size_t lhs, const CInt &rhs)