/*============================================================================= Copyright (c) 2011-2014 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 #include #ifdef SPROUT_NO_CXX11_NUMERIC_LIMITS # include # include # include # if !defined(__FLT_DENORM_MIN__) || !defined(__LDBL_DENORM_MIN__) || !defined(__LDBL_DENORM_MIN__) # include # 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 class numeric_limits_base { private: typedef std::numeric_limits 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 class numeric_limits_impl; template class numeric_limits_impl : public sprout::detail::numeric_limits_base { private: typedef std::numeric_limits 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 class numeric_limits_impl : public sprout::detail::numeric_limits_base { 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 class numeric_limits : public sprout::detail::numeric_limits_impl::is_specialized> {}; template class numeric_limits : public sprout::numeric_limits {}; template class numeric_limits : public sprout::numeric_limits {}; template class numeric_limits : public sprout::numeric_limits {}; #define SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(TYPE, MIN, MAX) \ template<> \ class numeric_limits \ : public sprout::detail::numeric_limits_base \ { \ 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(0); \ } \ static SPROUT_CONSTEXPR TYPE round_error() SPROUT_NOEXCEPT { \ return static_cast(0); \ } \ \ static SPROUT_CONSTEXPR TYPE infinity() SPROUT_NOEXCEPT { \ return static_cast(0); \ } \ static SPROUT_CONSTEXPR TYPE quiet_NaN() SPROUT_NOEXCEPT { \ return static_cast(0); \ } \ static SPROUT_CONSTEXPR TYPE signaling_NaN() SPROUT_NOEXCEPT { \ return static_cast(0); \ } \ static SPROUT_CONSTEXPR TYPE denorm_min() SPROUT_NOEXCEPT { \ return static_cast(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(0), USHRT_MAX); SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(unsigned int, static_cast(0), UINT_MAX); SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(unsigned long, static_cast(0), ULONG_MAX); SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL(unsigned long long, static_cast(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(0), UCHAR_MAX); SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL( char16_t, static_cast(sprout::numeric_limits::min()), static_cast(sprout::numeric_limits::max()) ); SPROUT_NUMERIC_LIMITS_INTEGRAL_SPECIALIZED_DECL( char32_t, static_cast(sprout::numeric_limits::min()), static_cast(sprout::numeric_limits::max()) ); 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 \ : public sprout::detail::numeric_limits_base \ { \ 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_val(), __builtin_nan(""), __builtin_nans(""), __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 using numeric_limits = std::numeric_limits; #else // #if SPROUT_USE_TEMPLATE_ALIASES template class numeric_limits : public std::numeric_limits {}; #endif // #if SPROUT_USE_TEMPLATE_ALIASES #endif // #ifdef SPROUT_NO_CXX11_NUMERIC_LIMITS } // namespace sprout #endif // #ifndef SPROUT_LIMITS_HPP