#pragma once namespace DD { /** Shortcut for simple referencing native arrays. */ template using ArrayNative = TYPE[N]; /************************************************************************/ /* TypeSizeCheck. */ /************************************************************************/ /** Safety check scheme. */ template struct TypeSizeCheckT { /** Safety check. */ static_assert(sizeof(T) == BYTES, "Type size is invalid."); /** Type forwarder type. */ using Type = T; }; /** Safety check. */ template using TypeSizeCheck = typename TypeSizeCheckT::Type; /************************************************************************/ /* Types. */ /************************************************************************/ /** Table of basic types according to byte size. */ template struct Types; /** 1-byte types. */ template<> struct Types<1> { using Unsigned = TypeSizeCheck; using Signed = TypeSizeCheck; }; /** 2-byte types. */ template<> struct Types<2> { using Unsigned = TypeSizeCheck; using Signed = TypeSizeCheck; }; /** 4-byte types. */ template<> struct Types<4> { #if DD_COMPILE_ARDUINO using Unsigned = TypeSizeCheck; using Signed = TypeSizeCheck< signed long, 4>; #else using Unsigned = TypeSizeCheck; using Signed = TypeSizeCheck< int, 4>; #endif using Float = TypeSizeCheck< float, 4>; }; /** 8-byte types. */ template<> struct Types<8> { using Unsigned = TypeSizeCheck; using Signed = TypeSizeCheck< signed long long, 8>; using Float = TypeSizeCheck< double, 8>; }; /************************************************************************/ /* Typedefs. */ /************************************************************************/ /** Signed types. */ template using Signed = typename Types::Signed; template using SignedT = Signed; /** Unsigned types. */ template using Unsigned = typename Types::Unsigned; template using UnsignedT = Unsigned; /** Float types. */ template using Float = typename Types::Float; template using FloatT = Float; /** 8-bit types. */ using Types8 = Types<1>; using u8 = Unsigned<1>; using i8 = Signed<1>; /** 16-bit types. */ using Types16 = Types<2>; using u16 = Unsigned<2>; using i16 = Signed<2>; /** 32-bit types. */ using Types32 = Types<4>; using u32 = Unsigned<4>; using i32 = Signed<4>; using f32 = Float<4>; /** 64-bit types. */ using Types64 = Types<8>; using u64 = Unsigned<8>; using i64 = Signed<8>; using f64 = Float<8>; /** Other. */ using Null = decltype(nullptr); /************************************************************************/ /* Casting helpers. */ /************************************************************************/ template constexpr SignedT & AsSigned(T & t) { return reinterpret_cast &>(t); } template constexpr const SignedT & AsSigned(const T & t) { return reinterpret_cast &>(t); } template constexpr UnsignedT & AsUnsigned(T & t) { return reinterpret_cast &>(t); } template constexpr const UnsignedT & AsUnsigned(const T & t) { return reinterpret_cast &>(t); } }