mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Merge branch 'development' into feature/update-builtin-detection-and-etl-traits
This commit is contained in:
commit
2b3148a598
@ -28,7 +28,7 @@
|
||||

|
||||

|
||||
|
||||
[](https://www.codacy.com/manual/jwellbelove/etl?utm_source=github.com&utm_medium=referral&utm_content=ETLCPP/etl&utm_campaign=Badge_Grade)
|
||||
[](https://app.codacy.com/gh/ETLCPP/etl/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
||||
|
||||
[](https://github.com/sponsors/ETLCPP)
|
||||
|
||||
|
||||
@ -118,9 +118,9 @@ CRC calculations (8, 16, 32 & 64-bit)
|
||||
Checksums and hash functions
|
||||
- Variants (type-safe unions)
|
||||
- Extensive template support utilities
|
||||
- Robust Error Handling: Configurable error checking using asserts, exceptions, error handlers, or no checks; user’s choice.
|
||||
- Robust Error Handling: Configurable error checking using asserts, exceptions, error handlers, or no checks; user's choice.
|
||||
- Thoroughly Tested:
|
||||
Over 10,000 unit tests
|
||||
Over **14,000** tests
|
||||
Tested with Visual Studio 2022, GCC 12, and Clang 14
|
||||
Continuous integration via GitHub Actions.
|
||||
- Readable and Well-Documented: Clean, maintainable source code with clear documentation.
|
||||
@ -128,6 +128,7 @@ Continuous integration via GitHub Actions.
|
||||
- Archived: A snapshot of the ETL is preserved in the Arctic Code Vault for long-term digital preservation.
|
||||
|
||||
## Support the ETL
|
||||
|
||||
Maintaining the ETL can take a lot of man-hours of work, but unfortunately it doesn't pay the bills. When I have to take on paying work, the ETL gets a lot less attention. So if you have found the library is an important component in your work and you would like to help out, then please consider by supporting the project.
|
||||
|
||||
---
|
||||
|
||||
@ -15,6 +15,9 @@ 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**
|
||||
|
||||
```cpp
|
||||
etl::cyclic_value<int, 2, 7> value_ct; // Compile time. Fixed range of 2 to 7 inclusive.
|
||||
@ -24,126 +27,183 @@ value_rt.set(3, 8);
|
||||
```
|
||||
|
||||
## Constructor
|
||||
|
||||
### Run time limits
|
||||
|
||||
```cpp
|
||||
cyclic_value<int> value;
|
||||
cyclic_value<T>() noexcept;
|
||||
```
|
||||
Creates a runtime cyclic value of type int with default constructed initial defined limits.
|
||||
Constructs a cyclic value of type `T` with an initial value of `first`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
cyclic_value<int, N, M> value;
|
||||
cyclic_value<T>(T first, T last);
|
||||
```
|
||||
Creates a compile time cyclic value of type int with fixed limits of N and M.
|
||||
Constructs a *run time* cyclic value of type `T` with limits of `first` and `last` and an initial value of `first`.
|
||||
Asserts an `etl::cyclic_value_reversed_limits` if `last` < `first`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
**Example**
|
||||
```cpp
|
||||
cyclic_value<int> value(N, M);
|
||||
cyclic_value<T>(T first, T last, T initial);
|
||||
```
|
||||
Creates a runtime cyclic value of type int with initial defined limits of N and M.
|
||||
Constructs a cyclic value of type `T` with limits of `first` and `last` 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
|
||||
|
||||
```cpp
|
||||
cyclic_value<T, First, Last>() noexcept;
|
||||
```
|
||||
Constructs a cyclic value of type `T` default constructed with an initial value of `First`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
cyclic_value<T, First, Last>(T initial) noexcept;
|
||||
```
|
||||
Constructs a cyclic value of type `T` constructed with an `initial`.
|
||||
`initial` will be clamped to be in the range `(First, Last)`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
## Modifiers
|
||||
|
||||
```cpp
|
||||
cyclic_value& operator ++();
|
||||
cyclic_value& operator ++(int);
|
||||
cyclic_value& operator ++() noexcept;
|
||||
cyclic_value& operator ++(int) noexcept;
|
||||
```
|
||||
Increments the value. If the value is at the last value then is set to the first.
|
||||
Increments the value. If the value is at the last value then is set to the first.
|
||||
`constexpr` from C++14.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
cyclic_value& operator --();
|
||||
cyclic_value& operator --(int);
|
||||
cyclic_value& operator --() noexcept;
|
||||
cyclic_value& operator --(int) noexcept;
|
||||
```
|
||||
Decrements the value. If the value is at the first value then is set to the last.
|
||||
Decrements the value. If the value is at the first value then is set to the last.
|
||||
`constexpr` from C++14.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void advance(int n);
|
||||
template <typename TStep>
|
||||
void advance(TStep n) noexcept;
|
||||
```
|
||||
Advances the value by the specified amount, wrapping if necessary.
|
||||
Advances the value by the specified amount, wrapping if necessary.
|
||||
`constexpr` from C++14.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename TStep>
|
||||
cyclic_value& operator +=(TStep n) noexcept;
|
||||
```
|
||||
Advances the value by the specified amount, wrapping if necessary.
|
||||
`constexpr` from C++14.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename TStep>
|
||||
cyclic_value& operator -=(TStep n) noexcept;
|
||||
```
|
||||
Decrements the value by the specified amount, wrapping if necessary.
|
||||
`constexpr` from C++14.
|
||||
|
||||
## Access
|
||||
|
||||
```cpp
|
||||
T get() const;
|
||||
```
|
||||
Gets the current value
|
||||
Gets the current value.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
T first() const;
|
||||
T first() const noexcept;
|
||||
```
|
||||
Sets the current value to the first value
|
||||
Gets the first value.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
T last() const;
|
||||
T last() const noexcept;
|
||||
```
|
||||
Sets the current value to the last value
|
||||
Gets the last value.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void set(T first, T last);
|
||||
void set(T first, T last) noexcept;
|
||||
```
|
||||
Sets the new first and last values. Sets the current value to first.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void set(T value);
|
||||
void set(T value) noexcept;
|
||||
```
|
||||
Sets the current value.
|
||||
Sets the current value.
|
||||
`constexpr` from C++14.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void to_first();
|
||||
void to_first() noexcept;
|
||||
```
|
||||
Sets the current value to the first value
|
||||
Sets the current value to the first value.
|
||||
`constexpr` from C++14.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void to_last();
|
||||
void to_last() noexcept;
|
||||
```
|
||||
Sets the current value to the last value
|
||||
Sets the current value to the last value.
|
||||
`constexpr` from C++14.
|
||||
|
||||
## Operations
|
||||
|
||||
```cpp
|
||||
void swap(cyclic_value<T, FIRST, LAST>& other);
|
||||
void swap(cyclic_value<T, FIRST, LAST>& other) noexcept;
|
||||
```
|
||||
Swaps with another cyclic value.
|
||||
Swaps with another cyclic value.
|
||||
`constexpr` from C++14.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void swap(cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs);
|
||||
```
|
||||
Swaps with another cyclic value.
|
||||
|
||||
## Operators
|
||||
|
||||
```cpp
|
||||
operator T();
|
||||
operator const T() const;
|
||||
operator T() noexcept;
|
||||
operator const T() const noexcept;
|
||||
```
|
||||
Conversion operators to `T`.
|
||||
Conversion operators to `T`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
cyclic_value& operator =(T t);
|
||||
cyclic_value& operator =(T t) noexcept;
|
||||
```
|
||||
Sets the current value to `t`.
|
||||
Sets the current value to `t`.
|
||||
`constexpr` from C++14.
|
||||
|
||||
## Non-member functions
|
||||
```cpp
|
||||
template <typename T, const T FIRST, const T LAST>
|
||||
void swap(cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs)
|
||||
void swap(cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs) noexcept
|
||||
```
|
||||
Swaps two cyclic values.
|
||||
|
||||
@ -151,14 +211,63 @@ Swaps two cyclic values.
|
||||
|
||||
```cpp
|
||||
template <typename T, const T FIRST, const T LAST>
|
||||
bool operator == (cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs)
|
||||
bool operator == (cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs) noexcept
|
||||
```
|
||||
Checks equality of two cyclic values.
|
||||
Checks equality of two cyclic values.
|
||||
`constexpr` from C++11.
|
||||
|
||||
{{< callout type="warning">}}
|
||||
After version `20.49.0` equality is judged only by the current value.
|
||||
Previously the first and last limits were also considered.
|
||||
|
||||
<= 20.49.0
|
||||
`etl::cyclic_value<2, 7>(3) != etl::cyclic_value<2, 6>(3)`
|
||||
|
||||
> 20.49.0
|
||||
`etl::cyclic_value<2, 7>(3) == etl::cyclic_value<2, 6>(3)`
|
||||
{{< /callout >}}
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename T, const T FIRST, const T LAST>
|
||||
bool operator != (cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs)
|
||||
bool operator != (cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs) noexcept
|
||||
```
|
||||
Checks inequality of two cyclic values.
|
||||
Checks inequality of two cyclic values.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename T, const T FIRST, const T LAST>
|
||||
bool operator < (cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs) noexcept
|
||||
```
|
||||
Checks if the current value of `lhs` is less than the current value of `rhs`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename T, const T FIRST, const T LAST>
|
||||
bool operator <= (cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs) noexcept
|
||||
```
|
||||
Checks if the current value of `lhs` is less than or equal the current value of `rhs`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename T, const T FIRST, const T LAST>
|
||||
bool operator > (cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs) noexcept
|
||||
```
|
||||
Checks if the current value of `lhs` is greater than the current value of `rhs`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename T, const T FIRST, const T LAST>
|
||||
bool operator >= (cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs) noexcept
|
||||
```
|
||||
Checks if the current value of `lhs` is greater than or equal the current value of `rhs`.
|
||||
`constexpr` from C++11.
|
||||
|
||||
@ -38,10 +38,198 @@ SOFTWARE.
|
||||
#include "platform.h"
|
||||
#include "algorithm.h"
|
||||
#include "exception.h"
|
||||
#include "integral_limits.h"
|
||||
#include "largest.h"
|
||||
#include "negative.h"
|
||||
#include "static_assert.h"
|
||||
#include "type_traits.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
namespace private_cyclic_value
|
||||
{
|
||||
template <typename T>
|
||||
struct traits
|
||||
{
|
||||
typedef typename etl::make_unsigned<T>::type unsigned_type;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Increments a value and wraps it at the supplied limits.
|
||||
///\param value The current value.
|
||||
///\param min_value The minimum value.
|
||||
///\param max_value The maximum value.
|
||||
///\return The new value.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 T increment(T value, T min_value, T max_value) ETL_NOEXCEPT
|
||||
{
|
||||
return value == max_value ? min_value : static_cast<T>(etl::to_unsigned(value) + 1U);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Decrements a value and wraps it at the supplied limits.
|
||||
///\param value The current value.
|
||||
///\param min_value The minimum value.
|
||||
///\param max_value The maximum value.
|
||||
///\return The new value.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 T decrement(T value, T min_value, T max_value) ETL_NOEXCEPT
|
||||
{
|
||||
return value == min_value ? max_value : static_cast<T>(etl::to_unsigned(value) - 1U);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Advances a value and wraps it at the supplied limits.
|
||||
/// Called for the case where the range is not the full width of the type.
|
||||
///\param value The current value.
|
||||
///\param min_value The minimum value.
|
||||
///\param max_value The maximum value.
|
||||
///\param step The number of steps.
|
||||
///\param subtract True if the value is to be decremented, false if it is to be incremented.
|
||||
///\return The advanced value.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 T advance(T value, T min_value, T max_value, typename traits<T>::unsigned_type step, bool subtract) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename traits<T>::unsigned_type unsigned_type;
|
||||
|
||||
switch (step)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
return subtract ? decrement(value, min_value, max_value) : increment(value, min_value, max_value);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (subtract)
|
||||
{
|
||||
unsigned_type distance_to_first = static_cast<unsigned_type>(etl::to_unsigned(value) - etl::to_unsigned(min_value));
|
||||
|
||||
if (step <= distance_to_first)
|
||||
{
|
||||
// Room to subtract the step.
|
||||
value = static_cast<T>(etl::to_unsigned(value) - step);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Step would roll over.
|
||||
step -= distance_to_first + 1U;
|
||||
value = static_cast<T>(etl::to_unsigned(max_value) - step);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned_type distance_to_last = static_cast<unsigned_type>(etl::to_unsigned(max_value) - etl::to_unsigned(value));
|
||||
|
||||
if (step <= distance_to_last)
|
||||
{
|
||||
// Room to add the step.
|
||||
value = static_cast<T>(etl::to_unsigned(value) + step);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Step would roll over.
|
||||
step -= distance_to_last + 1U;
|
||||
value = static_cast<T>(etl::to_unsigned(min_value) + step);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Advances a value and wraps it at the supplied limits.
|
||||
/// Called for the case where the range is the full width of the type.
|
||||
///\param value The current value.
|
||||
///\param step The number of steps.
|
||||
///\param subtract True if the value is to be decremented, false if it is to be incremented.
|
||||
///\return The advanced value.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 T advance(T value, typename traits<T>::unsigned_type step, bool subtract) ETL_NOEXCEPT
|
||||
{
|
||||
if (subtract)
|
||||
{
|
||||
value = static_cast<T>(etl::to_unsigned(value) - step);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = static_cast<T>(etl::to_unsigned(value) + step);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Provides information about a range.
|
||||
// Ensures that Last - First + 1 is only calculated for when the range is not the full width of the type, to avoid overflow errors.
|
||||
//*************************************************************************
|
||||
template <typename T, T First, T Last, bool Full_Range = ((First == etl::integral_limits<T>::min) && (Last == etl::integral_limits<T>::max))>
|
||||
struct range_traits;
|
||||
|
||||
//*************************************************************************
|
||||
// Specialisation for when the range is the full width of the type.
|
||||
template <typename T, T First, T Last>
|
||||
struct range_traits<T, First, Last, true>
|
||||
{
|
||||
typedef typename traits<T>::unsigned_type unsigned_type;
|
||||
|
||||
static const bool is_full_range = true;
|
||||
static const unsigned_type value = 0; // Unused, but required for template specialisation.
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Specialisation for when the range is not the full width of the type.
|
||||
template <typename T, T First, T Last>
|
||||
struct range_traits<T, First, Last, false>
|
||||
{
|
||||
typedef typename traits<T>::unsigned_type unsigned_type;
|
||||
|
||||
static const bool is_full_range = false;
|
||||
static const unsigned_type value = static_cast<unsigned_type>(static_cast<unsigned_type>(Last) - static_cast<unsigned_type>(First)) + 1U;
|
||||
};
|
||||
|
||||
// Out-of-class definitions (required pre-C++17 for ODR-use of static const members).
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTANT bool range_traits<T, First, Last, true>::is_full_range;
|
||||
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTANT typename range_traits<T, First, Last, true>::unsigned_type range_traits<T, First, Last, true>::value;
|
||||
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTANT bool range_traits<T, First, Last, false>::is_full_range;
|
||||
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTANT typename range_traits<T, First, Last, false>::unsigned_type range_traits<T, First, Last, false>::value;
|
||||
|
||||
} // 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.
|
||||
//***************************************************************************
|
||||
@ -59,13 +247,20 @@ namespace etl
|
||||
template <typename T, T First, T Last>
|
||||
class cyclic_value<T, First, Last, false>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename private_cyclic_value::traits<T>::unsigned_type unsigned_type;
|
||||
|
||||
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.
|
||||
/// The initial value is set to the first value.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR cyclic_value()
|
||||
ETL_CONSTEXPR cyclic_value() ETL_NOEXCEPT
|
||||
: value(First)
|
||||
{
|
||||
}
|
||||
@ -75,15 +270,15 @@ namespace etl
|
||||
/// Set to an initial value.
|
||||
/// Clamped to the range.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 explicit cyclic_value(T initial)
|
||||
ETL_CONSTEXPR explicit cyclic_value(T initial) ETL_NOEXCEPT
|
||||
: value(etl::clamp(initial, First, Last))
|
||||
{
|
||||
set(initial);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Copy constructor.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR cyclic_value(const cyclic_value<T, First, Last>& other)
|
||||
ETL_CONSTEXPR cyclic_value(const cyclic_value<T, First, Last>& other) ETL_NOEXCEPT
|
||||
: value(other.value)
|
||||
{
|
||||
}
|
||||
@ -91,19 +286,48 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(const cyclic_value<T, First, Last>& other)
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(const cyclic_value<T, First, Last>& other) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
value = other.value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a number of steps and clamps to the range.
|
||||
///\param n The number of steps.
|
||||
///\return A reference to this value.
|
||||
//*************************************************************************
|
||||
template <typename TStep>
|
||||
ETL_CONSTEXPR14 cyclic_value& operator+=(TStep n) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<TStep>::value, "TStep must be an integral type");
|
||||
|
||||
advance(n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Subtracts a number of steps and clamps to the range.
|
||||
///\param n The number of steps.
|
||||
///\return A reference to this value.
|
||||
//*************************************************************************
|
||||
template <typename TStep>
|
||||
ETL_CONSTEXPR14 cyclic_value& operator-=(TStep n) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<TStep>::value, "TStep must be an integral type");
|
||||
|
||||
do_advance(n, !etl::is_negative(n));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Sets the value.
|
||||
/// Truncates to the First/Last range.
|
||||
///\param value The value.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void set(T value_)
|
||||
ETL_CONSTEXPR14 void set(T value_) ETL_NOEXCEPT
|
||||
{
|
||||
value = etl::clamp(value_, First, Last);
|
||||
}
|
||||
@ -111,7 +335,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Resets the value to the first in the range.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void to_first()
|
||||
ETL_CONSTEXPR14 void to_first() ETL_NOEXCEPT
|
||||
{
|
||||
value = First;
|
||||
}
|
||||
@ -119,7 +343,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Resets the value to the last in the range.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void to_last()
|
||||
ETL_CONSTEXPR14 void to_last() ETL_NOEXCEPT
|
||||
{
|
||||
value = Last;
|
||||
}
|
||||
@ -128,30 +352,13 @@ namespace etl
|
||||
/// Advances to value by a number of steps.
|
||||
///\param n The number of steps to advance.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void advance(int n)
|
||||
template <typename TStep>
|
||||
ETL_CONSTEXPR14 T advance(TStep n) ETL_NOEXCEPT
|
||||
{
|
||||
if (n > 0)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
operator++();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < -n; ++i)
|
||||
{
|
||||
operator--();
|
||||
}
|
||||
}
|
||||
}
|
||||
ETL_STATIC_ASSERT(etl::is_integral<TStep>::value, "TStep must be an integral type");
|
||||
|
||||
do_advance(n, etl::is_negative(n));
|
||||
|
||||
//*************************************************************************
|
||||
/// Conversion operator.
|
||||
/// \return The value of the underlying type.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 operator T()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -159,7 +366,7 @@ namespace etl
|
||||
/// Const conversion operator.
|
||||
/// \return The value of the underlying type.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR operator const T() const
|
||||
ETL_CONSTEXPR operator T() const ETL_NOEXCEPT
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@ -167,16 +374,9 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// ++ operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value& operator++()
|
||||
ETL_CONSTEXPR14 cyclic_value& operator++() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
if (value >= Last) ETL_UNLIKELY
|
||||
{
|
||||
value = First;
|
||||
}
|
||||
else
|
||||
{
|
||||
++value;
|
||||
}
|
||||
value = private_cyclic_value::increment(value, First, Last);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -184,7 +384,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// ++ operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value operator++(int)
|
||||
ETL_CONSTEXPR14 cyclic_value operator++(int) ETL_NOEXCEPT
|
||||
{
|
||||
cyclic_value temp(*this);
|
||||
|
||||
@ -196,16 +396,9 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// -- operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value& operator--()
|
||||
ETL_CONSTEXPR14 cyclic_value& operator--() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
if (value <= First) ETL_UNLIKELY
|
||||
{
|
||||
value = Last;
|
||||
}
|
||||
else
|
||||
{
|
||||
--value;
|
||||
}
|
||||
value = private_cyclic_value::decrement(value, First, Last);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -213,7 +406,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// -- operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value operator--(int)
|
||||
ETL_CONSTEXPR14 cyclic_value operator--(int) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
cyclic_value temp(*this);
|
||||
|
||||
@ -225,7 +418,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// = operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(T t)
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(T t) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
set(t);
|
||||
return *this;
|
||||
@ -234,8 +427,8 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// = operator.
|
||||
//*************************************************************************
|
||||
template <const T FIRST2, const T LAST2>
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(const cyclic_value<T, FIRST2, LAST2>& other)
|
||||
template <T FIRST2, T LAST2>
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(const cyclic_value<T, FIRST2, LAST2>& other) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
set(other.get());
|
||||
return *this;
|
||||
@ -244,7 +437,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Gets the value.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR T get() const
|
||||
ETL_CONSTEXPR T get() const ETL_NOEXCEPT
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@ -252,7 +445,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Gets the first value.
|
||||
//*************************************************************************
|
||||
static ETL_CONSTEXPR T first()
|
||||
static ETL_CONSTEXPR T first() ETL_NOEXCEPT
|
||||
{
|
||||
return First;
|
||||
}
|
||||
@ -260,7 +453,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Gets the last value.
|
||||
//*************************************************************************
|
||||
static ETL_CONSTEXPR T last()
|
||||
static ETL_CONSTEXPR T last() ETL_NOEXCEPT
|
||||
{
|
||||
return Last;
|
||||
}
|
||||
@ -268,39 +461,39 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Swaps the values.
|
||||
//*************************************************************************
|
||||
void swap(cyclic_value<T, First, Last>& other)
|
||||
ETL_CONSTEXPR14 void swap(cyclic_value<T, First, Last>& other) ETL_NOEXCEPT
|
||||
{
|
||||
using ETL_OR_STD::swap; // Allow ADL
|
||||
|
||||
swap(value, other.value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Swaps the values.
|
||||
//*************************************************************************
|
||||
friend void swap(cyclic_value<T, First, Last>& lhs, cyclic_value<T, First, Last>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Operator ==.
|
||||
//*************************************************************************
|
||||
friend ETL_CONSTEXPR bool operator==(const cyclic_value<T, First, Last>& lhs, const cyclic_value<T, First, Last>& rhs)
|
||||
{
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Operator !=.
|
||||
//*************************************************************************
|
||||
friend ETL_CONSTEXPR bool operator!=(const cyclic_value<T, First, Last>& lhs, const cyclic_value<T, First, Last>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*************************************************************************
|
||||
template <typename TStep>
|
||||
ETL_CONSTEXPR14 void do_advance(TStep n, bool subtract) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<TStep>::value, "TStep must be an integral type");
|
||||
|
||||
typedef private_cyclic_value::range_traits<T, First, Last> range_info;
|
||||
|
||||
// Are the limits the full width of the type? If so, we can do a simpler calculation.
|
||||
if ETL_IF_CONSTEXPR (range_info::is_full_range)
|
||||
{
|
||||
unsigned_type step = static_cast<unsigned_type>(etl::absolute_unsigned(n));
|
||||
|
||||
value = private_cyclic_value::advance(value, step, subtract);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned_type range = range_info::value;
|
||||
unsigned_type step = static_cast<unsigned_type>(etl::absolute_unsigned(n) % range);
|
||||
|
||||
value = private_cyclic_value::advance(value, First, Last, step, subtract);
|
||||
}
|
||||
}
|
||||
|
||||
T value; ///< The current value.
|
||||
};
|
||||
|
||||
@ -315,14 +508,20 @@ namespace etl
|
||||
template <typename T, T First, T Last>
|
||||
class cyclic_value<T, First, Last, true>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename private_cyclic_value::traits<T>::unsigned_type unsigned_type;
|
||||
|
||||
public:
|
||||
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "T must be an integral type");
|
||||
|
||||
//*************************************************************************
|
||||
/// 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_CONSTEXPR cyclic_value() ETL_NOEXCEPT
|
||||
: value(First)
|
||||
, first_value(First)
|
||||
, last_value(Last)
|
||||
@ -335,11 +534,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_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));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -350,16 +550,17 @@ namespace etl
|
||||
///\param last The last value in the range.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value(T first_, T last_, T initial)
|
||||
: first_value(first_)
|
||||
: value(etl::clamp(initial, first_, last_))
|
||||
, first_value(first_)
|
||||
, last_value(last_)
|
||||
{
|
||||
set(initial);
|
||||
ETL_ASSERT(first_ <= last_, ETL_ERROR(cyclic_value_reversed_limits));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Copy constructor.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR cyclic_value(const cyclic_value& other)
|
||||
ETL_CONSTEXPR cyclic_value(const cyclic_value& other) ETL_NOEXCEPT
|
||||
: value(other.value)
|
||||
, first_value(other.first_value)
|
||||
, last_value(other.last_value)
|
||||
@ -374,6 +575,8 @@ namespace etl
|
||||
//*************************************************************************
|
||||
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_;
|
||||
@ -383,7 +586,7 @@ namespace etl
|
||||
/// Sets the value.
|
||||
///\param value The value.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void set(T value_)
|
||||
ETL_CONSTEXPR14 void set(T value_) ETL_NOEXCEPT
|
||||
{
|
||||
value = etl::clamp(value_, first_value, last_value);
|
||||
}
|
||||
@ -391,7 +594,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Resets the value to the first in the range.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void to_first()
|
||||
ETL_CONSTEXPR14 void to_first() ETL_NOEXCEPT
|
||||
{
|
||||
value = first_value;
|
||||
}
|
||||
@ -399,7 +602,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Resets the value to the last in the range.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void to_last()
|
||||
ETL_CONSTEXPR14 void to_last() ETL_NOEXCEPT
|
||||
{
|
||||
value = last_value;
|
||||
}
|
||||
@ -408,30 +611,13 @@ namespace etl
|
||||
/// Advances to value by a number of steps.
|
||||
///\param n The number of steps to advance.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void advance(int n)
|
||||
template <typename TStep>
|
||||
ETL_CONSTEXPR14 T advance(TStep n) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
if (n > 0)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
operator++();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < -n; ++i)
|
||||
{
|
||||
operator--();
|
||||
}
|
||||
}
|
||||
}
|
||||
ETL_STATIC_ASSERT(etl::is_integral<TStep>::value, "TStep must be an integral type");
|
||||
|
||||
do_advance(n, etl::is_negative(n));
|
||||
|
||||
//*************************************************************************
|
||||
/// Conversion operator.
|
||||
/// \return The value of the underlying type.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 operator T()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -439,7 +625,7 @@ namespace etl
|
||||
/// Const conversion operator.
|
||||
/// \return The value of the underlying type.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR operator const T() const
|
||||
ETL_CONSTEXPR operator T() const ETL_NOEXCEPT
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@ -447,16 +633,9 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// ++ operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value& operator++()
|
||||
ETL_CONSTEXPR14 cyclic_value& operator++() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
if (value >= last_value)
|
||||
{
|
||||
value = first_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
++value;
|
||||
}
|
||||
value = private_cyclic_value::increment(value, first_value, last_value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -464,7 +643,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// ++ operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value operator++(int)
|
||||
ETL_CONSTEXPR14 cyclic_value operator++(int) ETL_NOEXCEPT
|
||||
{
|
||||
cyclic_value temp(*this);
|
||||
|
||||
@ -476,16 +655,9 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// -- operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value& operator--()
|
||||
ETL_CONSTEXPR14 cyclic_value& operator--() ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
if (value <= first_value)
|
||||
{
|
||||
value = last_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
--value;
|
||||
}
|
||||
value = private_cyclic_value::decrement(value, first_value, last_value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -493,7 +665,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// -- operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value operator--(int)
|
||||
ETL_CONSTEXPR14 cyclic_value operator--(int) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
cyclic_value temp(*this);
|
||||
|
||||
@ -505,7 +677,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// = operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(T t)
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(T t) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
set(t);
|
||||
return *this;
|
||||
@ -514,7 +686,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// = operator.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(const cyclic_value& other)
|
||||
ETL_CONSTEXPR14 cyclic_value& operator=(const cyclic_value& other) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
value = other.value;
|
||||
first_value = other.first_value;
|
||||
@ -522,10 +694,39 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a number of steps and clamps to the range.
|
||||
///\param n The number of steps.
|
||||
///\return A reference to this value.
|
||||
//*************************************************************************
|
||||
template <typename TStep>
|
||||
ETL_CONSTEXPR14 cyclic_value& operator+=(TStep n) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<TStep>::value, "TStep must be an integral type");
|
||||
|
||||
advance(n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Subtracts a number of steps and clamps to the range.
|
||||
///\param n The number of steps.
|
||||
///\return A reference to this value.
|
||||
//*************************************************************************
|
||||
template <typename TStep>
|
||||
ETL_CONSTEXPR14 cyclic_value& operator-=(TStep n) ETL_LVALUE_REF_QUALIFIER ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<TStep>::value, "TStep must be an integral type");
|
||||
|
||||
do_advance(n, !etl::is_negative(n));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the value.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR T get() const
|
||||
ETL_CONSTEXPR T get() const ETL_NOEXCEPT
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@ -533,7 +734,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Gets the first value.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR T first() const
|
||||
ETL_CONSTEXPR T first() const ETL_NOEXCEPT
|
||||
{
|
||||
return first_value;
|
||||
}
|
||||
@ -541,7 +742,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Gets the last value.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR T last() const
|
||||
ETL_CONSTEXPR T last() const ETL_NOEXCEPT
|
||||
{
|
||||
return last_value;
|
||||
}
|
||||
@ -549,7 +750,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Swaps the values.
|
||||
//*************************************************************************
|
||||
void swap(cyclic_value<T, First, Last>& other)
|
||||
ETL_CONSTEXPR14 void swap(cyclic_value<T, First, Last>& other) ETL_NOEXCEPT
|
||||
{
|
||||
using ETL_OR_STD::swap; // Allow ADL
|
||||
|
||||
@ -558,36 +759,117 @@ namespace etl
|
||||
swap(value, other.value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Swaps the values.
|
||||
//*************************************************************************
|
||||
friend void swap(cyclic_value<T, First, Last>& lhs, cyclic_value<T, First, Last>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Operator ==.
|
||||
//*************************************************************************
|
||||
friend ETL_CONSTEXPR bool operator==(const cyclic_value<T, First, Last>& lhs, const cyclic_value<T, First, Last>& rhs)
|
||||
{
|
||||
return (lhs.value == rhs.value) && (lhs.first_value == rhs.first_value) && (lhs.last_value == rhs.last_value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Operator !=.
|
||||
//*************************************************************************
|
||||
friend ETL_CONSTEXPR bool operator!=(const cyclic_value<T, First, Last>& lhs, const cyclic_value<T, First, Last>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*************************************************************************
|
||||
template <typename TStep>
|
||||
ETL_CONSTEXPR14 void do_advance(TStep n, bool subtract) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<TStep>::value, "TStep must be an integral type");
|
||||
|
||||
const bool Is_Full_Range = (first_value == etl::integral_limits<T>::min) && (last_value == etl::integral_limits<T>::max);
|
||||
|
||||
// Are the limits the full width of the type? If so, we can do a simpler calculation.
|
||||
if (Is_Full_Range)
|
||||
{
|
||||
unsigned_type step = static_cast<unsigned_type>(etl::absolute_unsigned(n));
|
||||
|
||||
value = private_cyclic_value::advance(value, step, subtract);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned_type range = static_cast<unsigned_type>(etl::to_unsigned(last_value) - etl::to_unsigned(first_value)) + 1U;
|
||||
unsigned_type step = static_cast<unsigned_type>(etl::absolute_unsigned(n) % range);
|
||||
|
||||
value = private_cyclic_value::advance(value, first_value, last_value, step, subtract);
|
||||
}
|
||||
}
|
||||
|
||||
T value; ///< The current value.
|
||||
T first_value; ///< The first value in the range.
|
||||
T last_value; ///< The last value in the range.
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Swaps the values.
|
||||
//*************************************************************************
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTEXPR14 void swap(etl::cyclic_value<T, First, Last>& lhs, etl::cyclic_value<T, First, Last>& rhs) ETL_NOEXCEPT
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
} // namespace etl
|
||||
|
||||
//*************************************************************************
|
||||
/// Operator ==
|
||||
///\param lhs The left-hand operand.
|
||||
///\param rhs The right-hand operand.
|
||||
///\return `true` if lhs == rhs.
|
||||
//*************************************************************************
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTEXPR bool operator==(const etl::cyclic_value<T, First, Last>& lhs, const etl::cyclic_value<T, First, Last>& rhs) ETL_NOEXCEPT
|
||||
{
|
||||
return (lhs.get() == rhs.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Operator !=
|
||||
///\param lhs The left-hand operand.
|
||||
///\param rhs The right-hand operand.
|
||||
///\return `true` if lhs != rhs.
|
||||
//*************************************************************************
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTEXPR bool operator!=(const etl::cyclic_value<T, First, Last>& lhs, const etl::cyclic_value<T, First, Last>& 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.
|
||||
//*************************************************************************
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTEXPR bool operator<(const etl::cyclic_value<T, First, Last>& lhs, const etl::cyclic_value<T, First, Last>& rhs) ETL_NOEXCEPT
|
||||
{
|
||||
return lhs.get() < rhs.get();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Operator <=
|
||||
///\param lhs The left-hand operand.
|
||||
///\param rhs The right-hand operand.
|
||||
///\return `true` if lhs is less than or equal to rhs.
|
||||
//*************************************************************************
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTEXPR bool operator<=(const etl::cyclic_value<T, First, Last>& lhs, const etl::cyclic_value<T, First, Last>& 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.
|
||||
//*************************************************************************
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTEXPR bool operator>(const etl::cyclic_value<T, First, Last>& lhs, const etl::cyclic_value<T, First, Last>& 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.
|
||||
//*************************************************************************
|
||||
template <typename T, T First, T Last>
|
||||
ETL_CONSTEXPR bool operator>=(const etl::cyclic_value<T, First, Last>& lhs, const etl::cyclic_value<T, First, Last>& rhs) ETL_NOEXCEPT
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -367,7 +367,6 @@ namespace etl
|
||||
{ \
|
||||
etl::error_handler::error((e)); \
|
||||
throw((e)); \
|
||||
return; \
|
||||
} \
|
||||
} while (false) // If the condition fails, calls the error handler then
|
||||
// throws an exception.
|
||||
@ -377,7 +376,6 @@ namespace etl
|
||||
{ \
|
||||
etl::error_handler::error((e)); \
|
||||
throw((e)); \
|
||||
return (v); \
|
||||
} \
|
||||
} while (false) // If the condition fails, calls the error handler then
|
||||
// throws an exception.
|
||||
@ -391,13 +389,11 @@ namespace etl
|
||||
do { \
|
||||
etl::error_handler::error((e)); \
|
||||
throw((e)); \
|
||||
return; \
|
||||
} while (false) // Calls the error handler then throws an exception.
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) \
|
||||
do { \
|
||||
etl::error_handler::error((e)); \
|
||||
throw((e)); \
|
||||
return (v); \
|
||||
} while (false) // Calls the error handler then throws an exception.
|
||||
#else
|
||||
#define ETL_ASSERT(b, e) \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -196,7 +196,7 @@ RunStandard()
|
||||
RunCheck gcc "No STL" ON OFF OFF bgcc
|
||||
|
||||
RunCheck gcc "STL - Disable builtins" OFF ON ON bgcc
|
||||
RunCheck gcc "No STL - Disable builtins" ON ON ON bgcc
|
||||
RunCheck gcc "No STL - Disable builtins" ON ON ON bgcc
|
||||
|
||||
if [ "$has_force_03" = "1" ]; then
|
||||
RunCheck gcc "STL - Force C++03" OFF ON OFF bgcc
|
||||
@ -213,7 +213,6 @@ RunStandard()
|
||||
if [ "$has_force_03" = "1" ]; then
|
||||
RunCheck clang "STL - Force C++03" OFF ON OFF bclang
|
||||
RunCheck clang "No STL - Force C++03" ON ON OFF bclang
|
||||
fi
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@ -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)
|
||||
{
|
||||
@ -336,7 +345,7 @@ namespace
|
||||
{
|
||||
etl::cyclic_value<int, 2, 7> value;
|
||||
|
||||
value.advance(14);
|
||||
value.advance(20);
|
||||
|
||||
CHECK_EQUAL(4, value);
|
||||
}
|
||||
@ -347,7 +356,7 @@ namespace
|
||||
etl::cyclic_value<int> value;
|
||||
|
||||
value.set(2, 7);
|
||||
value.advance(14);
|
||||
value.advance(20);
|
||||
|
||||
CHECK_EQUAL(4, value);
|
||||
}
|
||||
@ -358,7 +367,7 @@ namespace
|
||||
etl::cyclic_value<int, 2, 7> value;
|
||||
|
||||
value.to_last();
|
||||
value.advance(-14);
|
||||
value.advance(-20);
|
||||
|
||||
CHECK_EQUAL(5, value);
|
||||
}
|
||||
@ -370,7 +379,7 @@ namespace
|
||||
|
||||
value.set(2, 7);
|
||||
value.to_last();
|
||||
value.advance(-14);
|
||||
value.advance(-20);
|
||||
|
||||
CHECK_EQUAL(5, value);
|
||||
}
|
||||
@ -408,6 +417,168 @@ namespace
|
||||
CHECK_EQUAL(1U, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_positive_n_compile_time)
|
||||
{
|
||||
etl::cyclic_value<int, 2, 7> value;
|
||||
|
||||
value += 2;
|
||||
|
||||
CHECK_EQUAL(4, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_positive_n_run_time)
|
||||
{
|
||||
etl::cyclic_value<int> value;
|
||||
|
||||
value.set(2, 7);
|
||||
value += 2;
|
||||
|
||||
CHECK_EQUAL(4, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_positive_n_large_compile_time)
|
||||
{
|
||||
etl::cyclic_value<int, 2, 7> value;
|
||||
|
||||
value += 20;
|
||||
|
||||
CHECK_EQUAL(4, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_positive_n_large_run_time)
|
||||
{
|
||||
etl::cyclic_value<int> value;
|
||||
|
||||
value.set(2, 7);
|
||||
value += 20;
|
||||
|
||||
CHECK_EQUAL(4, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_negative_n_large_compile_time)
|
||||
{
|
||||
etl::cyclic_value<int, 2, 7> value;
|
||||
|
||||
value.to_last();
|
||||
value += -20;
|
||||
|
||||
CHECK_EQUAL(5, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_negative_n_large_run_time)
|
||||
{
|
||||
etl::cyclic_value<int> value;
|
||||
|
||||
value.set(2, 7);
|
||||
value.to_last();
|
||||
value += -20;
|
||||
|
||||
CHECK_EQUAL(5, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_negative_n_unsigned_compile_time)
|
||||
{
|
||||
etl::cyclic_value<size_t, 0U, 2U> value;
|
||||
|
||||
value += -2;
|
||||
|
||||
CHECK_EQUAL(1U, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_negative_n_run_time)
|
||||
{
|
||||
etl::cyclic_value<int> value;
|
||||
|
||||
value.set(2, 7);
|
||||
value.to_last();
|
||||
value += -20;
|
||||
|
||||
CHECK_EQUAL(5, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decrease_positive_compile_time)
|
||||
{
|
||||
etl::cyclic_value<int, 2, 7> value;
|
||||
|
||||
value -= 2;
|
||||
|
||||
CHECK_EQUAL(6, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_subtract_positive_n_run_time)
|
||||
{
|
||||
etl::cyclic_value<int> value;
|
||||
|
||||
value.set(2, 7);
|
||||
value -= 2;
|
||||
|
||||
CHECK_EQUAL(6, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_subtract_positive_n_large_compile_time)
|
||||
{
|
||||
etl::cyclic_value<int, 2, 7> value;
|
||||
|
||||
value -= 20;
|
||||
|
||||
CHECK_EQUAL(6, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_subtract_positive_n_large_run_time)
|
||||
{
|
||||
etl::cyclic_value<int> value;
|
||||
|
||||
value.set(2, 7);
|
||||
value -= 20;
|
||||
|
||||
CHECK_EQUAL(6, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_subtract_negative_n_large_compile_time)
|
||||
{
|
||||
etl::cyclic_value<int, 2, 7> value;
|
||||
|
||||
value.to_last();
|
||||
value -= -20;
|
||||
|
||||
CHECK_EQUAL(3, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_subtract_negative_n_large_run_time)
|
||||
{
|
||||
etl::cyclic_value<int> value;
|
||||
|
||||
value.set(2, 7);
|
||||
value.to_last();
|
||||
value -= -20;
|
||||
|
||||
CHECK_EQUAL(3, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_subtract_negative_n_unsigned_compile_time)
|
||||
{
|
||||
etl::cyclic_value<size_t, 0U, 2U> value;
|
||||
|
||||
value -= -2;
|
||||
|
||||
CHECK_EQUAL(2U, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_assignment_compile_time)
|
||||
{
|
||||
@ -493,7 +664,50 @@ namespace
|
||||
CHECK(data2 == compare1);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP14
|
||||
//*************************************************************************
|
||||
TEST(test_comparison_operators)
|
||||
{
|
||||
etl::cyclic_value<int, 0, 9> cv1(3);
|
||||
etl::cyclic_value<int, 0, 9> cv2(3);
|
||||
etl::cyclic_value<int, 0, 9> cv3(5);
|
||||
etl::cyclic_value<int, -1, 8> cv4(3);
|
||||
|
||||
CHECK_TRUE(cv1 == cv2);
|
||||
CHECK_FALSE(cv1 == cv3);
|
||||
|
||||
CHECK_FALSE(cv1 != cv2);
|
||||
CHECK_TRUE(cv1 != cv3);
|
||||
|
||||
CHECK_FALSE(cv1 < cv2);
|
||||
CHECK_FALSE(cv2 < cv1);
|
||||
CHECK_TRUE(cv1 < cv3);
|
||||
CHECK_FALSE(cv3 < cv1);
|
||||
CHECK_FALSE(cv1 < cv4);
|
||||
CHECK_FALSE(cv4 < cv1);
|
||||
|
||||
CHECK_FALSE(cv1 > cv2);
|
||||
CHECK_FALSE(cv2 > cv1);
|
||||
CHECK_FALSE(cv1 > cv3);
|
||||
CHECK_TRUE(cv3 > cv1);
|
||||
CHECK_FALSE(cv1 > cv4);
|
||||
CHECK_FALSE(cv4 > cv1);
|
||||
|
||||
CHECK_TRUE(cv1 <= cv2);
|
||||
CHECK_TRUE(cv2 <= cv1);
|
||||
CHECK_TRUE(cv1 <= cv3);
|
||||
CHECK_FALSE(cv3 <= cv1);
|
||||
CHECK_TRUE(cv1 <= cv4);
|
||||
CHECK_TRUE(cv4 <= cv1);
|
||||
|
||||
CHECK_TRUE(cv1 >= cv2);
|
||||
CHECK_TRUE(cv2 >= cv1);
|
||||
CHECK_FALSE(cv1 >= cv3);
|
||||
CHECK_TRUE(cv3 >= cv1);
|
||||
CHECK_TRUE(cv1 >= cv4);
|
||||
CHECK_TRUE(cv4 >= cv1);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
TEST(test_cyclic_value_constexpr_ctor)
|
||||
{
|
||||
@ -502,6 +716,7 @@ namespace
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP14
|
||||
//*************************************************************************
|
||||
TEST(test_cyclic_value_constexpr_ctor_with_range)
|
||||
{
|
||||
@ -510,6 +725,7 @@ namespace
|
||||
static_assert(cv.last() == 9, "constexpr range ctor last");
|
||||
CHECK(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_cyclic_value_constexpr_copy_ctor)
|
||||
@ -519,6 +735,299 @@ namespace
|
||||
static_assert(cv2.get() == 0, "constexpr copy ctor");
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_constexpr_comparison_operators)
|
||||
{
|
||||
constexpr etl::cyclic_value<int, 0, 9> cv1(3);
|
||||
constexpr etl::cyclic_value<int, 0, 9> cv2(3);
|
||||
constexpr etl::cyclic_value<int, 0, 9> cv3(5);
|
||||
constexpr etl::cyclic_value<int, -1, 8> cv4(3);
|
||||
|
||||
static_assert((cv1 == cv2), "(cv1 == cv2) failed");
|
||||
static_assert(!(cv1 == cv3), "!(cv1 == cv3) failed");
|
||||
|
||||
static_assert(!(cv1 != cv2), "!(cv1 != cv2) failed");
|
||||
static_assert((cv1 != cv3), "(cv1 != cv3) failed");
|
||||
|
||||
static_assert(!(cv1 < cv2), "!(cv1 < cv2) failed");
|
||||
static_assert(!(cv2 < cv1), "!(cv2 < cv1) failed");
|
||||
static_assert((cv1 < cv3), "(cv1 < cv3) failed");
|
||||
static_assert(!(cv3 < cv1), "!(cv3 < cv1) failed");
|
||||
static_assert(!(cv1 < cv4), "!(cv1 < cv4) failed");
|
||||
static_assert(!(cv4 < cv1), "!(cv4 < cv1) failed");
|
||||
|
||||
static_assert(!(cv1 > cv2), "!(cv1 > cv2) failed");
|
||||
static_assert(!(cv2 > cv1), "!(cv2 > cv1) failed");
|
||||
static_assert(!(cv1 > cv3), "!(cv1 > cv3) failed");
|
||||
static_assert((cv3 > cv1), "(cv3 > cv1) failed");
|
||||
static_assert(!(cv1 > cv4), "!(cv1 > cv4) failed");
|
||||
static_assert(!(cv4 > cv1), "!(cv4 > cv1) failed");
|
||||
|
||||
static_assert((cv1 <= cv2), "(cv1 <= cv2) failed");
|
||||
static_assert((cv2 <= cv1), "(cv2 <= cv1) failed");
|
||||
static_assert((cv1 <= cv3), "(cv1 <= cv3) failed");
|
||||
static_assert(!(cv3 <= cv1), "!(cv3 <= cv1) failed");
|
||||
static_assert((cv1 <= cv4), "(cv1 <= cv4) failed");
|
||||
static_assert((cv4 <= cv1), "(cv4 <= cv1) failed");
|
||||
|
||||
static_assert((cv1 >= cv2), "(cv1 >= cv2) failed");
|
||||
static_assert((cv2 >= cv1), "(cv2 >= cv1) failed");
|
||||
static_assert(!(cv1 >= cv3), "!(cv1 >= cv3) failed");
|
||||
static_assert((cv3 >= cv1), "(cv3 >= cv1) failed");
|
||||
static_assert((cv1 >= cv4), "(cv1 >= cv4) failed");
|
||||
static_assert((cv4 >= cv1), "(cv4 >= cv1) failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_maximum_unsigned_range_wrap_with_large_step_type)
|
||||
{
|
||||
etl::cyclic_value<uint8_t, 0, 255> value(0);
|
||||
|
||||
value.advance(static_cast<int32_t>(255));
|
||||
CHECK_EQUAL(255, value);
|
||||
|
||||
value.advance(static_cast<int32_t>(1));
|
||||
CHECK_EQUAL(0, value);
|
||||
|
||||
value.advance(static_cast<int32_t>(256));
|
||||
CHECK_EQUAL(0, value);
|
||||
|
||||
value.advance(static_cast<int32_t>(-256));
|
||||
CHECK_EQUAL(0, value);
|
||||
|
||||
value.advance(static_cast<int32_t>(-1));
|
||||
CHECK_EQUAL(255, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_maximum_signed_range_wrap_with_large_step_type)
|
||||
{
|
||||
etl::cyclic_value<int8_t, -128, 127> value(0);
|
||||
|
||||
value.advance(static_cast<int32_t>(127));
|
||||
CHECK_EQUAL(127, int(value));
|
||||
|
||||
value.advance(static_cast<int32_t>(1));
|
||||
CHECK_EQUAL(-128, int(value));
|
||||
|
||||
value.advance(static_cast<int32_t>(256));
|
||||
CHECK_EQUAL(-128, int(value));
|
||||
|
||||
value.advance(static_cast<int32_t>(-256));
|
||||
CHECK_EQUAL(-128, int(value));
|
||||
|
||||
value.advance(static_cast<int32_t>(-1));
|
||||
CHECK_EQUAL(127, int(value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_compile_time_range_issue_in_advance_for_full_range_unsigned_limits_where_step_is_same_size_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<uint8_t>::min;
|
||||
const auto maximum = etl::integral_limits<uint8_t>::max;
|
||||
|
||||
etl::cyclic_value<uint8_t> value(minimum, maximum);
|
||||
|
||||
value.advance(int8_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_compile_time_range_issue_in_advance_for_full_range_signed_limits_where_step_is_same_size_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<int8_t>::min;
|
||||
const auto maximum = etl::integral_limits<int8_t>::max;
|
||||
|
||||
etl::cyclic_value<int8_t> value(minimum, maximum);
|
||||
|
||||
value.advance(int8_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_compile_time_range_issue_in_advance_for_full_range_unsigned_limits_where_step_is_larger_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<uint8_t>::min;
|
||||
const auto maximum = etl::integral_limits<uint8_t>::max;
|
||||
|
||||
etl::cyclic_value<uint8_t, minimum, maximum> value(0);
|
||||
|
||||
value.advance(int16_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_compile_time_range_issue_in_advance_for_full_range_signed_limits_where_step_is_larger_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<int8_t>::min;
|
||||
const auto maximum = etl::integral_limits<int8_t>::max;
|
||||
|
||||
etl::cyclic_value<int8_t> value(minimum, maximum);
|
||||
|
||||
value.advance(uint16_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_compile_time_range_issue_in_advance_for_full_range_unsigned_limits_where_step_is_smaller_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<uint16_t>::min;
|
||||
const auto maximum = etl::integral_limits<uint16_t>::max;
|
||||
|
||||
etl::cyclic_value<uint16_t, minimum, maximum> value(0);
|
||||
|
||||
value.advance(int8_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_compile_time_range_issue_in_advance_for_full_range_signed_limits_where_step_is_smaller_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<int16_t>::min;
|
||||
const auto maximum = etl::integral_limits<int16_t>::max;
|
||||
|
||||
etl::cyclic_value<int16_t> value(minimum, maximum);
|
||||
|
||||
value.advance(int8_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_compile_time_range_issue_in_advance_for_full_range_unsigned_limits_where_the_types_are_64bit)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<uint64_t>::min;
|
||||
const auto maximum = etl::integral_limits<uint64_t>::max;
|
||||
|
||||
etl::cyclic_value<uint64_t, minimum, maximum> value(0);
|
||||
|
||||
value.advance(int64_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_compile_time_range_issue_in_advance_for_full_range_signed_limits_where_the_types_are_64bit)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<int64_t>::min;
|
||||
const auto maximum = etl::integral_limits<int64_t>::max;
|
||||
|
||||
etl::cyclic_value<int64_t> value(minimum, maximum);
|
||||
|
||||
value.advance(int64_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_run_time_range_issue_in_advance_for_full_range_unsigned_limits_where_step_is_same_size_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<uint8_t>::min;
|
||||
const auto maximum = etl::integral_limits<uint8_t>::max;
|
||||
|
||||
etl::cyclic_value<uint8_t> value(minimum, maximum);
|
||||
|
||||
value.advance(int8_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_run_time_range_issue_in_advance_for_full_range_signed_limits_where_step_is_same_size_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<int8_t>::min;
|
||||
const auto maximum = etl::integral_limits<int8_t>::max;
|
||||
|
||||
etl::cyclic_value<int8_t> value(minimum, maximum);
|
||||
|
||||
value.advance(int8_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_run_time_range_issue_in_advance_for_full_range_unsigned_limits_where_step_is_larger_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<uint8_t>::min;
|
||||
const auto maximum = etl::integral_limits<uint8_t>::max;
|
||||
|
||||
etl::cyclic_value<uint8_t, minimum, maximum> value(0);
|
||||
|
||||
value.advance(int16_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_run_time_range_issue_in_advance_for_full_range_signed_limits_where_step_is_larger_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<int8_t>::min;
|
||||
const auto maximum = etl::integral_limits<int8_t>::max;
|
||||
|
||||
etl::cyclic_value<int8_t> value(minimum, maximum);
|
||||
|
||||
value.advance(uint16_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_run_time_range_issue_in_advance_for_full_range_unsigned_limits_where_step_is_smaller_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<uint16_t>::min;
|
||||
const auto maximum = etl::integral_limits<uint16_t>::max;
|
||||
|
||||
etl::cyclic_value<uint16_t, minimum, maximum> value(0);
|
||||
|
||||
value.advance(int8_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_run_time_range_issue_in_advance_for_full_range_signed_limits_where_step_is_smaller_type)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<int16_t>::min;
|
||||
const auto maximum = etl::integral_limits<int16_t>::max;
|
||||
|
||||
etl::cyclic_value<int16_t> value(minimum, maximum);
|
||||
|
||||
value.advance(int8_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_run_time_range_issue_in_advance_for_full_range_unsigned_limits_where_the_types_are_64bit)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<uint64_t>::min;
|
||||
const auto maximum = etl::integral_limits<uint64_t>::max;
|
||||
|
||||
etl::cyclic_value<uint64_t, minimum, maximum> value(0);
|
||||
|
||||
value.advance(int64_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_run_time_range_issue_in_advance_for_full_range_signed_limits_where_the_types_are_64bit)
|
||||
{
|
||||
const auto minimum = etl::integral_limits<int64_t>::min;
|
||||
const auto maximum = etl::integral_limits<int64_t>::max;
|
||||
|
||||
etl::cyclic_value<int64_t> value(minimum, maximum);
|
||||
|
||||
value.advance(int64_t(2));
|
||||
|
||||
CHECK_EQUAL(minimum + 2, value.get());
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user