Sprout/sprout/limits.hpp

317 lines
11 KiB
C++
Raw Normal View History

2013-08-08 09:54:33 +00:00
/*=============================================================================
2015-01-10 10:13:57 +00:00
Copyright (c) 2011-2015 Bolero MURAKAMI
2013-08-08 09:54:33 +00:00
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)
=============================================================================*/
2013-08-06 15:15:09 +00:00
#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
2013-08-06 15:15:09 +00:00
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:
2013-08-07 00:54:38 +00:00
SPROUT_STATIC_CONSTEXPR bool is_specialized = impl_type::is_specialized;
2013-08-06 15:15:09 +00:00
2013-08-07 00:54:38 +00:00
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;
2013-08-06 15:15:09 +00:00
2013-08-07 00:54:38 +00:00
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;
2013-08-06 15:15:09 +00:00
2013-08-07 00:54:38 +00:00
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;
2013-08-06 15:15:09 +00:00
};
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);
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())
);
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; \
} \
}
2014-05-29 16:22:00 +00:00
#if !defined(__FLT_DENORM_MIN__)
2013-08-06 15:15:09 +00:00
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
float,
FLT_MIN, FLT_MAX,
FLT_EPSILON, 0.5F,
INFINITY, NAN, NAN, FLT_MIN
2014-05-29 16:22:00 +00:00
);
#else // #if !defined(__FLT_DENORM_MIN__)
2014-05-29 16:22:00 +00:00
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
float,
FLT_MIN, FLT_MAX,
FLT_EPSILON, 0.5F,
2013-08-06 15:15:09 +00:00
__builtin_huge_valf(), __builtin_nanf(""), __builtin_nansf(""), __FLT_DENORM_MIN__
);
2014-05-29 16:22:00 +00:00
#endif // #if !defined(__FLT_DENORM_MIN__)
#if !defined(__DBL_DENORM_MIN__)
2013-08-06 15:15:09 +00:00
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
double,
DBL_MIN, DBL_MAX,
DBL_EPSILON, 0.5,
INFINITY, NAN, NAN, DBL_MIN
2014-05-29 16:22:00 +00:00
);
#else // #if !defined(__DBL_DENORM_MIN__)
2014-05-29 16:22:00 +00:00
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
double,
DBL_MIN, DBL_MAX,
DBL_EPSILON, 0.5,
2013-08-06 15:15:09 +00:00
__builtin_huge_val(), __builtin_nan(""), __builtin_nans(""), __DBL_DENORM_MIN__
);
2014-05-29 16:22:00 +00:00
#endif // #if !defined(__DBL_DENORM_MIN__)
#if !defined(__LDBL_DENORM_MIN__)
2013-08-06 15:15:09 +00:00
SPROUT_NUMERIC_LIMITS_FLOATING_POINT_SPECIALIZED_DECL(
long double,
LDBL_MIN, LDBL_MAX,
LDBL_EPSILON, 0.5L,
INFINITY, NAN, NAN, LDBL_MIN
2014-05-29 16:22:00 +00:00
);
#else // #if !defined(__LDBL_DENORM_MIN__)
2014-05-29 16:22:00 +00:00
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__
2013-08-06 15:15:09 +00:00
);
2014-05-29 16:22:00 +00:00
#endif // #if !defined(__LDBL_DENORM_MIN__)
2013-08-06 15:15:09 +00:00
#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