Added runtime ans static asserts for reverse ordered limts.

This commit is contained in:
John Wellbelove 2026-09-20 08:37:08 +01:00
parent 7931d2d918
commit 435b705c90
4 changed files with 43 additions and 6 deletions

View File

@ -15,6 +15,7 @@ Supports compile time and runtime variants.
template <typename T, const T First = 0, const T Last = 0>
class cyclic_value
```
Static asserts if `Last` < `First`.
**Example**
@ -38,18 +39,20 @@ Constructs a cyclic value of type `T` with an initial value of `first`.
---
```cpp
cyclic_value<T>(T first, T last) noexcept;
cyclic_value<T>(T first, T last);
```
Constructs a *run time* cyclic value of type `T` with limits of `first` and `fast` and an initial value of `first`.
Asserts an `etl::cyclic_value_reversed_limits` if `last` < `first`.
`constexpr` from C++11.
---
```cpp
cyclic_value<T>(T first, T last, T initial) noexcept;
cyclic_value<T>(T first, T last, T initial);
```
Constructs a cyclic value of type `T` with limits of `first` and `fast` and an initial value of `initial`.
`initial` will be clamped to be in the range `(first, last)`.
Asserts an `etl::cyclic_value_reversed_limits` if `last` < `first`.
`constexpr` from C++11.
### Compile time limits
@ -144,6 +147,7 @@ Gets the last value.
void set(T first, T last) noexcept;
```
Sets the new *run time* `first` and `last` values. Sets the current value to `first`.
Asserts an `etl::cyclic_value_reversed_limits` if `last` < `first`.
`constexpr` from C++14.
---

View File

@ -155,6 +155,22 @@ namespace etl
}
} // namespace private_cyclic_value
struct cyclic_value_exception : etl::exception
{
cyclic_value_exception(string_type reason_, string_type file_, numeric_type line_)
: etl::exception(reason_, file_, line_)
{
}
};
struct cyclic_value_reversed_limits : cyclic_value_exception
{
cyclic_value_reversed_limits(string_type file_, numeric_type line_)
: cyclic_value_exception(ETL_ERROR_TEXT("cyclic_value_exception:reversed limits", ETL_CYCLIC_VALUE_FILE_ID"A"), file_, line_)
{
}
};
//***************************************************************************
/// Provides a value that cycles between two limits.
//***************************************************************************
@ -179,6 +195,7 @@ namespace etl
public:
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "T must be an integral type");
ETL_STATIC_ASSERT(First <= Last, "First is not <= Last");
//*************************************************************************
/// Default constructor.
@ -431,7 +448,7 @@ namespace etl
//*************************************************************************
/// Constructor.
/// Sets 'first' and 'last' to the template parameter values.
/// Sets 'first' and 'last' to the template parameter values which will be zero.
/// The initial value is set to the first value.
//*************************************************************************
ETL_CONSTEXPR cyclic_value() ETL_NOEXCEPT
@ -447,11 +464,12 @@ namespace etl
///\param first The first value in the range.
///\param last The last value in the range.
//*************************************************************************
ETL_CONSTEXPR cyclic_value(T first_, T last_) ETL_NOEXCEPT
ETL_CONSTEXPR14 cyclic_value(T first_, T last_)
: value(first_)
, first_value(first_)
, last_value(last_)
{
ETL_ASSERT(first_ <= last_, ETL_ERROR(cyclic_value_reversed_limits));
}
//*************************************************************************
@ -461,11 +479,12 @@ namespace etl
///\param first The first value in the range.
///\param last The last value in the range.
//*************************************************************************
ETL_CONSTEXPR cyclic_value(T first_, T last_, T initial) ETL_NOEXCEPT
ETL_CONSTEXPR14 cyclic_value(T first_, T last_, T initial)
: value(etl::clamp(initial, first_, last_))
, first_value(first_)
, last_value(last_)
{
ETL_ASSERT(first_ <= last_, ETL_ERROR(cyclic_value_reversed_limits));
}
//*************************************************************************
@ -484,8 +503,10 @@ namespace etl
///\param first The first value in the range.
///\param last The last value in the range.
//*************************************************************************
ETL_CONSTEXPR14 void set(T first_, T last_) ETL_NOEXCEPT
ETL_CONSTEXPR14 void set(T first_, T last_)
{
ETL_ASSERT(first_ <= last_, ETL_ERROR(cyclic_value_reversed_limits));
first_value = first_;
last_value = last_;
value = first_;

View File

@ -112,4 +112,5 @@ SOFTWARE.
#define ETL_FORMAT_FILE_ID "79"
#define ETL_INPLACE_FUNCTION_FILE_ID "80"
#define ETL_INTRUSIVE_AVL_TREE_FILE_ID "81"
#define ETL_CYCLIC_VALUE_FILE_ID "82"
#endif

View File

@ -56,6 +56,15 @@ namespace
CHECK_EQUAL(7, value.last());
}
//*************************************************************************
TEST(test_reversed_run_time_initialisation)
{
etl::cyclic_value<int> value(1, 2);
CHECK_THROW(etl::cyclic_value<int>(7, 2), etl::cyclic_value_reversed_limits);
CHECK_THROW(value.set(7, 2), etl::cyclic_value_reversed_limits);
}
//*************************************************************************
TEST(test_copy_constructor_compile_time)
{
@ -707,6 +716,7 @@ namespace
CHECK(true);
}
#if ETL_USING_CPP14
//*************************************************************************
TEST(test_cyclic_value_constexpr_ctor_with_range)
{
@ -715,6 +725,7 @@ namespace
static_assert(cv.last() == 9, "constexpr range ctor last");
CHECK(true);
}
#endif
//*************************************************************************
TEST(test_cyclic_value_constexpr_copy_ctor)