mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
* Support runtime floating-point clamped_value before C++20 * Add referenced clamped values with shared ranges
1379 lines
52 KiB
C++
1379 lines
52 KiB
C++
///\file
|
|
|
|
/******************************************************************************
|
|
The MIT License(MIT)
|
|
|
|
Embedded Template Library.
|
|
https://github.com/ETLCPP/etl
|
|
https://www.etlcpp.com
|
|
|
|
Copyright(c) 2026 John Wellbelove
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files(the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions :
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
#ifndef ETL_CLAMPED_VALUE_INCLUDED
|
|
#define ETL_CLAMPED_VALUE_INCLUDED
|
|
|
|
#include "platform.h"
|
|
#include "absolute.h"
|
|
#include "algorithm.h"
|
|
#include "error_handler.h"
|
|
#include "functional.h"
|
|
#include "limits.h"
|
|
#include "math.h"
|
|
#include "static_assert.h"
|
|
#include "type_traits.h"
|
|
#include "utility.h"
|
|
|
|
///\def ETL_HAS_FLOATING_POINT_CLAMPED_VALUE
|
|
/// Set to `1` when clamped_value supports floating-point types.
|
|
/// Runtime floating-point support requires C++11 variadic templates.
|
|
/// The macro may be defined by the build or platform profile to override
|
|
/// automatic detection.
|
|
#if !defined(ETL_HAS_FLOATING_POINT_CLAMPED_VALUE)
|
|
#if ETL_USING_CPP11
|
|
#define ETL_HAS_FLOATING_POINT_CLAMPED_VALUE 1
|
|
#else
|
|
#define ETL_HAS_FLOATING_POINT_CLAMPED_VALUE 0
|
|
#endif
|
|
#endif
|
|
|
|
///\def ETL_HAS_COMPILE_TIME_FLOATING_POINT_CLAMPED_VALUE
|
|
/// Set to `1` when clamped_value supports floating-point compile-time bounds.
|
|
#if !defined(ETL_HAS_COMPILE_TIME_FLOATING_POINT_CLAMPED_VALUE)
|
|
#if ETL_HAS_FLOATING_POINT_CLAMPED_VALUE && ETL_USING_CPP20 && defined(__cpp_nontype_template_args) && (__cpp_nontype_template_args >= 201911L)
|
|
#define ETL_HAS_COMPILE_TIME_FLOATING_POINT_CLAMPED_VALUE 1
|
|
#else
|
|
#define ETL_HAS_COMPILE_TIME_FLOATING_POINT_CLAMPED_VALUE 0
|
|
#endif
|
|
#endif
|
|
|
|
///\defgroup clamped_value clamped_value
|
|
/// Provides a value that is clamped between two limits.
|
|
/// Integral types are supported in all language modes. Floating-point types
|
|
/// with runtime bounds are supported when
|
|
/// ETL_HAS_FLOATING_POINT_CLAMPED_VALUE is `1`.
|
|
/// \ingroup utilities
|
|
|
|
namespace etl
|
|
{
|
|
/// \cond INTERNAL
|
|
namespace private_clamped_value
|
|
{
|
|
//*************************************************************************
|
|
/// Type policy for clamped_value.
|
|
/// Integral values use a signed difference type and unsigned saturation
|
|
/// arithmetic. Floating-point values use `T` as the difference type.
|
|
//*************************************************************************
|
|
template <typename T, bool IsIntegral = etl::is_integral<T>::value>
|
|
struct traits;
|
|
|
|
template <typename T>
|
|
struct traits<T, true>
|
|
{
|
|
typedef typename etl::make_signed<T>::type difference_type;
|
|
typedef typename etl::make_unsigned<T>::type unsigned_type;
|
|
typedef etl::numeric_limits<T> limits_type;
|
|
typedef etl::numeric_limits<difference_type> difference_limits_type;
|
|
};
|
|
|
|
template <typename T>
|
|
struct traits<T, false>
|
|
{
|
|
ETL_STATIC_ASSERT(ETL_HAS_FLOATING_POINT_CLAMPED_VALUE&& etl::is_floating_point<T>::value,
|
|
"clamped_value requires an integral type, or a floating-point type when supported");
|
|
|
|
typedef T difference_type;
|
|
typedef etl::numeric_limits<T> limits_type;
|
|
typedef etl::numeric_limits<T> difference_limits_type;
|
|
};
|
|
|
|
template <typename T, bool IsIntegral = etl::is_integral<T>::value>
|
|
struct arithmetic;
|
|
|
|
//*************************************************************************
|
|
/// Saturating arithmetic policy for integral values.
|
|
//*************************************************************************
|
|
template <typename T>
|
|
struct arithmetic<T, true>
|
|
{
|
|
typedef typename traits<T>::unsigned_type unsigned_type;
|
|
|
|
ETL_NODISCARD
|
|
static
|
|
ETL_CONSTEXPR14 T advance(T value, T min_value, T max_value, typename traits<T>::difference_type n) ETL_NOEXCEPT
|
|
{
|
|
if (n == 0)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
const unsigned_type current = etl::to_unsigned(value); // static_cast<unsigned_type>(value);
|
|
const unsigned_type step = etl::absolute_unsigned(n);
|
|
|
|
if ((n > 0) && (value < max_value))
|
|
{
|
|
const unsigned_type distance = etl::to_unsigned(max_value) - current; // static_cast<unsigned_type>(max_value) - current;
|
|
|
|
value = (step >= distance) ? max_value : static_cast<T>(current + step);
|
|
}
|
|
else if ((n < 0) && (value > min_value))
|
|
{
|
|
const unsigned_type distance = current - etl::to_unsigned(min_value); // static_cast<unsigned_type>(min_value);
|
|
|
|
value = (step >= distance) ? min_value : static_cast<T>(current - step);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
ETL_NODISCARD
|
|
static ETL_CONSTEXPR14 T subtract(T value, T min_value, T max_value, typename traits<T>::difference_type n) ETL_NOEXCEPT
|
|
{
|
|
if (n == traits<T>::difference_limits_type::lowest()) ETL_UNLIKELY
|
|
{
|
|
value = advance(value, min_value, max_value, traits<T>::difference_limits_type::max());
|
|
return advance(value, min_value, max_value, 1);
|
|
}
|
|
|
|
return advance(value, min_value, max_value, static_cast<typename traits<T>::difference_type>(-n));
|
|
}
|
|
};
|
|
|
|
#if ETL_HAS_FLOATING_POINT_CLAMPED_VALUE
|
|
//*************************************************************************
|
|
/// Saturating arithmetic policy for floating-point values.
|
|
//*************************************************************************
|
|
template <typename T>
|
|
struct arithmetic<T, false>
|
|
{
|
|
ETL_NODISCARD
|
|
static ETL_CONSTEXPR14 T advance(T value, T min_value, T max_value, T n) ETL_NOEXCEPT
|
|
{
|
|
if ((n > T(0)) && (value < max_value))
|
|
{
|
|
const T distance = max_value - value;
|
|
value = (n >= distance) ? max_value : static_cast<T>(value + n);
|
|
}
|
|
else if ((n < T(0)) && (value > min_value))
|
|
{
|
|
const T distance = value - min_value;
|
|
value = (-n >= distance) ? min_value : static_cast<T>(value + n);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
ETL_NODISCARD
|
|
static ETL_CONSTEXPR14 T subtract(T value, T min_value, T max_value, T n) ETL_NOEXCEPT
|
|
{
|
|
return advance(value, min_value, max_value, -n);
|
|
}
|
|
};
|
|
#endif
|
|
|
|
//*************************************************************************
|
|
/// Advances a value and saturates it at the supplied bounds.
|
|
///\param value The current value.
|
|
///\param min_value The minimum value.
|
|
///\param max_value The maximum value.
|
|
///\param n The number of steps.
|
|
///\return The advanced value.
|
|
//*************************************************************************
|
|
template <typename T>
|
|
ETL_NODISCARD ETL_CONSTEXPR14 T advance(T value, T min_value, T max_value, typename traits<T>::difference_type n) ETL_NOEXCEPT
|
|
{
|
|
return arithmetic<T>::advance(value, min_value, max_value, n);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Subtracts a value and saturates it at the supplied bounds.
|
|
/// Handles the lowest integral difference without signed overflow.
|
|
///\param value The current value.
|
|
///\param min_value The minimum value.
|
|
///\param max_value The maximum value.
|
|
///\param n The number of steps to subtract.
|
|
///\return The value after subtraction.
|
|
//*************************************************************************
|
|
template <typename T>
|
|
ETL_NODISCARD ETL_CONSTEXPR14 T subtract(T value, T min_value, T max_value, typename traits<T>::difference_type n) ETL_NOEXCEPT
|
|
{
|
|
return arithmetic<T>::subtract(value, min_value, max_value, n);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Verifies that a clamped value, bound, or difference is not NaN.
|
|
/// Integral values always pass validation.
|
|
///\param value The value to validate.
|
|
//*************************************************************************
|
|
template <typename T>
|
|
ETL_CONSTEXPR14 void validate(T value)
|
|
{
|
|
ETL_ASSERT(!etl::is_nan(value), ETL_ERROR_GENERIC("clamped_value: NaN is not supported"));
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Validates a value and its bounds before clamping.
|
|
///\param value The value to clamp.
|
|
///\param min_value The minimum permitted value.
|
|
///\param max_value The maximum permitted value.
|
|
///\return The value clamped to the supplied range.
|
|
//*************************************************************************
|
|
template <typename T>
|
|
ETL_NODISCARD ETL_CONSTEXPR14 T validated_clamp(T value, T min_value, T max_value)
|
|
{
|
|
validate(value);
|
|
validate(min_value);
|
|
validate(max_value);
|
|
ETL_ASSERT(min_value <= max_value, ETL_ERROR_GENERIC("clamped_value: invalid range"));
|
|
return etl::clamp(value, min_value, max_value);
|
|
}
|
|
} // namespace private_clamped_value
|
|
/// \endcond
|
|
|
|
#if ETL_USING_CPP11
|
|
template <typename T, T... Limits>
|
|
class clamped_value;
|
|
#else // ETL_NOT_USING_CPP11
|
|
#include "private/diagnostic_float_equal_push.h"
|
|
template <typename T, T Min = T(), T Max = T(), bool RuntimeSpecialisation = ((Min == T()) && (Max == T()))>
|
|
class clamped_value;
|
|
#include "private/diagnostic_pop.h"
|
|
#endif
|
|
|
|
//***************************************************************************
|
|
/// Provides a value that is clamped between two compile-time limits.
|
|
/// Supports incrementing, decrementing and arbitrary advance.
|
|
///@tparam T An integral type, or a floating-point type when
|
|
/// ETL_HAS_COMPILE_TIME_FLOATING_POINT_CLAMPED_VALUE is `1`.
|
|
///@tparam Min The minimum value of the range.
|
|
///@tparam Max The maximum value of the range.
|
|
///\ingroup clamped_value
|
|
//***************************************************************************
|
|
#if ETL_USING_CPP11
|
|
template <typename T, T Min, T Max>
|
|
class clamped_value<T, Min, Max>
|
|
#else // ETL_NOT_USING_CPP11
|
|
template <typename T, T Min, T Max>
|
|
class clamped_value<T, Min, Max, false>
|
|
#endif
|
|
{
|
|
public:
|
|
|
|
/// The type used to advance or subtract from the stored value.
|
|
typedef typename private_clamped_value::traits<T>::difference_type difference_type;
|
|
|
|
/// Numeric limits for the stored value type.
|
|
typedef typename private_clamped_value::traits<T>::limits_type limits_type;
|
|
|
|
/// Numeric limits for difference_type.
|
|
typedef typename private_clamped_value::traits<T>::difference_limits_type difference_limits_type;
|
|
|
|
/// \cond INTERNAL
|
|
ETL_STATIC_ASSERT(Min <= Max, "clamped_value minimum must not exceed maximum");
|
|
/// \endcond
|
|
|
|
//*************************************************************************
|
|
/// Default constructor.
|
|
/// The initial value is set to the minimum value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR clamped_value() ETL_NOEXCEPT
|
|
: value(Min)
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Constructor.
|
|
/// Set to an initial value.
|
|
/// Clamped to the range.
|
|
/// NaN is rejected for floating-point values.
|
|
///\param initial The initial value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 explicit clamped_value(T initial)
|
|
: value(private_clamped_value::validated_clamp(initial, Min, Max))
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Copy constructor.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR clamped_value(const clamped_value& other) ETL_NOEXCEPT
|
|
: value(other.value)
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Assignment operator.
|
|
///\param other The value to copy.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator=(const clamped_value& other) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
if (this == &other)
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
set(other.value);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Sets the value.
|
|
/// Clamps to the Min/Max range.
|
|
/// NaN is rejected for floating-point values.
|
|
///\param value_ The value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void set(T value_)
|
|
{
|
|
value = private_clamped_value::validated_clamp(value_, Min, Max);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Resets the value to the minimum in the range.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void to_min() ETL_NOEXCEPT
|
|
{
|
|
value = Min;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Resets the value to the maximum in the range.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void to_max() ETL_NOEXCEPT
|
|
{
|
|
value = Max;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Advances the value by a number of steps.
|
|
/// Saturates at the Min/Max range.
|
|
/// Floating-point steps may be fractional. NaN is rejected.
|
|
///\param n The number of steps.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void advance(difference_type n)
|
|
{
|
|
private_clamped_value::validate(n);
|
|
value = private_clamped_value::advance(value, Min, Max, n);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Conversion operator.
|
|
/// \return The value of the underlying type.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR14 operator T() const ETL_NOEXCEPT
|
|
{
|
|
return value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// ++ operator.
|
|
/// Advances by one.
|
|
/// Saturates at Max.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator++() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
value = private_clamped_value::advance(value, Min, Max, difference_type(1));
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// ++ operator.
|
|
/// Saturates at Max.
|
|
///\return The value before incrementing.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value operator++(int) ETL_NOEXCEPT
|
|
{
|
|
clamped_value temp(*this);
|
|
++(*this);
|
|
return temp;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// -- operator.
|
|
/// Subtracts one.
|
|
/// Saturates at Min.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator--() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
value = private_clamped_value::advance(value, Min, Max, difference_type(-1));
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// -- operator.
|
|
/// Saturates at Min.
|
|
///\return The value before decrementing.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value operator--(int) ETL_NOEXCEPT
|
|
{
|
|
clamped_value temp(*this);
|
|
--(*this);
|
|
return temp;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// = operator.
|
|
/// Clamps to the Min/Max range.
|
|
///\param value_ The value to assign.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator=(T value_) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
set(value_);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Adds a number of steps and clamps to the range.
|
|
/// Floating-point steps may be fractional. NaN is rejected.
|
|
///\param n The number of steps.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator+=(difference_type n) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
advance(n);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Subtracts a number of steps and clamps to the range.
|
|
/// Floating-point steps may be fractional. NaN is rejected.
|
|
///\param n The number of steps.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator-=(difference_type n) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
private_clamped_value::validate(n);
|
|
value = private_clamped_value::subtract(value, Min, Max, n);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the value.
|
|
///\return The current value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR T get() const ETL_NOEXCEPT
|
|
{
|
|
return value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the minimum value.
|
|
///\return The minimum value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR T min() const ETL_NOEXCEPT
|
|
{
|
|
return Min;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the maximum value.
|
|
///\return The maximum value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR T max() const ETL_NOEXCEPT
|
|
{
|
|
return Max;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Swaps the values.
|
|
///\param other The value to swap with.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void swap(clamped_value& other) ETL_NOEXCEPT
|
|
{
|
|
using ETL_OR_STD::swap;
|
|
swap(value, other.value);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Swaps the values.
|
|
///\param lhs The first value.
|
|
///\param rhs The second value.
|
|
//*************************************************************************
|
|
friend ETL_CONSTEXPR14 void swap(clamped_value& lhs, clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
lhs.swap(rhs);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Operator ==.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if the values are equal.
|
|
//*************************************************************************
|
|
friend ETL_CONSTEXPR bool operator==(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
#include "private/diagnostic_float_equal_push.h"
|
|
return lhs.value == rhs.value;
|
|
#include "private/diagnostic_pop.h"
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Operator !=.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if the values are not equal.
|
|
//*************************************************************************
|
|
friend ETL_CONSTEXPR bool operator!=(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Operator <.
|
|
///\param lhs The left-hand operand.
|
|
///\param rhs The right-hand operand.
|
|
///\return `true` if lhs is less than rhs.
|
|
/// @{
|
|
friend ETL_CONSTEXPR bool operator<(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return lhs.value < rhs.value;
|
|
}
|
|
|
|
/// @}
|
|
|
|
//*************************************************************************
|
|
/// Operator <=.
|
|
///\param lhs The left-hand operand.
|
|
///\param rhs The right-hand operand.
|
|
///\return `true` if lhs is less than or equal to rhs.
|
|
/// @{
|
|
friend ETL_CONSTEXPR bool operator<=(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(rhs < lhs);
|
|
}
|
|
|
|
/// @}
|
|
|
|
//*************************************************************************
|
|
/// Operator >.
|
|
///\param lhs The left-hand operand.
|
|
///\param rhs The right-hand operand.
|
|
///\return `true` if lhs is greater than rhs.
|
|
/// @{
|
|
friend ETL_CONSTEXPR bool operator>(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return rhs < lhs;
|
|
}
|
|
|
|
/// @}
|
|
|
|
//*************************************************************************
|
|
/// Operator >=.
|
|
///\param lhs The left-hand operand.
|
|
///\param rhs The right-hand operand.
|
|
///\return `true` if lhs is greater than or equal to rhs.
|
|
/// @{
|
|
friend ETL_CONSTEXPR bool operator>=(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(lhs < rhs);
|
|
}
|
|
|
|
/// @}
|
|
|
|
private:
|
|
|
|
T value;
|
|
};
|
|
|
|
//***************************************************************************
|
|
/// Provides a value that is clamped between two runtime limits.
|
|
/// Supports incrementing, decrementing and arbitrary advance.
|
|
///@tparam T An integral type, or a floating-point type when
|
|
/// ETL_HAS_FLOATING_POINT_CLAMPED_VALUE is `1`.
|
|
///@tparam Min Ignored for this specialisation.
|
|
///@tparam Max Ignored for this specialisation.
|
|
///\ingroup clamped_value
|
|
//***************************************************************************
|
|
#if ETL_USING_CPP11
|
|
template <typename T>
|
|
class clamped_value<T>
|
|
#else // ETL_NOT_USING_CPP11
|
|
template <typename T, T Min, T Max>
|
|
class clamped_value<T, Min, Max, true>
|
|
#endif
|
|
{
|
|
public:
|
|
|
|
/// The type used to advance or subtract from the stored value.
|
|
typedef typename private_clamped_value::traits<T>::difference_type difference_type;
|
|
|
|
/// Numeric limits for the stored value type.
|
|
typedef typename private_clamped_value::traits<T>::limits_type limits_type;
|
|
|
|
/// Numeric limits for difference_type.
|
|
typedef typename private_clamped_value::traits<T>::difference_limits_type difference_limits_type;
|
|
|
|
//*************************************************************************
|
|
/// Default constructor.
|
|
/// Sets the value to the minimum representable value of `T` and the
|
|
/// bounds to the full range of `T`.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR clamped_value() ETL_NOEXCEPT
|
|
: value(limits_type::lowest())
|
|
, min_value(limits_type::lowest())
|
|
, max_value(limits_type::max())
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Constructor.
|
|
/// Sets the value to the minimum of the range.
|
|
/// Reversed bounds and NaN bounds are rejected.
|
|
///\param min_ The minimum value.
|
|
///\param max_ The maximum value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value(T min_, T max_)
|
|
: value(min_)
|
|
, min_value(min_)
|
|
, max_value(max_)
|
|
{
|
|
private_clamped_value::validate(min_);
|
|
private_clamped_value::validate(max_);
|
|
ETL_ASSERT(min_ <= max_, ETL_ERROR_GENERIC("clamped_value: invalid range"));
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Constructor.
|
|
/// Set to an initial value.
|
|
/// Clamped to the range.
|
|
/// Reversed bounds and NaN values or bounds are rejected.
|
|
///\param min_ The minimum value.
|
|
///\param max_ The maximum value.
|
|
///\param initial The initial value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value(T min_, T max_, T initial)
|
|
: value(private_clamped_value::validated_clamp(initial, min_, max_))
|
|
, min_value(min_)
|
|
, max_value(max_)
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Copy constructor.
|
|
///\param other The value to copy.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR clamped_value(const clamped_value& other) ETL_NOEXCEPT
|
|
: value(other.value)
|
|
, min_value(other.min_value)
|
|
, max_value(other.max_value)
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Sets the range.
|
|
/// Sets the value to the minimum of the range.
|
|
/// Reversed bounds and NaN bounds are rejected.
|
|
///\param min_ The minimum value.
|
|
///\param max_ The maximum value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void set(T min_, T max_)
|
|
{
|
|
private_clamped_value::validate(min_);
|
|
private_clamped_value::validate(max_);
|
|
ETL_ASSERT(min_ <= max_, ETL_ERROR_GENERIC("clamped_value: invalid range"));
|
|
min_value = min_;
|
|
max_value = max_;
|
|
value = min_;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Sets the value.
|
|
/// Clamps to the runtime Min/Max range.
|
|
/// NaN is rejected for floating-point values.
|
|
///\param value_ The value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void set(T value_)
|
|
{
|
|
value = private_clamped_value::validated_clamp(value_, min_value, max_value);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Resets the value to the minimum in the range.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void to_min() ETL_NOEXCEPT
|
|
{
|
|
value = min_value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Resets the value to the maximum in the range.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void to_max() ETL_NOEXCEPT
|
|
{
|
|
value = max_value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Advances the value by a number of steps.
|
|
/// Saturates at the runtime Min/Max range.
|
|
/// Floating-point steps may be fractional. NaN is rejected.
|
|
///\param n The number of steps.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void advance(difference_type n)
|
|
{
|
|
private_clamped_value::validate(n);
|
|
value = private_clamped_value::advance(value, min_value, max_value, n);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Conversion operator.
|
|
/// \return The value of the underlying type.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR14 operator T() const ETL_NOEXCEPT
|
|
{
|
|
return value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// ++ operator.
|
|
/// Advances by one.
|
|
/// Saturates at the maximum.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator++() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
value = private_clamped_value::advance(value, min_value, max_value, difference_type(1));
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// ++ operator.
|
|
/// Saturates at the maximum.
|
|
///\return The value before incrementing.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value operator++(int) ETL_NOEXCEPT
|
|
{
|
|
clamped_value temp(*this);
|
|
++(*this);
|
|
return temp;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// -- operator.
|
|
/// Subtracts one.
|
|
/// Saturates at the minimum.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator--() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
value = private_clamped_value::advance(value, min_value, max_value, difference_type(-1));
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// -- operator.
|
|
/// Saturates at the minimum.
|
|
///\return The value before decrementing.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value operator--(int) ETL_NOEXCEPT
|
|
{
|
|
clamped_value temp(*this);
|
|
--(*this);
|
|
return temp;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// = operator.
|
|
/// Clamps to the runtime Min/Max range.
|
|
///\param value_ The value to assign.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator=(T value_) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
set(value_);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// = operator.
|
|
/// Copies the value and runtime bounds.
|
|
///\param other The value to copy.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator=(const clamped_value& other) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
if (this == &other)
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
value = other.value;
|
|
min_value = other.min_value;
|
|
max_value = other.max_value;
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Adds a number of steps and clamps to the range.
|
|
/// Floating-point steps may be fractional. NaN is rejected.
|
|
///\param n The number of steps.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator+=(difference_type n) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
advance(n);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Subtracts a number of steps and clamps to the range.
|
|
/// Floating-point steps may be fractional. NaN is rejected.
|
|
///\param n The number of steps.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value& operator-=(difference_type n) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
private_clamped_value::validate(n);
|
|
value = private_clamped_value::subtract(value, min_value, max_value, n);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the value.
|
|
///\return The current value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR T get() const ETL_NOEXCEPT
|
|
{
|
|
return value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the minimum value.
|
|
///\return The minimum value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR T min() const ETL_NOEXCEPT
|
|
{
|
|
return min_value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the maximum value.
|
|
///\return The maximum value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR T max() const ETL_NOEXCEPT
|
|
{
|
|
return max_value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Swaps the values and runtime bounds.
|
|
///\param other The value to swap with.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 void swap(clamped_value& other) ETL_NOEXCEPT
|
|
{
|
|
using ETL_OR_STD::swap;
|
|
swap(value, other.value);
|
|
swap(min_value, other.min_value);
|
|
swap(max_value, other.max_value);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Swaps the values and runtime bounds.
|
|
///\param lhs The first value.
|
|
///\param rhs The second value.
|
|
//*************************************************************************
|
|
friend ETL_CONSTEXPR14 void swap(clamped_value& lhs, clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
lhs.swap(rhs);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Operator ==.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if the values are equal.
|
|
//*************************************************************************
|
|
friend ETL_CONSTEXPR bool operator==(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
#include "private/diagnostic_float_equal_push.h"
|
|
return lhs.value == rhs.value;
|
|
#include "private/diagnostic_pop.h"
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Operator !=.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if the values differ.
|
|
//*************************************************************************
|
|
friend ETL_CONSTEXPR bool operator!=(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Operator <.
|
|
///\param lhs The left-hand operand.
|
|
///\param rhs The right-hand operand.
|
|
///\return `true` if lhs is less than rhs.
|
|
/// @{
|
|
friend ETL_CONSTEXPR bool operator<(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return lhs.value < rhs.value;
|
|
}
|
|
/// @}
|
|
|
|
//*************************************************************************
|
|
/// Operator <=.
|
|
///\param lhs The left-hand operand.
|
|
///\param rhs The right-hand operand.
|
|
///\return `true` if lhs is less than or equal to rhs.
|
|
/// @{
|
|
friend ETL_CONSTEXPR bool operator<=(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(rhs < lhs);
|
|
}
|
|
|
|
/// @}
|
|
|
|
//*************************************************************************
|
|
/// Operator >.
|
|
///\param lhs The left-hand operand.
|
|
///\param rhs The right-hand operand.
|
|
///\return `true` if lhs is greater than rhs.
|
|
/// @{
|
|
friend ETL_CONSTEXPR bool operator>(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return rhs < lhs;
|
|
}
|
|
|
|
/// @}
|
|
|
|
//*************************************************************************
|
|
/// Operator >=.
|
|
///\param lhs The left-hand operand.
|
|
///\param rhs The right-hand operand.
|
|
///\return `true` if lhs is greater than or equal to rhs.
|
|
/// @{
|
|
friend ETL_CONSTEXPR bool operator>=(const clamped_value& lhs, const clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(lhs < rhs);
|
|
}
|
|
|
|
/// @}
|
|
|
|
private:
|
|
|
|
T value;
|
|
T min_value;
|
|
T max_value;
|
|
};
|
|
|
|
#if ETL_USING_CPP11
|
|
//***************************************************************************
|
|
/// An immutable pair of runtime limits that may be shared by multiple
|
|
/// referenced_clamped_value objects.
|
|
///@tparam T An integral type, or a floating-point type when
|
|
/// ETL_HAS_FLOATING_POINT_CLAMPED_VALUE is `1`.
|
|
///\ingroup clamped_value
|
|
//***************************************************************************
|
|
template <typename T>
|
|
class clamped_value_range
|
|
{
|
|
public:
|
|
|
|
typedef typename private_clamped_value::traits<T>::limits_type limits_type;
|
|
|
|
//*************************************************************************
|
|
/// Constructs the full representable range of T.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value_range()
|
|
: min_value(limits_type::lowest())
|
|
, max_value(limits_type::max())
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Constructs a range with the supplied limits.
|
|
/// Reversed bounds and NaN bounds are rejected.
|
|
///\param min_ The minimum value.
|
|
///\param max_ The maximum value.
|
|
//*************************************************************************
|
|
ETL_CONSTEXPR14 clamped_value_range(T min_, T max_)
|
|
: min_value(min_)
|
|
, max_value(max_)
|
|
{
|
|
private_clamped_value::validate(min_);
|
|
private_clamped_value::validate(max_);
|
|
ETL_ASSERT(min_ <= max_, ETL_ERROR_GENERIC("clamped_value_range: invalid range"));
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the minimum value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR T min() const ETL_NOEXCEPT
|
|
{
|
|
return min_value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the maximum value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD ETL_CONSTEXPR T max() const ETL_NOEXCEPT
|
|
{
|
|
return max_value;
|
|
}
|
|
|
|
private:
|
|
|
|
const T min_value;
|
|
const T max_value;
|
|
};
|
|
|
|
//***************************************************************************
|
|
/// Provides a value clamped to a shared immutable runtime range.
|
|
/// The referenced range must outlive this object.
|
|
///@tparam T An integral type, or a floating-point type when
|
|
/// ETL_HAS_FLOATING_POINT_CLAMPED_VALUE is `1`.
|
|
///\ingroup clamped_value
|
|
//***************************************************************************
|
|
template <typename T>
|
|
class referenced_clamped_value
|
|
{
|
|
public:
|
|
|
|
/// The referenced range type.
|
|
typedef clamped_value_range<T> range_type;
|
|
|
|
/// The type used to advance or subtract from the stored value.
|
|
typedef typename private_clamped_value::traits<T>::difference_type difference_type;
|
|
|
|
/// Numeric limits for the stored value type.
|
|
typedef typename private_clamped_value::traits<T>::limits_type limits_type;
|
|
|
|
/// Numeric limits for difference_type.
|
|
typedef typename private_clamped_value::traits<T>::difference_limits_type difference_limits_type;
|
|
|
|
//*************************************************************************
|
|
/// Constructs a value initialized to the minimum of the referenced range.
|
|
///\param range_ The range to reference. It must outlive this object.
|
|
//*************************************************************************
|
|
explicit referenced_clamped_value(const range_type& range_)
|
|
: value(range_.min())
|
|
, value_range(etl::cref(range_))
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Constructs a value clamped to the referenced range.
|
|
///\param range_ The range to reference. It must outlive this object.
|
|
///\param initial The initial value.
|
|
//*************************************************************************
|
|
referenced_clamped_value(const range_type& range_, T initial)
|
|
: value(private_clamped_value::validated_clamp(initial, range_.min(), range_.max()))
|
|
, value_range(etl::cref(range_))
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Prevents construction with a temporary range.
|
|
//*************************************************************************
|
|
referenced_clamped_value(range_type&&) = delete;
|
|
referenced_clamped_value(range_type&&, T) = delete;
|
|
|
|
//*************************************************************************
|
|
/// Copies the value and its range reference.
|
|
///\param other The value to copy.
|
|
//*************************************************************************
|
|
referenced_clamped_value(const referenced_clamped_value& other) ETL_NOEXCEPT
|
|
: value(other.value)
|
|
, value_range(other.value_range)
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Copy assignment. Copies the value and its range reference.
|
|
///\param other The value and range reference to copy.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
referenced_clamped_value& operator=(const referenced_clamped_value& other) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
if (this != &other)
|
|
{
|
|
value = other.value;
|
|
value_range = other.value_range;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Sets the value and clamps it to the referenced range.
|
|
///\param value_ The value to assign.
|
|
//*************************************************************************
|
|
void set(T value_)
|
|
{
|
|
value = private_clamped_value::validated_clamp(value_, min(), max());
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Resets the value to the minimum of the referenced range.
|
|
//*************************************************************************
|
|
void to_min() ETL_NOEXCEPT
|
|
{
|
|
value = min();
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Resets the value to the maximum of the referenced range.
|
|
//*************************************************************************
|
|
void to_max() ETL_NOEXCEPT
|
|
{
|
|
value = max();
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Advances the value and saturates it at the referenced bounds.
|
|
///\param n The difference to add.
|
|
//*************************************************************************
|
|
void advance(difference_type n)
|
|
{
|
|
private_clamped_value::validate(n);
|
|
value = private_clamped_value::advance(value, min(), max(), n);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Converts to the underlying value type.
|
|
///\return The current value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD operator T() const ETL_NOEXCEPT
|
|
{
|
|
return value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Advances by one and saturates at the maximum.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
referenced_clamped_value& operator++() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
value = private_clamped_value::advance(value, min(), max(), difference_type(1));
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Advances by one and returns the previous value.
|
|
///\return The value before incrementing.
|
|
//*************************************************************************
|
|
referenced_clamped_value operator++(int) ETL_NOEXCEPT
|
|
{
|
|
referenced_clamped_value temp(*this);
|
|
++(*this);
|
|
return temp;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Subtracts one and saturates at the minimum.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
referenced_clamped_value& operator--() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
|
{
|
|
value = private_clamped_value::advance(value, min(), max(), difference_type(-1));
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Subtracts one and returns the previous value.
|
|
///\return The value before decrementing.
|
|
//*************************************************************************
|
|
referenced_clamped_value operator--(int) ETL_NOEXCEPT
|
|
{
|
|
referenced_clamped_value temp(*this);
|
|
--(*this);
|
|
return temp;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Assigns a value and clamps it to the referenced range.
|
|
///\param value_ The value to assign.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
referenced_clamped_value& operator=(T value_) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
set(value_);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Adds a difference and clamps to the referenced range.
|
|
///\param n The difference to add.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
referenced_clamped_value& operator+=(difference_type n) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
advance(n);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Subtracts a difference and clamps to the referenced range.
|
|
///\param n The difference to subtract.
|
|
///\return A reference to this value.
|
|
//*************************************************************************
|
|
referenced_clamped_value& operator-=(difference_type n) ETL_LVALUE_REF_QUALIFIER
|
|
{
|
|
private_clamped_value::validate(n);
|
|
value = private_clamped_value::subtract(value, min(), max(), n);
|
|
return *this;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the current value.
|
|
///\return The current value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD
|
|
T get() const ETL_NOEXCEPT
|
|
{
|
|
return value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the minimum of the referenced range.
|
|
///\return The minimum value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD
|
|
T min() const ETL_NOEXCEPT
|
|
{
|
|
return value_range.get().min();
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the maximum of the referenced range.
|
|
///\return The maximum value.
|
|
//*************************************************************************
|
|
ETL_NODISCARD
|
|
T max() const ETL_NOEXCEPT
|
|
{
|
|
return value_range.get().max();
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Gets the referenced range.
|
|
///\return The referenced range.
|
|
//*************************************************************************
|
|
ETL_NODISCARD
|
|
const range_type& range() const ETL_NOEXCEPT
|
|
{
|
|
return value_range.get();
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Swaps the values and range references.
|
|
///\param other The value to swap with.
|
|
//*************************************************************************
|
|
void swap(referenced_clamped_value& other) ETL_NOEXCEPT
|
|
{
|
|
using ETL_OR_STD::swap;
|
|
swap(value, other.value);
|
|
swap(value_range, other.value_range);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Swaps the values and range references.
|
|
///\param lhs The first value.
|
|
///\param rhs The second value.
|
|
//*************************************************************************
|
|
friend void swap(referenced_clamped_value& lhs, referenced_clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
lhs.swap(rhs);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Compares current values for equality.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if the current values are equal.
|
|
//*************************************************************************
|
|
friend bool operator==(const referenced_clamped_value& lhs, const referenced_clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
#include "private/diagnostic_float_equal_push.h"
|
|
return lhs.value == rhs.value;
|
|
#include "private/diagnostic_pop.h"
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Compares current values for inequality.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if the current values differ.
|
|
//*************************************************************************
|
|
friend bool operator!=(const referenced_clamped_value& lhs, const referenced_clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Compares current values using less-than.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if lhs is less than rhs.
|
|
//*************************************************************************
|
|
friend bool operator<(const referenced_clamped_value& lhs, const referenced_clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return lhs.value < rhs.value;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Compares current values using less-than-or-equal.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if lhs is less than or equal to rhs.
|
|
//*************************************************************************
|
|
friend bool operator<=(const referenced_clamped_value& lhs, const referenced_clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(rhs < lhs);
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Compares current values using greater-than.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if lhs is greater than rhs.
|
|
//*************************************************************************
|
|
friend bool operator>(const referenced_clamped_value& lhs, const referenced_clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return rhs < lhs;
|
|
}
|
|
|
|
//*************************************************************************
|
|
/// Compares current values using greater-than-or-equal.
|
|
///\param lhs The left-hand value.
|
|
///\param rhs The right-hand value.
|
|
///\return `true` if lhs is greater than or equal to rhs.
|
|
//*************************************************************************
|
|
friend bool operator>=(const referenced_clamped_value& lhs, const referenced_clamped_value& rhs) ETL_NOEXCEPT
|
|
{
|
|
return !(lhs < rhs);
|
|
}
|
|
|
|
private:
|
|
|
|
T value;
|
|
etl::reference_wrapper<const range_type> value_range;
|
|
};
|
|
#endif
|
|
} // namespace etl
|
|
|
|
#endif
|