// Copyright 2017-2021 Pharap // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #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 #if !defined(__AVR__) #define FIXED_POINTS_NO_RANDOM #endif // Pay no attention to the man behind the curtains FIXED_POINTS_BEGIN_NAMESPACE namespace FIXED_POINTS_DETAILS { template< typename T > struct BitSize { BitSize() = delete; static constexpr auto Value = sizeof(T) * CHAR_BIT; }; 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() = delete; using Type = ConditionalT<(Bits <= BitSize::Value), T, typename LeastTypeHelper::Type>; }; template< unsigned Bits > struct LeastTypeHelper { LeastTypeHelper() = 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() = 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() = delete; using Type = LeastType; }; template< unsigned Bits > using LeastInt = typename LeastIntDef::Type; template< unsigned Bits > struct MsbMask { MsbMask() = delete; static constexpr LeastUInt Value = (1ull << (Bits - 1)); }; template< unsigned Bits > struct IdentityMask { IdentityMask() = delete; static constexpr LeastUInt Value = 1 | (static_cast>(IdentityMask::Value) << 1); }; template<> struct IdentityMask<0> { IdentityMask() = delete; static constexpr LeastUInt<0> Value = 0; }; #if !defined(FIXED_POINTS_NO_RANDOM) 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()); } }; #endif /////////////////////// // Here be dragons!! // // // // /\___/\ _ // // ( O . O ) \\ // // > ^ < // // // ( \ / )// // // u U U u // // // // Or cats?... // // ~Mwrow~ // /////////////////////// } FIXED_POINTS_END_NAMESPACE