2012-06-13 14:41:53 +10:00
|
|
|
/*
|
2015-04-13 18:05:28 +10:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2012-06-13 14:41:53 +10:00
|
|
|
*
|
2015-04-13 18:05:28 +10:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2012-06-13 14:41:53 +10:00
|
|
|
*
|
2015-04-13 18:05:28 +10:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
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"
|
|
|
|
|
|
|
|
#include "debug.hpp"
|
2015-02-03 00:07:09 +11:00
|
|
|
#include "json/tree.hpp"
|
2011-05-23 17:18:52 +10:00
|
|
|
#include "maths.hpp"
|
|
|
|
|
|
|
|
#include <limits>
|
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>
|
|
|
|
const util::range<T>
|
|
|
|
util::range<T>::UNLIMITED (std::numeric_limits<T>::has_infinity ? -std::numeric_limits<T>::infinity () :
|
|
|
|
std::numeric_limits<T>::lowest (),
|
|
|
|
std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity () :
|
|
|
|
std::numeric_limits<T>::max ());
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
|
|
|
const util::range<T>
|
|
|
|
util::range<T>::MAX (std::numeric_limits<T>::lowest (),
|
|
|
|
std::numeric_limits<T>::max ());
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
|
|
|
const util::range<T>
|
|
|
|
util::range<T>::UNIT (0.0, 1.0);
|
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
2015-02-20 20:45:39 +11:00
|
|
|
util::range<T>::range (T _min, T _max):
|
2011-05-23 17:18:52 +10:00
|
|
|
min (_min),
|
|
|
|
max (_max)
|
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
|
|
|
|
util::range<T>::magnitude (void) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2015-02-20 20:49:41 +11:00
|
|
|
return max - min;
|
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
|
2015-02-20 20:49:41 +11:00
|
|
|
util::range<T>::contains (T val) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2015-02-20 20:49:41 +11:00
|
|
|
return val >= min && val <= max;
|
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
|
|
|
|
util::range<T>::contains (const range <T> &r) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
2015-02-20 20:49:41 +11:00
|
|
|
return r.min >= min && r.max <= max;
|
2012-01-04 17:05:09 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-11 16:27:37 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
|
|
|
T
|
|
|
|
util::range<T>::at (float t) const
|
|
|
|
{
|
|
|
|
return static_cast<T> (min + (max - min) * t);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
|
|
|
T
|
2015-02-20 20:45:39 +11:00
|
|
|
util::range<T>::clamp (T val) const
|
|
|
|
{
|
|
|
|
return std::max (min, std::min (val, max));
|
|
|
|
}
|
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
|
2015-02-20 20:45:39 +11:00
|
|
|
util::range<T>::expand (T val)
|
|
|
|
{
|
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.
|
|
|
|
min = std::min (val, min);
|
|
|
|
max = std::max (val, max);
|
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>
|
2015-02-20 20:45:39 +11:00
|
|
|
util::range<T>&
|
|
|
|
util::range<T>::operator*= (T val)
|
|
|
|
{
|
2012-05-24 15:03:26 +10:00
|
|
|
min *= val;
|
|
|
|
max *= val;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2012-05-24 15:03:26 +10:00
|
|
|
template <typename T>
|
2015-02-20 20:45:39 +11:00
|
|
|
util::range<T>
|
|
|
|
util::range<T>::operator* (T val) const
|
|
|
|
{
|
|
|
|
return util::range<T> (min * val, max * val);
|
2012-05-24 15:03:26 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-29 17:31:20 +10:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
|
|
|
util::range<T>
|
|
|
|
util::range<T>::operator- (T val) const
|
|
|
|
{
|
|
|
|
return util::range<T> (min - val, max - val);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2012-01-04 17:05:09 +11:00
|
|
|
namespace util {
|
|
|
|
template <>
|
|
|
|
double
|
2015-02-20 20:45:39 +11:00
|
|
|
range<double>::random (void) const
|
|
|
|
{
|
2012-01-04 17:05:09 +11:00
|
|
|
double pos = ::rand () / (double)(RAND_MAX);
|
|
|
|
return (max - min) * pos + min;
|
2015-04-13 18:06:08 +10:00
|
|
|
}
|
2012-01-04 17:05:09 +11:00
|
|
|
|
|
|
|
template <>
|
|
|
|
float
|
2015-02-20 20:45:39 +11:00
|
|
|
range<float>::random (void) const
|
|
|
|
{
|
2012-01-04 17:05:09 +11:00
|
|
|
float pos = ::rand () / (float)(RAND_MAX);
|
|
|
|
return (max - min) * pos + min;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2011-05-23 17:18:52 +10:00
|
|
|
template <typename T>
|
|
|
|
T
|
2015-02-20 20:45:39 +11:00
|
|
|
util::range<T>::random (void) const
|
|
|
|
{
|
2012-01-04 17:05:09 +11:00
|
|
|
return min + (T)::rand () % (max - min);
|
2011-05-23 17:18:52 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2011-08-15 20:11:42 +10:00
|
|
|
namespace util {
|
|
|
|
template <>
|
|
|
|
bool
|
|
|
|
range<float>::operator ==(const range<float> &rhs) const
|
2015-02-20 20:45:39 +11:00
|
|
|
{
|
|
|
|
return almost_equal (min, rhs.min) &&
|
|
|
|
almost_equal (max, rhs.max);
|
|
|
|
}
|
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
|
|
|
{
|
|
|
|
return almost_equal (min, rhs.min) &&
|
|
|
|
almost_equal (max, rhs.max);
|
|
|
|
}
|
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
|
2015-02-20 20:45:39 +11:00
|
|
|
util::range<T>::operator ==(const util::range<T> &rhs) const
|
|
|
|
{
|
|
|
|
return min == rhs.min && max == rhs.max;
|
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
2015-02-20 20:49:41 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename T>
|
|
|
|
void
|
|
|
|
util::range<T>::sanity (void) const
|
|
|
|
{
|
|
|
|
CHECK (min <= max);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace util {
|
|
|
|
template <>
|
|
|
|
void
|
|
|
|
range<double>::sanity (void) const
|
|
|
|
{
|
|
|
|
if (std::isnan (min) || std::isnan (max))
|
|
|
|
return;
|
|
|
|
CHECK (min <= max);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-20 20:40:01 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2012-06-13 14:41:53 +10:00
|
|
|
namespace util {
|
|
|
|
template struct range<double>;
|
|
|
|
template struct range<float>;
|
|
|
|
template struct range<uint8_t>;
|
|
|
|
template struct range<uint16_t>;
|
|
|
|
template struct range<uint32_t>;
|
|
|
|
template struct range<uint64_t>;
|
|
|
|
}
|
2014-03-06 15:22:47 +11:00
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2015-02-02 21:22:38 +11:00
|
|
|
namespace json { namespace tree {
|
2014-03-06 15:22:47 +11:00
|
|
|
template <>
|
|
|
|
util::range<double>
|
2015-02-20 20:45:39 +11:00
|
|
|
io<util::range<double>>::deserialise (const json::tree::node &node)
|
|
|
|
{
|
2014-03-06 15:22:47 +11:00
|
|
|
if (node.is_string () && (node == "UNIT" ||
|
|
|
|
node == "unit")) {
|
|
|
|
return util::range<double>::UNIT;
|
|
|
|
} else if (node.is_string () && (node == "UNLIMITED" ||
|
|
|
|
node == "unlimited")) {
|
|
|
|
return util::range<double>::UNLIMITED;
|
|
|
|
} else {
|
|
|
|
return {
|
|
|
|
node[0].as_number (),
|
|
|
|
node[1].as_number ()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2015-02-02 21:22:38 +11:00
|
|
|
} }
|