diff --git a/README.md b/README.md index 4af60c4..19e4e8f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,12 @@ Base X-platform library. [![License](https://img.shields.io/badge/license-BSD--2%20clause-blue.svg)](https://bkaradzic.github.io/bgfx/license.html) [![Join the chat at https://discord.gg/9eMbv7J](https://img.shields.io/discord/712512073522872352?color=%237289DA&label=bx&logo=discord&logoColor=white)](https://discord.gg/9eMbv7J) +Goals: + + - Provide OS/runtime/compiler independent core functionality to be able to + write cross-platform applications. + - Compile without C Runtime (CRT) and without C++ Standard Library (STL). + Contact ------- diff --git a/include/bx/inline/typetraits.inl b/include/bx/inline/typetraits.inl index 6614279..64fad7c 100644 --- a/include/bx/inline/typetraits.inl +++ b/include/bx/inline/typetraits.inl @@ -464,6 +464,58 @@ namespace bx return IsUnsignedT::value; } + //--- + template struct MakeSignedT { using Type = Ty; }; + template using MakeSignedType = typename MakeSignedT::Type; + + template struct MakeSignedT : AddConstType > {}; + template struct MakeSignedT : AddVolatileType> {}; + template struct MakeSignedT : AddCvType > {}; + + template<> struct MakeSignedT< char > { using Type = signed char; }; + template<> struct MakeSignedT< signed char > { using Type = signed char; }; + template<> struct MakeSignedT { using Type = signed char; }; + template<> struct MakeSignedT< short > { using Type = signed short; }; + template<> struct MakeSignedT { using Type = signed short; }; + template<> struct MakeSignedT< int > { using Type = signed int; }; + template<> struct MakeSignedT { using Type = signed int; }; + template<> struct MakeSignedT< long > { using Type = signed long; }; + template<> struct MakeSignedT { using Type = signed long; }; + template<> struct MakeSignedT< long long> { using Type = signed long long; }; + template<> struct MakeSignedT { using Type = signed long long; }; + + template + inline constexpr auto asSigned(Ty _t) + { + return MakeSignedType(_t); + } + + //--- + template struct MakeUnsignedT { using Type = Ty; }; + template using MakeUnsignedType = typename MakeUnsignedT::Type; + + template struct MakeUnsignedT : AddConstType > {}; + template struct MakeUnsignedT : AddVolatileType> {}; + template struct MakeUnsignedT : AddCvType > {}; + + template<> struct MakeUnsignedT< char > { using Type = unsigned char; }; + template<> struct MakeUnsignedT< signed char > { using Type = unsigned char; }; + template<> struct MakeUnsignedT { using Type = unsigned char; }; + template<> struct MakeUnsignedT< short > { using Type = unsigned short; }; + template<> struct MakeUnsignedT { using Type = unsigned short; }; + template<> struct MakeUnsignedT< int > { using Type = unsigned int; }; + template<> struct MakeUnsignedT { using Type = unsigned int; }; + template<> struct MakeUnsignedT< long > { using Type = unsigned long; }; + template<> struct MakeUnsignedT { using Type = unsigned long; }; + template<> struct MakeUnsignedT< long long> { using Type = unsigned long long; }; + template<> struct MakeUnsignedT { using Type = unsigned long long; }; + + template + inline constexpr auto asUnsigned(Ty _t) + { + return MakeUnsignedType(_t); + } + //--- template struct IsIntegerT : FalseConstant {}; template<> struct IsIntegerT : TrueConstant {}; diff --git a/include/bx/typetraits.h b/include/bx/typetraits.h index 5510c85..f0aab53 100644 --- a/include/bx/typetraits.h +++ b/include/bx/typetraits.h @@ -165,6 +165,14 @@ namespace bx template constexpr bool isUnsigned(); + /// Returns value of `_t` as signed type value. + template + constexpr auto asSigned(Ty _t); + + /// Returns value of `_t` as unsigned type value. + template + constexpr auto asUnsigned(Ty _t); + /// Returns true if type `Ty` is integer type, otherwise returns false. template constexpr bool isInteger(); diff --git a/src/dtoa.cpp b/src/dtoa.cpp index 2498a9a..e65c2ff 100644 --- a/src/dtoa.cpp +++ b/src/dtoa.cpp @@ -8,8 +8,6 @@ #include #include -#include - namespace bx { /* @@ -481,12 +479,8 @@ namespace bx return 0; } - _max = toString(_dst + 1 - , _max - 1 - , typename std::make_unsigned::type(-_value) - , _base - , _separator - ); + _max = toString(_dst + 1, _max - 1, asUnsigned(-_value), _base, _separator); + if (_max == 0) { return 0; @@ -496,12 +490,7 @@ namespace bx return int32_t(_max + 1); } - return toString(_dst - , _max - , typename std::make_unsigned::type(_value) - , _base - , _separator - ); + return toString(_dst, _max, asUnsigned(_value), _base, _separator); } int32_t toString(char* _dst, int32_t _max, int32_t _value, uint32_t _base, char _separator) diff --git a/tests/typetraits_test.cpp b/tests/typetraits_test.cpp index fbe5dac..c826129 100644 --- a/tests/typetraits_test.cpp +++ b/tests/typetraits_test.cpp @@ -299,6 +299,95 @@ TEST_CASE("type-traits isUnsigned", "") STATIC_REQUIRE(!bx::isUnsigned() ); } +TEST_CASE("type-traits MakeSignedT", "") +{ + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + STATIC_REQUIRE(bx::isSigned::Type >() ); + + enum struct E : unsigned short {}; + using char_type = std::make_signed_t; + using int_type = std::make_signed_t; + using long_type = std::make_signed_t; + using enum_type = std::make_signed_t; + + STATIC_REQUIRE(true + && bx::isSame() + && bx::isSame() + && bx::isSame() + && bx::isSame() + ); +} + +TEST_CASE("type-traits MakeUnsignedT", "") +{ + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + STATIC_REQUIRE(bx::isUnsigned::Type >() ); + + using uchar_type = std::make_unsigned_t; + using uint_type = std::make_unsigned_t; + using ulong_type = std::make_unsigned_t; + + STATIC_REQUIRE(true + && bx::isSame() + && bx::isSame() + && bx::isSame() + ); +} + TEST_CASE("type-traits isInteger", "") { STATIC_REQUIRE( bx::isInteger() );