mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-11-29 01:03:45 +00:00
318 lines
11 KiB
C++
318 lines
11 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2011-2017 Bolero MURAKAMI
|
|
https://github.com/bolero-MURAKAMI/Sprout
|
|
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
=============================================================================*/
|
|
#ifndef SPROUT_LIMITS_HPP
|
|
#define SPROUT_LIMITS_HPP
|
|
|
|
#include <limits>
|
|
#include <sprout/config.hpp>
|
|
#ifdef SPROUT_NO_CXX11_NUMERIC_LIMITS
|
|
# include <cstdint>
|
|
# include <climits>
|
|
# include <cfloat>
|
|
# if !defined(__FLT_DENORM_MIN__) || !defined(__LDBL_DENORM_MIN__) || !defined(__LDBL_DENORM_MIN__)
|
|
# include <cmath>
|
|
# endif // #if !defined(__FLT_DENORM_MIN__) || !defined(__LDBL_DENORM_MIN__) || !defined(__LDBL_DENORM_MIN__)
|
|
#endif // #ifdef SPROUT_NO_CXX11_NUMERIC_LIMITS
|
|
|
|
namespace sprout {
|
|
//
|
|
// numeric_limits
|
|
//
|
|
#ifdef SPROUT_NO_CXX11_NUMERIC_LIMITS
|
|
namespace detail {
|
|
template<typename T>
|
|
class numeric_limits_base {
|
|
private:
|
|
typedef std::numeric_limits<T> impl_type;
|
|
public:
|
|
SPROUT_STATIC_CONSTEXPR bool is_specialized = impl_type::is_specialized;
|
|
|
|
SPROUT_STATIC_CONSTEXPR int digits = impl_type::digits;
|
|
SPROUT_STATIC_CONSTEXPR int digits10 = impl_type::digits10;
|
|
SPROUT_STATIC_CONSTEXPR int max_digits10 = impl_type::max_digits10;
|
|
SPROUT_STATIC_CONSTEXPR bool is_signed = impl_type::is_signed;
|
|
SPROUT_STATIC_CONSTEXPR bool is_integer = impl_type::is_integer;
|
|
SPROUT_STATIC_CONSTEXPR bool is_exact = impl_type::is_exact;
|
|
SPROUT_STATIC_CONSTEXPR int radix = impl_type::radix;
|
|
|
|
SPROUT_STATIC_CONSTEXPR int min_exponent = impl_type::min_exponent;
|
|
SPROUT_STATIC_CONSTEXPR int min_exponent10 = impl_type::min_exponent10;
|
|
SPROUT_STATIC_CONSTEXPR int max_exponent = impl_type::max_exponent;
|
|
SPROUT_STATIC_CONSTEXPR int max_exponent10 = impl_type::max_exponent10;
|
|
SPROUT_STATIC_CONSTEXPR bool has_infinity = impl_type::has_infinity;
|
|
SPROUT_STATIC_CONSTEXPR bool has_quiet_NaN = impl_type::has_quiet_NaN;
|
|
SPROUT_STATIC_CONSTEXPR bool has_signaling_NaN = impl_type::has_signaling_NaN;
|
|
SPROUT_STATIC_CONSTEXPR std::float_denorm_style has_denorm = impl_type::has_denorm;
|
|
SPROUT_STATIC_CONSTEXPR bool has_denorm_loss = impl_type::has_denorm_loss;
|
|
|
|
SPROUT_STATIC_CONSTEXPR bool is_iec559 = impl_type::is_iec559;
|
|
SPROUT_STATIC_CONSTEXPR bool is_bounded = impl_type::is_bounded;
|
|
SPROUT_STATIC_CONSTEXPR bool is_modulo = impl_type::is_modulo;
|
|
SPROUT_STATIC_CONSTEXPR bool traps = impl_type::traps;
|
|
SPROUT_STATIC_CONSTEXPR bool tinyness_before = impl_type::tinyness_before;
|
|
SPROUT_STATIC_CONSTEXPR std::float_round_style round_style = impl_type::round_style;
|
|
};
|
|
|
|
template<typename T, bool IsInitialized>
|
|
class numeric_limits_impl;
|
|
template<typename T>
|
|
class numeric_limits_impl<T, true>
|
|
: public sprout::detail::numeric_limits_base<T>
|
|
{
|
|
private:
|
|
typedef std::numeric_limits<T> impl_type;
|
|
public:
|
|
static SPROUT_CONSTEXPR T min() SPROUT_NOEXCEPT {
|
|
return impl_type::min();
|
|
}
|
|
static SPROUT_CONSTEXPR T max() SPROUT_NOEXCEPT {
|
|
return impl_type::max();
|
|
}
|
|
static SPROUT_CONSTEXPR T lowest() SPROUT_NOEXCEPT {
|
|
return impl_type::lowest();
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR T epsilon() SPROUT_NOEXCEPT {
|
|
return impl_type::epsilon();
|
|
}
|
|
static SPROUT_CONSTEXPR T round_error() SPROUT_NOEXCEPT {
|
|
return impl_type::round_error();
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR T infinity() SPROUT_NOEXCEPT {
|
|
return impl_type::infinity();
|
|
}
|
|
static SPROUT_CONSTEXPR T quiet_NaN() SPROUT_NOEXCEPT {
|
|
return impl_type::quiet_NaN();
|
|
}
|
|
static SPROUT_CONSTEXPR T signaling_NaN() SPROUT_NOEXCEPT {
|
|
return impl_type::signaling_NaN();
|
|
}
|
|
static SPROUT_CONSTEXPR T denorm_min() SPROUT_NOEXCEPT {
|
|
return impl_type::denorm_min();
|
|
}
|
|
};
|
|
template<typename T>
|
|
class numeric_limits_impl<T, false>
|
|
: public sprout::detail::numeric_limits_base<T>
|
|
{
|
|
public:
|
|
static SPROUT_CONSTEXPR T min() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
static SPROUT_CONSTEXPR T max() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
static SPROUT_CONSTEXPR T lowest() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR T epsilon() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
static SPROUT_CONSTEXPR T round_error() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR T infinity() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
static SPROUT_CONSTEXPR T quiet_NaN() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
static SPROUT_CONSTEXPR T signaling_NaN() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
static SPROUT_CONSTEXPR T denorm_min() SPROUT_NOEXCEPT {
|
|
return T();
|
|
}
|
|
};
|
|
} // namespace detail
|
|
|
|
template<typename T>
|
|
class numeric_limits
|
|
: public sprout::detail::numeric_limits_impl<T, std::numeric_limits<T>::is_specialized>
|
|
{};
|
|
template<typename T>
|
|
class numeric_limits<T const>
|
|
: public sprout::numeric_limits<T>
|
|
{};
|
|
template<typename T>
|
|
class numeric_limits<T volatile>
|
|
: public sprout::numeric_limits<T>
|
|
{};
|
|
template<typename T>
|
|
class numeric_limits<T const volatile>
|
|
: public sprout::numeric_limits<T>
|
|
{};
|
|
|
|
#define SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(TYPE, MIN, MAX) \
|
|
template<> \
|
|
class numeric_limits<TYPE> \
|
|
: public sprout::detail::numeric_limits_base<TYPE> \
|
|
{ \
|
|
public: \
|
|
static SPROUT_CONSTEXPR TYPE min() SPROUT_NOEXCEPT { \
|
|
return MIN; \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE max() SPROUT_NOEXCEPT { \
|
|
return MAX; \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE lowest() SPROUT_NOEXCEPT { \
|
|
return min(); \
|
|
} \
|
|
\
|
|
static SPROUT_CONSTEXPR TYPE epsilon() SPROUT_NOEXCEPT { \
|
|
return static_cast<TYPE>(0); \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE round_error() SPROUT_NOEXCEPT { \
|
|
return static_cast<TYPE>(0); \
|
|
} \
|
|
\
|
|
static SPROUT_CONSTEXPR TYPE infinity() SPROUT_NOEXCEPT { \
|
|
return static_cast<TYPE>(0); \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE quiet_NaN() SPROUT_NOEXCEPT { \
|
|
return static_cast<TYPE>(0); \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE signaling_NaN() SPROUT_NOEXCEPT { \
|
|
return static_cast<TYPE>(0); \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE denorm_min() SPROUT_NOEXCEPT { \
|
|
return static_cast<TYPE>(0); \
|
|
} \
|
|
}
|
|
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(bool, false, true);
|
|
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(short, SHRT_MIN, SHRT_MAX);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(int, INT_MIN, INT_MAX);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(long, LONG_MIN, LONG_MAX);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(long long, LLONG_MIN, LLONG_MAX);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(unsigned short, static_cast<unsigned short>(0), USHRT_MAX);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(unsigned int, static_cast<unsigned int>(0), UINT_MAX);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(unsigned long, static_cast<unsigned long>(0), ULONG_MAX);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(unsigned long long, static_cast<unsigned long long>(0), ULLONG_MAX);
|
|
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(signed char, SCHAR_MIN, SCHAR_MAX);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(unsigned char, static_cast<unsigned char>(0), UCHAR_MAX);
|
|
#if SPROUT_USE_UNICODE_LITERALS
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(
|
|
char16_t,
|
|
static_cast<char16_t>(sprout::numeric_limits<std::uint_least16_t>::min()),
|
|
static_cast<char16_t>(sprout::numeric_limits<std::uint_least16_t>::max())
|
|
);
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(
|
|
char32_t,
|
|
static_cast<char16_t>(sprout::numeric_limits<std::uint_least32_t>::min()),
|
|
static_cast<char16_t>(sprout::numeric_limits<std::uint_least32_t>::max())
|
|
);
|
|
#endif
|
|
SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(wchar_t, WCHAR_MIN, WCHAR_MAX);
|
|
#undef SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL
|
|
|
|
#define SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(TYPE, MIN, MAX, EPS, RND, INF, QNAN, SNAN, DMIN) \
|
|
template<> \
|
|
class numeric_limits<TYPE> \
|
|
: public sprout::detail::numeric_limits_base<TYPE> \
|
|
{ \
|
|
public: \
|
|
static SPROUT_CONSTEXPR TYPE min() SPROUT_NOEXCEPT { \
|
|
return MIN; \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE max() SPROUT_NOEXCEPT { \
|
|
return MAX; \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE lowest() SPROUT_NOEXCEPT { \
|
|
return -max(); \
|
|
} \
|
|
\
|
|
static SPROUT_CONSTEXPR TYPE epsilon() SPROUT_NOEXCEPT { \
|
|
return EPS; \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE round_error() SPROUT_NOEXCEPT { \
|
|
return RND; \
|
|
} \
|
|
\
|
|
static SPROUT_CONSTEXPR TYPE infinity() SPROUT_NOEXCEPT { \
|
|
return INF; \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE quiet_NaN() SPROUT_NOEXCEPT { \
|
|
return QNAN; \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE signaling_NaN() SPROUT_NOEXCEPT { \
|
|
return SNAN; \
|
|
} \
|
|
static SPROUT_CONSTEXPR TYPE denorm_min() SPROUT_NOEXCEPT { \
|
|
return DMIN; \
|
|
} \
|
|
}
|
|
|
|
#if !defined(__FLT_DENORM_MIN__)
|
|
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
|
|
float,
|
|
FLT_MIN, FLT_MAX,
|
|
FLT_EPSILON, 0.5F,
|
|
INFINITY, NAN, NAN, FLT_MIN
|
|
);
|
|
#else // #if !defined(__FLT_DENORM_MIN__)
|
|
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
|
|
float,
|
|
FLT_MIN, FLT_MAX,
|
|
FLT_EPSILON, 0.5F,
|
|
__builtin_huge_valf(), __builtin_nanf(""), __builtin_nansf(""), __FLT_DENORM_MIN__
|
|
);
|
|
#endif // #if !defined(__FLT_DENORM_MIN__)
|
|
#if !defined(__DBL_DENORM_MIN__)
|
|
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
|
|
double,
|
|
DBL_MIN, DBL_MAX,
|
|
DBL_EPSILON, 0.5,
|
|
INFINITY, NAN, NAN, DBL_MIN
|
|
);
|
|
#else // #if !defined(__DBL_DENORM_MIN__)
|
|
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
|
|
double,
|
|
DBL_MIN, DBL_MAX,
|
|
DBL_EPSILON, 0.5,
|
|
__builtin_huge_val(), __builtin_nan(""), __builtin_nans(""), __DBL_DENORM_MIN__
|
|
);
|
|
#endif // #if !defined(__DBL_DENORM_MIN__)
|
|
#if !defined(__LDBL_DENORM_MIN__)
|
|
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
|
|
long double,
|
|
LDBL_MIN, LDBL_MAX,
|
|
LDBL_EPSILON, 0.5L,
|
|
INFINITY, NAN, NAN, LDBL_MIN
|
|
);
|
|
#else // #if !defined(__LDBL_DENORM_MIN__)
|
|
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
|
|
long double,
|
|
LDBL_MIN, LDBL_MAX,
|
|
LDBL_EPSILON, 0.5L,
|
|
__builtin_huge_vall(), __builtin_nanl(""), __builtin_nansl(""), __LDBL_DENORM_MIN__
|
|
);
|
|
#endif // #if !defined(__LDBL_DENORM_MIN__)
|
|
#undef SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL
|
|
|
|
#else // #ifdef SPROUT_NO_CXX11_NUMERIC_LIMITS
|
|
|
|
#if SPROUT_USE_TEMPLATE_ALIASES
|
|
template<typename T>
|
|
using numeric_limits = std::numeric_limits<T>;
|
|
#else // #if SPROUT_USE_TEMPLATE_ALIASES
|
|
template<typename T>
|
|
class numeric_limits
|
|
: public std::numeric_limits<T>
|
|
{};
|
|
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
|
|
|
|
#endif // #ifdef SPROUT_NO_CXX11_NUMERIC_LIMITS
|
|
} // namespace sprout
|
|
|
|
#endif // #ifndef SPROUT_LIMITS_HPP
|