diff --git a/utils.hpp b/utils.hpp index c9df788..c931b80 100644 --- a/utils.hpp +++ b/utils.hpp @@ -1,5 +1,12 @@ #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 + namespace uart { namespace util { @@ -11,5 +18,103 @@ struct always_false { template static constexpr auto always_false_v = always_false::value; +// clang-format off +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() { static_assert(always_false_v, "Not implemented"); return 0; } + template static constexpr float max() { static_assert(always_false_v, "Not implemented"); return 0; } +}; + +template <> +struct NumericLimits { + template static constexpr double min() { static_assert(always_false_v, "Not implemented"); return 0; } + template static constexpr double max() { static_assert(always_false_v, "Not implemented"); return 0; } +}; + +template <> +struct NumericLimits { + template static constexpr long double min() { static_assert(always_false_v, "Not implemented"); return 0; } + template static constexpr long double max() { static_assert(always_false_v, "Not implemented"); return 0; } +}; +// clang-format on + } // namespace util } // namespace uart