diff --git a/matrix.cpp b/matrix.cpp index 7a992373..0bbcc8b0 100644 --- a/matrix.cpp +++ b/matrix.cpp @@ -261,15 +261,15 @@ template matrix4 matrix::perspective (T fov, T aspect, range Z) { - CHECK_GE (Z.min, 0); - CHECK_GE (Z.max, 0); + CHECK_GE (Z.lo, 0); + CHECK_GE (Z.hi, 0); T f = 1 / std::tan (fov / 2); T x = f / aspect; T y = f; - T z1 = (Z.max + Z.min) / (Z.min - Z.max); - T z2 = (2 * Z.max * Z.min) / (Z.min - Z.max); + T z1 = (Z.hi + Z.lo) / (Z.lo - Z.hi); + T z2 = (2 * Z.hi * Z.lo) / (Z.lo - Z.hi); return { { { x, 0, 0, 0 }, diff --git a/range.cpp b/range.cpp index 2143cb40..d376b3bb 100644 --- a/range.cpp +++ b/range.cpp @@ -21,37 +21,15 @@ #include "json/tree.hpp" #include "maths.hpp" -#include #include #include /////////////////////////////////////////////////////////////////////////////// template -const util::range -util::range::UNLIMITED (std::numeric_limits::has_infinity ? -std::numeric_limits::infinity () : - std::numeric_limits::lowest (), - std::numeric_limits::has_infinity ? std::numeric_limits::infinity () : - std::numeric_limits::max ()); - -//----------------------------------------------------------------------------- -template -const util::range -util::range::MAX (std::numeric_limits::lowest (), - std::numeric_limits::max ()); - - -//----------------------------------------------------------------------------- -template -const util::range -util::range::UNIT (0.0, 1.0); - - -/////////////////////////////////////////////////////////////////////////////// -template -util::range::range (T _min, T _max): - min (_min), - max (_max) +util::range::range (T _lo, T _hi): + lo (_lo), + hi (_hi) { sanity (); } @@ -62,7 +40,7 @@ template T util::range::magnitude (void) const { - return max - min; + return hi - lo; } @@ -71,7 +49,7 @@ template bool util::range::contains (T val) const { - return val >= min && val <= max; + return val >= lo && val <= hi; } @@ -80,7 +58,7 @@ template bool util::range::contains (const range &r) const { - return r.min >= min && r.max <= max; + return r.lo >= lo && r.hi <= hi; } @@ -89,7 +67,7 @@ template T util::range::at (float t) const { - return static_cast (min + (max - min) * t); + return static_cast (lo + (hi - lo) * t); } @@ -98,7 +76,7 @@ template T util::range::clamp (T val) const { - return std::max (min, std::min (val, max)); + return std::max (lo, std::min (val, hi)); } @@ -109,8 +87,8 @@ util::range::expand (T val) { // The arguments to min and max are such that expansion from initial NaN // values should change both min and max to be that value. - min = std::min (val, min); - max = std::max (val, max); + lo = std::min (val, lo); + hi = std::max (val, hi); } @@ -119,8 +97,8 @@ template util::range& util::range::operator*= (T val) { - min *= val; - max *= val; + lo *= val; + hi *= val; return *this; } @@ -131,7 +109,7 @@ template util::range util::range::operator* (T val) const { - return util::range (min * val, max * val); + return util::range (lo * val, hi * val); } @@ -140,7 +118,7 @@ template util::range util::range::operator- (T val) const { - return util::range (min - val, max - val); + return util::range (lo - val, hi - val); } @@ -151,7 +129,7 @@ namespace util { range::random (void) const { double pos = ::rand () / (double)(RAND_MAX); - return (max - min) * pos + min; + return (hi - lo) * pos + lo; } template <> @@ -159,7 +137,7 @@ namespace util { range::random (void) const { float pos = ::rand () / (float)(RAND_MAX); - return (max - min) * pos + min; + return (hi - lo) * pos + lo; } } @@ -169,7 +147,7 @@ template T util::range::random (void) const { - return min + (T)::rand () % (max - min); + return lo + (T)::rand () % (hi - lo); } @@ -179,8 +157,8 @@ namespace util { bool range::operator ==(const range &rhs) const { - return almost_equal (min, rhs.min) && - almost_equal (max, rhs.max); + return almost_equal (lo, rhs.lo) && + almost_equal (hi, rhs.hi); } @@ -188,8 +166,8 @@ namespace util { bool range::operator ==(const range &rhs) const { - return almost_equal (min, rhs.min) && - almost_equal (max, rhs.max); + return almost_equal (lo, rhs.lo) && + almost_equal (hi, rhs.hi); } } @@ -199,7 +177,7 @@ template bool util::range::operator ==(const util::range &rhs) const { - return min == rhs.min && max == rhs.max; + return lo == rhs.lo && hi == rhs.hi; } @@ -208,7 +186,7 @@ template void util::range::sanity (void) const { - CHECK (min <= max); + CHECK (lo <= hi); } @@ -218,9 +196,9 @@ namespace util { void range::sanity (void) const { - if (std::isnan (min) || std::isnan (max)) + if (std::isnan (lo) || std::isnan (hi)) return; - CHECK (min <= max); + CHECK (lo <= hi); } } @@ -237,17 +215,17 @@ namespace util { //----------------------------------------------------------------------------- -namespace json { namespace tree { +namespace json::tree { template <> util::range io>::deserialise (const json::tree::node &node) { if (node.is_string () && (node == "UNIT" || node == "unit")) { - return util::range::UNIT; + return util::range::unit (); } else if (node.is_string () && (node == "UNLIMITED" || node == "unlimited")) { - return util::range::UNLIMITED; + return util::range::unlimited (); } else { return { node[0].as_number (), @@ -255,4 +233,4 @@ namespace json { namespace tree { }; } } -} } +} diff --git a/range.hpp b/range.hpp index d7379884..2a7983ec 100644 --- a/range.hpp +++ b/range.hpp @@ -28,8 +28,8 @@ namespace util { */ template struct range { - T min; - T max; + T lo; + T hi; range (T _min, T _max); @@ -78,10 +78,10 @@ namespace util { { return !(*this == rhs); } /// A range which is guaranteed to contain all elements type T - static const range UNLIMITED; - static const range MAX; + static constexpr range unlimited (void); + static constexpr range max (void); /// A range which only contains elements between 0 and 1 inclusive - static const range UNIT; + static constexpr range unit (void); void sanity (void) const; }; diff --git a/range.ipp b/range.ipp index 470f04df..f5709792 100644 --- a/range.ipp +++ b/range.ipp @@ -20,19 +20,59 @@ #define __UTIL_RANGE_IPP #endif +#include #include //----------------------------------------------------------------------------- -namespace util { - template - template - U - range::normalise (T val) const { - static_assert (std::is_floating_point::value, - "normalise isn't implemented for integer types"); +template +template +U +util::range::normalise (T val) const +{ + static_assert (std::is_floating_point::value, + "normalise isn't implemented for integer types"); - return static_cast (val - min) / - static_cast (max - min); - } + return static_cast (val - lo) / + static_cast ( hi - lo); +} + + +/////////////////////////////////////////////////////////////////////////////// +template +constexpr +util::range +util::range::unlimited (void) +{ + return { + std::numeric_limits::has_infinity ? -std::numeric_limits::infinity () : + std::numeric_limits::lowest (), + std::numeric_limits::has_infinity ? std::numeric_limits::infinity () : + std::numeric_limits::max () + }; +} + + +//----------------------------------------------------------------------------- +template +constexpr +util::range +util::range::max (void) +{ + return { + std::numeric_limits::lowest (), + std::numeric_limits::max () + }; +} + + +//----------------------------------------------------------------------------- +template +constexpr +util::range +util::range::unit (void) +{ + return { + T {0}, T {1} + }; } diff --git a/test/range.cpp b/test/range.cpp index cb282f6e..09aba389 100644 --- a/test/range.cpp +++ b/test/range.cpp @@ -11,34 +11,34 @@ main (int, char **) util::TAP::logger tap; // Check some simple cases close to the edges of a unit range. Tests float rounding. - tap.expect ( util::range::UNIT.contains ( 0.0), "floating unit contains 0"); - tap.expect ( util::range::UNIT.contains ( 1.0), "floating unit contains 1"); - tap.expect ( util::range::UNIT.contains (std::numeric_limits::min ()), "floating unit contains min"); - tap.expect (!util::range::UNIT.contains (-0.00001), "doesn't contain fractionally low value"); - tap.expect (!util::range::UNIT.contains ( 1.00001), "doesn't contain fractionally high value"); + tap.expect ( util::range::unit ().contains ( 0.0), "floating unit contains 0"); + tap.expect ( util::range::unit ().contains ( 1.0), "floating unit contains 1"); + tap.expect ( util::range::unit ().contains (std::numeric_limits::min ()), "floating unit contains min"); + tap.expect (!util::range::unit ().contains (-0.00001), "doesn't contain fractionally low value"); + tap.expect (!util::range::unit ().contains ( 1.00001), "doesn't contain fractionally high value"); // Check edge cases of unit with integer values - tap.expect ( util::range::UNIT.contains (0), "unsigned unit contains 0"); - tap.expect ( util::range::UNIT.contains (1), "unsigned unit contains 1"); - tap.expect (!util::range::UNIT.contains (2), "unsigned unit doesn't contain 2"); - tap.expect (!util::range::UNIT.contains (std::numeric_limits ::max ()), "unsigned unit doesn't contain max"); + tap.expect ( util::range::unit ().contains (0), "unsigned unit contains 0"); + tap.expect ( util::range::unit ().contains (1), "unsigned unit contains 1"); + tap.expect (!util::range::unit ().contains (2), "unsigned unit doesn't contain 2"); + tap.expect (!util::range::unit ().contains (std::numeric_limits ::max ()), "unsigned unit doesn't contain max"); - // Check the inclusivity of UNLIMITED with special floating values - tap.expect ( util::range::UNLIMITED.contains (0.0), "floating unlimited contains 0"); - tap.expect ( util::range::UNLIMITED.contains (+std::numeric_limits::infinity ()), "floating unlimited contains +INF"); - tap.expect ( util::range::UNLIMITED.contains (-std::numeric_limits::infinity ()), "floating unlimited contains -INF"); - tap.expect (!util::range::UNLIMITED.contains ( std::numeric_limits::quiet_NaN ()), "floating unlimited doesn't contain NAN"); + // Check the inclusivity of unlimited with special floating values + tap.expect ( util::range::unlimited ().contains (0.0), "floating unlimited contains 0"); + tap.expect ( util::range::unlimited ().contains (+std::numeric_limits::infinity ()), "floating unlimited contains +INF"); + tap.expect ( util::range::unlimited ().contains (-std::numeric_limits::infinity ()), "floating unlimited contains -INF"); + tap.expect (!util::range::unlimited ().contains ( std::numeric_limits::quiet_NaN ()), "floating unlimited doesn't contain NAN"); - // Check the inclusivity of UNLIMITED with some large numbers - tap.expect ( util::range::UNLIMITED.contains (std::numeric_limits::min()), "floating unlimited contains min"); - tap.expect ( util::range::UNLIMITED.contains (std::numeric_limits::max()), "floating unlimited contains max"); + // Check the inclusivity of unlimited with some large numbers + tap.expect ( util::range::unlimited ().contains (std::numeric_limits::min()), "floating unlimited contains min"); + tap.expect ( util::range::unlimited ().contains (std::numeric_limits::max()), "floating unlimited contains max"); - // Check inclusivity of MAX - tap.expect (!util::range::MAX.contains ( std::numeric_limits::infinity ()), "floating max contains +INF"); - tap.expect (!util::range::MAX.contains (-std::numeric_limits::infinity ()), "floating max contains -INF"); + // Check inclusivity of max + tap.expect (!util::range::max ().contains ( std::numeric_limits::infinity ()), "floating max contains +INF"); + tap.expect (!util::range::max ().contains (-std::numeric_limits::infinity ()), "floating max contains -INF"); - tap.expect ( util::range::MAX.contains (std::numeric_limits::min()), "unsigned max contains min"); - tap.expect ( util::range::MAX.contains (std::numeric_limits::max()), "unsigned max contains max"); + tap.expect ( util::range::max ().contains (std::numeric_limits::min()), "unsigned max contains min"); + tap.expect ( util::range::max ().contains (std::numeric_limits::max()), "unsigned max contains max"); // Check that expansion via NaN is a noop { @@ -46,8 +46,8 @@ main (int, char **) std::numeric_limits::quiet_NaN ()); initial_nan.expand (1.0); - tap.expect_eq (initial_nan.min, 1.0, "NAN expansion noop for min"); - tap.expect_eq (initial_nan.max, 1.0, "NAN expansion noop for max"); + tap.expect_eq (initial_nan.lo, 1.0, "NAN expansion noop for lo"); + tap.expect_eq (initial_nan.hi, 1.0, "NAN expansion noop for hi"); } return tap.status ();