/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2011-2012 Danny Robson */ #include "range.hpp" #include "debug/assert.hpp" #include "maths.hpp" #include "random.hpp" #include #include #include /////////////////////////////////////////////////////////////////////////////// template cruft::range::range (T _lo, T _hi): lo (_lo), hi (_hi) { sanity (); } /////////////////////////////////////////////////////////////////////////////// template T cruft::range::magnitude (void) const { return hi - lo; } /////////////////////////////////////////////////////////////////////////////// template bool cruft::range::contains (T val) const { return val >= lo && val <= hi; } //----------------------------------------------------------------------------- template bool cruft::range::contains (const range &r) const { return r.lo >= lo && r.hi <= hi; } //----------------------------------------------------------------------------- template T cruft::range::at (float t) const { return static_cast (lo + (hi - lo) * t); } //----------------------------------------------------------------------------- template T cruft::range::clamp (T val) const { return std::max (lo, std::min (val, hi)); } //----------------------------------------------------------------------------- template void cruft::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. lo = std::min (val, lo); hi = std::max (val, hi); } /////////////////////////////////////////////////////////////////////////////// template cruft::range& cruft::range::operator*= (T val) { lo *= val; hi *= val; return *this; } //----------------------------------------------------------------------------- template cruft::range cruft::range::operator* (T val) const { return cruft::range (lo * val, hi * val); } //----------------------------------------------------------------------------- template cruft::range cruft::range::operator- (T val) const { return cruft::range (lo - val, hi - val); } //----------------------------------------------------------------------------- template cruft::range cruft::range::operator+ (T val) const { return cruft::range ( lo + val, hi + val ); } /////////////////////////////////////////////////////////////////////////////// template T cruft::range::random (void) const { if constexpr (std::is_floating_point_v) { return std::uniform_real_distribution (lo, hi) (cruft::random::generator ()); } else { return std::uniform_int_distribution (lo, hi) (cruft::random::generator ()); } } /////////////////////////////////////////////////////////////////////////////// namespace cruft { template <> bool range::operator ==(const range &rhs) const { return almost_equal (lo, rhs.lo) && almost_equal (hi, rhs.hi); } template <> bool range::operator ==(const range &rhs) const { return almost_equal (lo, rhs.lo) && almost_equal (hi, rhs.hi); } } //----------------------------------------------------------------------------- template bool cruft::range::operator ==(const cruft::range &rhs) const { return lo == rhs.lo && hi == rhs.hi; } /////////////////////////////////////////////////////////////////////////////// template std::ostream& cruft::operator <<(std::ostream &os, const range &rhs) { os << '[' << rhs.lo << ", " << rhs.hi << ']'; return os; } template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); template std::ostream& cruft::operator<< (std::ostream&, range const&); /////////////////////////////////////////////////////////////////////////////// template void cruft::range::sanity (void) const { CHECK (lo <= hi); } //----------------------------------------------------------------------------- namespace cruft { template <> void range::sanity (void) const { if (std::isnan (lo) || std::isnan (hi)) return; CHECK (lo <= hi); } } //----------------------------------------------------------------------------- template struct cruft::range; template struct cruft::range; template struct cruft::range; template struct cruft::range; template struct cruft::range; template struct cruft::range; template struct cruft::range; template struct cruft::range; template struct cruft::range; template struct cruft::range;