You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
6.1 KiB
220 lines
6.1 KiB
#pragma once
|
|
|
|
#include <Arduino.h>
|
|
#include <limits.h>
|
|
#include <stdint.h>
|
|
|
|
#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<Condition, TTrue, TFalse >::Type;
|
|
|
|
template< typename T, typename U >
|
|
using LargerType = ConditionalT<(BitSize<T>::Value > BitSize<U>::Value), T, U>;
|
|
|
|
template< typename T, typename U >
|
|
using StrictLargerType = ConditionalT< (BitSize<T>::Value > BitSize<U>::Value), T, ConditionalT< (BitSize<U>::Value > BitSize<T>::Value), U, void > >;
|
|
|
|
template< typename T, typename U >
|
|
using SmallerType = ConditionalT<(BitSize<T>::Value < BitSize<U>::Value), T, U>;
|
|
|
|
template< typename T, typename U >
|
|
using StrictSmallerType = ConditionalT< (BitSize<T>::Value < BitSize<U>::Value), T, ConditionalT< (BitSize<U>::Value < BitSize<T>::Value), U, void > >;
|
|
|
|
template< unsigned Bits, typename... Ts >
|
|
struct LeastTypeHelper;
|
|
|
|
template< unsigned Bits, typename T, typename... Ts >
|
|
struct LeastTypeHelper<Bits, T, Ts... >
|
|
{
|
|
LeastTypeHelper(void) = delete;
|
|
using Type = ConditionalT<(Bits <= BitSize<T>::Value), T, typename LeastTypeHelper<Bits, Ts...>::Type>;
|
|
};
|
|
|
|
template< unsigned Bits >
|
|
struct LeastTypeHelper<Bits>
|
|
{
|
|
LeastTypeHelper(void) = delete;
|
|
using Type = void;
|
|
};
|
|
|
|
|
|
template< unsigned Bits, typename... Ts >
|
|
using LeastType = typename LeastTypeHelper<Bits, Ts...>::Type;
|
|
|
|
template< unsigned Bits >
|
|
struct LeastUIntDef
|
|
{
|
|
static_assert(Bits <= BitSize<uintmax_t>::Value, "No type large enough");
|
|
LeastUIntDef(void) = delete;
|
|
using Type = LeastType<Bits, uint_least8_t, uint_least16_t, uint_least32_t, uint_least64_t, uintmax_t>;
|
|
};
|
|
|
|
|
|
template< unsigned Bits >
|
|
using LeastUInt = typename LeastUIntDef<Bits>::Type;
|
|
|
|
template< unsigned Bits >
|
|
struct LeastIntDef
|
|
{
|
|
static_assert(Bits <= BitSize<intmax_t>::Value, "No type large enough");
|
|
LeastIntDef(void) = delete;
|
|
using Type = LeastType<Bits, int_least8_t, int_least16_t, int_least32_t, int_least64_t, intmax_t>;
|
|
};
|
|
|
|
template< unsigned Bits >
|
|
using LeastInt = typename LeastIntDef<Bits>::Type;
|
|
|
|
template< unsigned Bits >
|
|
struct MsbMask
|
|
{
|
|
MsbMask(void) = delete;
|
|
constexpr const static LeastUInt<Bits> Value = (1ull << (Bits - 1));
|
|
};
|
|
|
|
template< unsigned Bits >
|
|
struct IdentityMask
|
|
{
|
|
IdentityMask(void) = delete;
|
|
constexpr const static LeastUInt<Bits> Value = 1 | (IdentityMask<Bits - 1>::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<uint8_t>
|
|
{
|
|
static inline uint8_t Random() { return static_cast<uint8_t>(random()); }
|
|
};
|
|
|
|
template<>
|
|
struct RandomHelper<uint16_t>
|
|
{
|
|
static inline uint16_t Random() { return static_cast<uint16_t>(random()); }
|
|
};
|
|
|
|
template<>
|
|
struct RandomHelper<uint32_t>
|
|
{
|
|
static inline uint32_t Random() { return static_cast<uint32_t>(random()); }
|
|
};
|
|
|
|
template<>
|
|
struct RandomHelper<uint64_t>
|
|
{
|
|
static inline uint64_t Random() { return (static_cast<uint64_t>(random()) << 32) | static_cast<uint64_t>(random()); }
|
|
};
|
|
|
|
template<>
|
|
struct RandomHelper<int8_t>
|
|
{
|
|
static inline int8_t Random() { return static_cast<int8_t>(random()); }
|
|
};
|
|
|
|
template<>
|
|
struct RandomHelper<int16_t>
|
|
{
|
|
static inline int16_t Random() { return static_cast<int16_t>(random()); }
|
|
};
|
|
|
|
template<>
|
|
struct RandomHelper<int32_t>
|
|
{
|
|
static inline int32_t Random() { return static_cast<int32_t>(random()); }
|
|
};
|
|
|
|
template<>
|
|
struct RandomHelper<int64_t>
|
|
{
|
|
static inline int64_t Random() { return (static_cast<int64_t>(random()) << 32) | static_cast<int64_t>(random()); }
|
|
};
|
|
|
|
///////////////////////
|
|
// Here be dragons!! //
|
|
// //
|
|
// /\___/\ _ //
|
|
// ( O . O ) \\ //
|
|
// > ^ < // //
|
|
// ( \ / )// //
|
|
// u U U u //
|
|
// //
|
|
// Or cats?... //
|
|
// ~Mwrow~ //
|
|
///////////////////////
|
|
}
|
|
FIXED_POINTS_END_NAMESPACE |