2012-06-13 14:41:53 +10:00
|
|
|
/*
|
2018-08-04 15:14:06 +10:00
|
|
|
* 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/.
|
2012-06-13 14:41:53 +10:00
|
|
|
*
|
|
|
|
* Copyright 2011-2012 Danny Robson <danny@nerdcruft.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2011-05-23 17:18:52 +10:00
|
|
|
#include "range.hpp"
|
|
|
|
|
2019-05-17 12:26:08 +10:00
|
|
|
#include "debug/assert.hpp"
|
2011-05-23 17:18:52 +10:00
|
|
|
#include "maths.hpp"
|
2018-05-03 18:32:08 +10:00
|
|
|
#include "random.hpp"
|
2011-05-23 17:18:52 +10:00
|
|
|
|
2014-03-06 15:22:47 +11:00
|
|
|
#include <cmath>
|
2011-05-23 17:18:52 +10:00
|
|
|
#include <cstdint>
|
|
|
|
|
|
|
|
|
2016-11-17 18:31:01 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename T>
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::range (T _lo, T _hi):
|
2016-12-21 16:44:48 +11:00
|
|
|
lo (_lo),
|
|
|
|
hi (_hi)
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
|
|
|
sanity ();
|
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
2015-02-20 20:49:41 +11:00
|
|
|
T
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::magnitude (void) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
return hi - lo;
|
2015-02-20 20:45:39 +11:00
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
|
|
|
bool
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::contains (T val) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
return val >= lo && val <= hi;
|
2015-02-20 20:45:39 +11:00
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
2015-02-20 20:49:41 +11:00
|
|
|
bool
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::contains (const range <T> &r) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
return r.lo >= lo && r.hi <= hi;
|
2012-01-04 17:05:09 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-11 16:27:37 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
|
|
|
T
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::at (float t) const
|
2015-03-11 16:27:37 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
return static_cast<T> (lo + (hi - lo) * t);
|
2015-03-11 16:27:37 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
|
|
|
T
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::clamp (T val) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
return std::max (lo, std::min (val, hi));
|
2015-02-20 20:45:39 +11:00
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2012-05-22 14:12:06 +10:00
|
|
|
template <typename T>
|
2012-05-23 17:01:54 +10:00
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::expand (T val)
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2012-05-23 20:41:11 +10:00
|
|
|
// The arguments to min and max are such that expansion from initial NaN
|
|
|
|
// values should change both min and max to be that value.
|
2016-12-21 16:44:48 +11:00
|
|
|
lo = std::min (val, lo);
|
|
|
|
hi = std::max (val, hi);
|
2012-05-22 14:12:06 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2012-05-24 15:03:26 +10:00
|
|
|
template <typename T>
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>&
|
|
|
|
cruft::range<T>::operator*= (T val)
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
lo *= val;
|
|
|
|
hi *= val;
|
2012-05-24 15:03:26 +10:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2012-05-24 15:03:26 +10:00
|
|
|
template <typename T>
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>
|
|
|
|
cruft::range<T>::operator* (T val) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
return cruft::range<T> (lo * val, hi * val);
|
2012-05-24 15:03:26 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-29 17:31:20 +10:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>
|
|
|
|
cruft::range<T>::operator- (T val) const
|
2015-09-29 17:31:20 +10:00
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
return cruft::range<T> (lo - val, hi - val);
|
2015-09-29 17:31:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-29 12:58:46 +10:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
|
|
|
cruft::range<T>
|
|
|
|
cruft::range<T>::operator+ (T val) const
|
|
|
|
{
|
|
|
|
return cruft::range<T> (
|
|
|
|
lo + val,
|
|
|
|
hi + val
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
|
|
|
T
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::random (void) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2018-05-03 18:32:08 +10:00
|
|
|
if constexpr (std::is_floating_point_v<T>) {
|
2018-08-05 14:42:02 +10:00
|
|
|
return std::uniform_real_distribution<T> (lo, hi) (cruft::random::generator ());
|
2018-05-03 18:32:08 +10:00
|
|
|
} else {
|
2018-08-05 14:42:02 +10:00
|
|
|
return std::uniform_int_distribution<T> (lo, hi) (cruft::random::generator ());
|
2018-05-03 18:32:08 +10:00
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2018-08-05 14:42:02 +10:00
|
|
|
namespace cruft {
|
2011-08-15 20:11:42 +10:00
|
|
|
template <>
|
|
|
|
bool
|
|
|
|
range<float>::operator ==(const range<float> &rhs) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
return almost_equal (lo, rhs.lo) &&
|
|
|
|
almost_equal (hi, rhs.hi);
|
2015-02-20 20:45:39 +11:00
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
2011-08-15 20:11:42 +10:00
|
|
|
template <>
|
|
|
|
bool
|
|
|
|
range<double>::operator ==(const range<double> &rhs) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
return almost_equal (lo, rhs.lo) &&
|
|
|
|
almost_equal (hi, rhs.hi);
|
2015-02-20 20:45:39 +11:00
|
|
|
}
|
2011-08-15 20:11:42 +10:00
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
|
|
|
bool
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::operator ==(const cruft::range<T> &rhs) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
return lo == rhs.lo && hi == rhs.hi;
|
2015-02-20 20:45:39 +11:00
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename T>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::range<T>::sanity (void) const
|
2015-02-20 20:49:41 +11:00
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
CHECK (lo <= hi);
|
2015-02-20 20:49:41 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2018-08-05 14:42:02 +10:00
|
|
|
namespace cruft {
|
2015-02-20 20:49:41 +11:00
|
|
|
template <>
|
|
|
|
void
|
|
|
|
range<double>::sanity (void) const
|
|
|
|
{
|
2016-12-21 16:44:48 +11:00
|
|
|
if (std::isnan (lo) || std::isnan (hi))
|
2015-02-20 20:49:41 +11:00
|
|
|
return;
|
2016-12-21 16:44:48 +11:00
|
|
|
CHECK (lo <= hi);
|
2015-02-20 20:49:41 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2018-08-05 14:42:02 +10:00
|
|
|
template struct cruft::range<double>;
|
|
|
|
template struct cruft::range<float>;
|
|
|
|
template struct cruft::range<int8_t>;
|
|
|
|
template struct cruft::range<int16_t>;
|
|
|
|
template struct cruft::range<int32_t>;
|
|
|
|
template struct cruft::range<int64_t>;
|
|
|
|
template struct cruft::range<uint8_t>;
|
|
|
|
template struct cruft::range<uint16_t>;
|
|
|
|
template struct cruft::range<uint32_t>;
|
|
|
|
template struct cruft::range<uint64_t>;
|