#pragma once #include #include #if defined(FIXED_POINTS_USE_NAMESPACE) #define FIXED_POINTS_NAMESPACE FixedPoints #define FIXED_POINTS_BEGIN_NAMESPACE namespace FIXED_POINTS_NAMESPACE\ { #define FIXED_POINTS_END_NAMESPACE } #define FIXED_POINTS_DETAILS Details #else #define FIXED_POINTS_NAMESPACE #define FIXED_POINTS_BEGIN_NAMESPACE #define FIXED_POINTS_END_NAMESPACE #define FIXED_POINTS_DETAILS FixedPointsDetails #endif // Pay no attention to the man behind the curtains FIXED_POINTS_BEGIN_NAMESPACE namespace FIXED_POINTS_DETAILS { template< typename T > struct BitSize { BitSize(void) = delete; constexpr static const auto Value = sizeof(T) * CHAR_BIT; }; template< typename T, typename U = T > constexpr auto Max(const T & left, const U & right) noexcept -> decltype((left > right) ? left : right) { return (left > right) ? left : right; } template< typename T, T Left, T Right > constexpr auto Max(void) noexcept -> decltype((Left > Right) ? Left : Right) { return (Left > Right) ? Left : Right; } template< typename T, typename U = T > constexpr auto Min(const T & left, const U & right) noexcept -> decltype((left < right) ? left : right) { return (left < right) ? left : right; } template< typename T, T Left, T Right > constexpr auto Min(void) noexcept -> decltype((Left < Right) ? Left : Right) { return (Left < Right) ? Left : Right; } template< bool Condition, typename TTrue, typename TFalse > struct Conditional; template< typename TTrue, typename TFalse > struct Conditional< true, TTrue, TFalse > { using Type = TTrue; }; template< typename TTrue, typename TFalse > struct Conditional< false, TTrue, TFalse > { using Type = TFalse; }; template< bool Condition, typename TTrue, typename TFalse > using ConditionalT = typename Conditional::Type; template< typename T, typename U > using LargerType = ConditionalT<(BitSize::Value > BitSize::Value), T, U>; template< typename T, typename U > using StrictLargerType = ConditionalT< (BitSize::Value > BitSize::Value), T, ConditionalT< (BitSize::Value > BitSize::Value), U, void > >; template< typename T, typename U > using SmallerType = ConditionalT<(BitSize::Value < BitSize::Value), T, U>; template< typename T, typename U > using StrictSmallerType = ConditionalT< (BitSize::Value < BitSize::Value), T, ConditionalT< (BitSize::Value < BitSize::Value), U, void > >; template< unsigned Bits, typename... Ts > struct LeastTypeHelper; template< unsigned Bits, typename T, typename... Ts > struct LeastTypeHelper { LeastTypeHelper(void) = delete; using Type = ConditionalT<(Bits <= BitSize::Value), T, typename LeastTypeHelper::Type>; }; template< unsigned Bits > struct LeastTypeHelper { LeastTypeHelper(void) = delete; using Type = void; }; template< unsigned Bits, typename... Ts > using LeastType = typename LeastTypeHelper::Type; template< unsigned Bits > struct LeastUIntDef { static_assert(Bits <= BitSize::Value, "No type large enough"); LeastUIntDef(void) = delete; using Type = LeastType; }; template< unsigned Bits > using LeastUInt = typename LeastUIntDef::Type; template< unsigned Bits > struct LeastIntDef { static_assert(Bits <= BitSize::Value, "No type large enough"); LeastIntDef(void) = delete; using Type = LeastType; }; template< unsigned Bits > using LeastInt = typename LeastIntDef::Type; template< unsigned Bits > struct MsbMask { MsbMask(void) = delete; constexpr const static LeastUInt Value = (1ull << (Bits - 1)); }; template< unsigned Bits > struct IdentityMask { IdentityMask(void) = delete; constexpr const static LeastUInt Value = 1 | (IdentityMask::Value << 1); }; template<> struct IdentityMask<0> { IdentityMask(void) = delete; constexpr const static LeastUInt<0> Value = 0; }; using IntegerLiteral = decltype(0); using IntegerLiteralU = decltype(0U); using IntegerLiteralL = decltype(0L); using IntegerLiteralUL = decltype(0UL); using IntegerLiteralLL = decltype(0LL); using IntegerLiteralULL = decltype(0ULL); using DecimalLiteral = decltype(0.0); using DecimalLiteralF = decltype(0.0F); using DecimalLiteralL = decltype(0.0L); template< typename T > struct RandomHelper; template<> struct RandomHelper { static inline uint8_t Random() { return static_cast(random()); } }; template<> struct RandomHelper { static inline uint16_t Random() { return static_cast(random()); } }; template<> struct RandomHelper { static inline uint32_t Random() { return static_cast(random()); } }; template<> struct RandomHelper { static inline uint64_t Random() { return (static_cast(random()) << 32) | static_cast(random()); } }; template<> struct RandomHelper { static inline int8_t Random() { return static_cast(random()); } }; template<> struct RandomHelper { static inline int16_t Random() { return static_cast(random()); } }; template<> struct RandomHelper { static inline int32_t Random() { return static_cast(random()); } }; template<> struct RandomHelper { static inline int64_t Random() { return (static_cast(random()) << 32) | static_cast(random()); } }; // Here be dragons!! // // // // /\___/\ ~ // ( O . O ) \\ // > ^ < // // ( \ / )// // u U U u // // Or cats? // ~Mwrow~ } FIXED_POINTS_END_NAMESPACE