From d4403099f916425d4bae3252c77396b51d8fe734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Mon, 22 Aug 2022 20:30:24 -0700 Subject: [PATCH] Added numeric min/max for type. --- include/bx/bx.h | 15 +++++---- include/bx/constants.h | 70 ++++++++++++++++++++++++++++++++++++++++ include/bx/inline/bx.inl | 46 ++++++++++++++++++++++++++ include/bx/math.h | 16 --------- tests/math_test.cpp | 38 ++++++++++++++++++++++ tests/sort_test.cpp | 13 ++++---- 6 files changed, 170 insertions(+), 28 deletions(-) create mode 100644 include/bx/constants.h diff --git a/include/bx/bx.h b/include/bx/bx.h index c03509e..c84e76f 100644 --- a/include/bx/bx.h +++ b/include/bx/bx.h @@ -14,6 +14,7 @@ #include "platform.h" #include "config.h" +#include "constants.h" #include "macros.h" #include "debug.h" @@ -32,12 +33,6 @@ namespace bx { - /// Used to return successful execution of a program code. - constexpr int32_t kExitSuccess = 0; - - /// Used to return unsuccessful execution of a program code. - constexpr int32_t kExitFailure = 1; - /// Returns true if type `Ty` is trivially copyable / POD type. template constexpr bool isTriviallyCopyable(); @@ -57,6 +52,14 @@ namespace bx /// Swap memory. void swap(void* _a, void* _b, size_t _numBytes); + /// Returns numeric minimum of type. + template + constexpr Ty min(); + + /// Returns numeric maximum of type. + template + constexpr Ty max(); + /// Returns minimum of two values. template constexpr Ty min(const Ty& _a, const Ty& _b); diff --git a/include/bx/constants.h b/include/bx/constants.h new file mode 100644 index 0000000..14c4cdb --- /dev/null +++ b/include/bx/constants.h @@ -0,0 +1,70 @@ +/* + * Copyright 2011-2022 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx/blob/master/LICENSE + */ + +#ifndef BX_CONSTANTS_H_HEADER_GUARD +#define BX_CONSTANTS_H_HEADER_GUARD + +namespace bx +{ + /// Used to return successful execution of a program code. + constexpr int32_t kExitSuccess = 0; + + /// Used to return unsuccessful execution of a program code. + constexpr int32_t kExitFailure = 1; + + /// The ratio of a circle's circumference to its diameter, + constexpr float kPi = 3.1415926535897932384626433832795f; + + /// The ratio of a circle's circumference to its radius. Pi multiplied by 2, or Tau. pi*2 + constexpr float kPi2 = 6.2831853071795864769252867665590f; + + /// The reciprocal of pi. 1/pi + constexpr float kInvPi = 1.0f/kPi; + + /// Pi divided by two. pi/2 + constexpr float kPiHalf = 1.5707963267948966192313216916398f; + + /// Pi divided by four. pi/4 + constexpr float kPiQuarter = 0.7853981633974483096156608458199f; + + /// The square root of two. sqrt(2) + constexpr float kSqrt2 = 1.4142135623730950488016887242097f; + + /// ln(10) + constexpr float kLogNat10 = 2.3025850929940456840179914546844f; + + /// The logarithm of the e to base 2. ln(kE) / ln(2) + constexpr float kInvLogNat2 = 1.4426950408889634073599246810019f; + + /// The natural logarithm of the 2. ln(2) + constexpr float kLogNat2Hi = 0.6931471805599453094172321214582f; + + /// + constexpr float kLogNat2Lo = 1.90821492927058770002e-10f; + + /// The base of natural logarithms. e(1) + constexpr float kE = 2.7182818284590452353602874713527f; + + /// + constexpr float kNearZero = 1.0f/float(1 << 28); + + /// Smallest normalized positive floating-point number. + constexpr float kFloatSmallest = 1.175494351e-38f; + + /// Maximum representable floating-point number. + constexpr float kFloatLargest = 3.402823466e+38f; + + /// Smallest normalized positive double-precision floating-point number. + constexpr double kDoubleSmallest = 2.2250738585072014e-308; + + /// Largest representable double-precision floating-point number. + constexpr double kDoubleLargest = 1.7976931348623158e+308; + + /// + extern const float kInfinity; + +} // namespace bx + +#endif // BX_CONSTANTS_H_HEADER_GUARD diff --git a/include/bx/inline/bx.inl b/include/bx/inline/bx.inl index 2788cb9..4b07f29 100644 --- a/include/bx/inline/bx.inl +++ b/include/bx/inline/bx.inl @@ -59,6 +59,52 @@ namespace bx Ty tmp = _a; _a = _b; _b = tmp; } + template + struct IsSignedT { static constexpr bool value = Ty(-1) < Ty(0); }; + + template::value> + struct Limits; + + template + struct Limits + { + static constexpr Ty max = ( ( (Ty(1) << ( (sizeof(Ty) * 8) - 2) ) - Ty(1) ) << 1) | Ty(1); + static constexpr Ty min = -max - Ty(1); + }; + + template + struct Limits + { + static constexpr Ty min = 0; + static constexpr Ty max = Ty(-1); + }; + + template<> + struct Limits + { + static constexpr float min = -kFloatLargest; + static constexpr float max = kFloatLargest; + }; + + template<> + struct Limits + { + static constexpr double min = -kDoubleLargest; + static constexpr double max = kDoubleLargest; + }; + + template + inline constexpr Ty max() + { + return bx::Limits::max; + } + + template + inline constexpr Ty min() + { + return bx::Limits::min; + } + template inline constexpr Ty min(const Ty& _a, const Ty& _b) { diff --git a/include/bx/math.h b/include/bx/math.h index b260813..f0e2acb 100644 --- a/include/bx/math.h +++ b/include/bx/math.h @@ -11,22 +11,6 @@ namespace bx { - constexpr float kPi = 3.1415926535897932384626433832795f; - constexpr float kPi2 = 6.2831853071795864769252867665590f; - constexpr float kInvPi = 1.0f/kPi; - constexpr float kPiHalf = 1.5707963267948966192313216916398f; - constexpr float kPiQuarter = 0.7853981633974483096156608458199f; - constexpr float kSqrt2 = 1.4142135623730950488016887242097f; - constexpr float kLogNat10 = 2.3025850929940456840179914546844f; - constexpr float kInvLogNat2 = 1.4426950408889634073599246810019f; - constexpr float kLogNat2Hi = 0.6931471805599453094172321214582f; - constexpr float kLogNat2Lo = 1.90821492927058770002e-10f; - constexpr float kE = 2.7182818284590452353602874713527f; - constexpr float kNearZero = 1.0f/float(1 << 28); - constexpr float kFloatMin = 1.175494e-38f; - constexpr float kFloatMax = 3.402823e+38f; - extern const float kInfinity; - /// typedef float (*LerpFn)(float _a, float _b, float _t); diff --git a/tests/math_test.cpp b/tests/math_test.cpp index a4c3544..3ce37eb 100644 --- a/tests/math_test.cpp +++ b/tests/math_test.cpp @@ -8,6 +8,8 @@ #include #include +#include // intXX_t +#include // UCHAR_* #if !BX_COMPILER_MSVC || BX_COMPILER_MSVC >= 1800 TEST_CASE("isFinite, isInfinite, isNan", "") @@ -334,3 +336,39 @@ TEST_CASE("quaternion", "") REQUIRE(bx::isEqual(quat, q2, 0.001f) ); } } + +TEST_CASE("limits", "") +{ + STATIC_REQUIRE(bx::Limits::min == INT8_MIN); + STATIC_REQUIRE(bx::Limits::max == INT8_MAX); + + STATIC_REQUIRE(bx::Limits::min == CHAR_MIN); + STATIC_REQUIRE(bx::Limits::max == CHAR_MAX); + + STATIC_REQUIRE(bx::Limits::min == 0); + STATIC_REQUIRE(bx::Limits::max == UCHAR_MAX); + + STATIC_REQUIRE(bx::Limits::min == INT16_MIN); + STATIC_REQUIRE(bx::Limits::max == INT16_MAX); + + STATIC_REQUIRE(bx::Limits::min == 0); + STATIC_REQUIRE(bx::Limits::max == UINT16_MAX); + + STATIC_REQUIRE(bx::Limits::min == INT32_MIN); + STATIC_REQUIRE(bx::Limits::max == INT32_MAX); + + STATIC_REQUIRE(bx::Limits::min == 0); + STATIC_REQUIRE(bx::Limits::max == UINT32_MAX); + + STATIC_REQUIRE(bx::Limits::min == INT64_MIN); + STATIC_REQUIRE(bx::Limits::max == INT64_MAX); + + STATIC_REQUIRE(bx::Limits::min == 0); + STATIC_REQUIRE(bx::Limits::max == UINT64_MAX); + + STATIC_REQUIRE(bx::Limits::min == std::numeric_limits::lowest() ); + STATIC_REQUIRE(bx::Limits::max == std::numeric_limits::max() ); + + STATIC_REQUIRE(bx::Limits::min == std::numeric_limits::lowest() ); + STATIC_REQUIRE(bx::Limits::max == std::numeric_limits::max() ); +} diff --git a/tests/sort_test.cpp b/tests/sort_test.cpp index 495a90e..93c5bc7 100644 --- a/tests/sort_test.cpp +++ b/tests/sort_test.cpp @@ -4,6 +4,7 @@ */ #include "test.h" +#include #include #include #include @@ -110,12 +111,12 @@ void compareTest(const Ty& _min, const Ty& _max) { REQUIRE(_min < _max); - REQUIRE(-1 == compareAscendingTest(std::numeric_limits::min(), std::numeric_limits::max() ) ); - REQUIRE(-1 == compareAscendingTest(Ty(0), std::numeric_limits::max() ) ); - REQUIRE( 0 == compareAscendingTest(std::numeric_limits::min(), std::numeric_limits::min() ) ); - REQUIRE( 0 == compareAscendingTest(std::numeric_limits::max(), std::numeric_limits::max() ) ); - REQUIRE( 1 == compareAscendingTest(std::numeric_limits::max(), Ty(0) ) ); - REQUIRE( 1 == compareAscendingTest(std::numeric_limits::max(), std::numeric_limits::min() ) ); + REQUIRE(-1 == compareAscendingTest(bx::min(), bx::max() ) ); + REQUIRE(-1 == compareAscendingTest(Ty(0), bx::max() ) ); + REQUIRE( 0 == compareAscendingTest(bx::min(), bx::min() ) ); + REQUIRE( 0 == compareAscendingTest(bx::max(), bx::max() ) ); + REQUIRE( 1 == compareAscendingTest(bx::max(), Ty(0) ) ); + REQUIRE( 1 == compareAscendingTest(bx::max(), bx::min() ) ); REQUIRE(-1 == compareAscendingTest(_min, _max) ); REQUIRE( 0 == compareAscendingTest(_min, _min) );