forked from OctaForge/libostd
104 lines
2.8 KiB
C++
104 lines
2.8 KiB
C++
/* Type limits for OctaSTD.
|
|
*
|
|
* This file is part of OctaSTD. See COPYING.md for futher information.
|
|
*/
|
|
|
|
#ifndef OSTD_LIMITS_HH
|
|
#define OSTD_LIMITS_HH
|
|
|
|
#include <limits.h>
|
|
#include <float.h>
|
|
|
|
#include "ostd/types.hh"
|
|
#include "ostd/type_traits.hh"
|
|
|
|
namespace ostd {
|
|
|
|
namespace detail {
|
|
template<typename T, bool I = IsIntegral<T>, bool F = IsFloatingPoint<T>>
|
|
struct NumericLimitsBase {
|
|
static constexpr T minv = T{};
|
|
static constexpr T maxv = T{};
|
|
static constexpr T lowv = T{};
|
|
static constexpr bool is_signed = false;
|
|
static constexpr bool is_integer = false;
|
|
};
|
|
|
|
/* signed integer types */
|
|
template<typename T, bool S = IsSigned<T>>
|
|
struct IntegerLimitsBase {
|
|
using UT = MakeUnsigned<T>;
|
|
static constexpr T minv = -(~(1ULL << (sizeof(T) * CHAR_BIT - 1))) - 1;
|
|
static constexpr T maxv = T(UT(~UT(0)) >> 1);
|
|
static constexpr T lowv = minv;
|
|
|
|
static constexpr bool is_signed = true;
|
|
static constexpr bool is_integer = true;
|
|
};
|
|
|
|
/* unsigned integer types */
|
|
template<typename T>
|
|
struct IntegerLimitsBase<T, false> {
|
|
static constexpr T minv = T(0);
|
|
static constexpr T maxv = ~T(0);
|
|
static constexpr T lowv = minv;
|
|
|
|
static constexpr bool is_signed = false;
|
|
static constexpr bool is_integer = true;
|
|
};
|
|
|
|
/* all integer types */
|
|
template<typename T>
|
|
struct NumericLimitsBase<T, true, false>: IntegerLimitsBase<T> {};
|
|
|
|
/* floating point types */
|
|
template<typename T>
|
|
struct FloatLimitsBase;
|
|
|
|
template<>
|
|
struct FloatLimitsBase<float> {
|
|
static constexpr float minv = FLT_MIN;
|
|
static constexpr float maxv = FLT_MAX;
|
|
static constexpr float lowv = -maxv;
|
|
};
|
|
|
|
template<>
|
|
struct FloatLimitsBase<double> {
|
|
static constexpr double minv = DBL_MIN;
|
|
static constexpr double maxv = DBL_MAX;
|
|
static constexpr double lowv = -maxv;
|
|
};
|
|
|
|
template<>
|
|
struct FloatLimitsBase<long double> {
|
|
static constexpr long double minv = LDBL_MIN;
|
|
static constexpr long double maxv = LDBL_MAX;
|
|
static constexpr long double lowv = -maxv;
|
|
};
|
|
|
|
template<typename T>
|
|
struct NumericLimitsBase<T, false, true>: FloatLimitsBase<T> {
|
|
static constexpr bool is_signed = true;
|
|
static constexpr bool is_integer = false;
|
|
};
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr T NumericLimitMin = detail::NumericLimitsBase<T>::minv;
|
|
|
|
template<typename T>
|
|
constexpr T NumericLimitMax = detail::NumericLimitsBase<T>::maxv;
|
|
|
|
template<typename T>
|
|
constexpr T NumericLimitLowest = detail::NumericLimitsBase<T>::lowv;
|
|
|
|
template<typename T>
|
|
constexpr bool NumericLimitIsSigned = detail::NumericLimitsBase<T>::is_signed;
|
|
|
|
template<typename T>
|
|
constexpr bool NumericLimitIsInteger = detail::NumericLimitsBase<T>::is_integer;
|
|
|
|
}
|
|
|
|
#endif
|