add initial numeric limits implementation (type-generic min/max/etc)

master
Daniel Kolesa 2016-11-15 22:46:03 +01:00
parent fc52acc79d
commit e7c6032edb
2 changed files with 107 additions and 3 deletions

103
ostd/limits.hh 100644
View File

@ -0,0 +1,103 @@
/* 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>
static constexpr T NumericLimitMin = detail::NumericLimitsBase<T>::minv;
template<typename T>
static constexpr T NumericLimitMax = detail::NumericLimitsBase<T>::maxv;
template<typename T>
static constexpr T NumericLimitLowest = detail::NumericLimitsBase<T>::lowv;
template<typename T>
static constexpr bool NumericLimitIsSigned = detail::NumericLimitsBase<T>::is_signed;
template<typename T>
static constexpr bool NumericLimitIsInteger = detail::NumericLimitsBase<T>::is_integer;
}
#endif

View File

@ -889,14 +889,15 @@ struct ToString<T> { \
} \
};
OSTD_TOSTR_NUM(sbyte, "%d")
OSTD_TOSTR_NUM(sbyte, "%hhd")
OSTD_TOSTR_NUM(short, "%hd")
OSTD_TOSTR_NUM(int, "%d")
OSTD_TOSTR_NUM(int &, "%d")
OSTD_TOSTR_NUM(long, "%ld")
OSTD_TOSTR_NUM(float, "%f")
OSTD_TOSTR_NUM(double, "%f")
OSTD_TOSTR_NUM(byte, "%u")
OSTD_TOSTR_NUM(byte, "%hhu")
OSTD_TOSTR_NUM(ushort, "%hu")
OSTD_TOSTR_NUM(uint, "%u")
OSTD_TOSTR_NUM(ulong, "%lu")
OSTD_TOSTR_NUM(llong, "%lld")