diff --git a/type.hpp b/type.hpp new file mode 100644 index 0000000..4e76b2f --- /dev/null +++ b/type.hpp @@ -0,0 +1,141 @@ +#pragma once + +// Fix for limits.h not exposing LLONG_MIN, LLONG_MIN, and ULLONG_MAX to C++ context +#ifdef __cplusplus +#define __STDC_VERSION__ 201112L +#endif + +#include +#include + +namespace type { + +// clang-format off +template struct set_bool { static constexpr auto value = Val; }; + +struct true_type : set_bool {}; +struct false_type : set_bool {}; + +template struct always_false : false_type {}; + +template static constexpr auto always_false_v = always_false::value; + +template struct is_integral : false_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; + +template static constexpr auto is_integral_v = is_integral::value; + +template struct is_same : false_type {}; +template struct is_same : true_type {}; + +template static constexpr auto is_same_v = is_same::value; + +template +struct NumericLimits { + static constexpr T min() { return T(); } + static constexpr T max() { return T(); } +}; + +template <> +struct NumericLimits { + static constexpr bool min() { return false; } + static constexpr bool max() { return true; } +}; + +template <> +struct NumericLimits { + static constexpr char min() { return CHAR_MIN; } + static constexpr char max() { return CHAR_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr signed char min() { return SCHAR_MIN; } + static constexpr signed char max() { return SCHAR_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr unsigned char min() { return 0; } + static constexpr unsigned char max() { return UCHAR_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr short min() { return SHRT_MIN; } + static constexpr short max() { return SHRT_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr int min() { return INT_MIN; } + static constexpr int max() { return INT_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr long int min() { return LONG_MIN; } + static constexpr long int max() { return LONG_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr long long int min() { return LLONG_MIN; } + static constexpr long long int max() { return LLONG_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr unsigned short min() { return 0; } + static constexpr unsigned short max() { return USHRT_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr unsigned int min() { return 0; } + static constexpr unsigned int max() { return UINT_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr unsigned long int min() { return 0; } + static constexpr unsigned long int max() { return ULONG_MAX; } +}; + +template <> +struct NumericLimits { + static constexpr unsigned long long int min() { return 0; } + static constexpr unsigned long long int max() { return ULLONG_MAX; } +}; + +template <> +struct NumericLimits { + template static constexpr float min() { return FLT_MIN; } + template static constexpr float max() { return FLT_MAX; } +}; + +template <> +struct NumericLimits { + template static constexpr double min() { return DBL_MIN; } + template static constexpr double max() { return DBL_MAX; } +}; + +template <> +struct NumericLimits { + template static constexpr long double min() { return LDBL_MIN; } + template static constexpr long double max() { return LDBL_MAX; } +}; +// clang-format on + +} // namespace type