mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-10 07:09:46 +08:00
Merge branch 'development' into hotfix/etl-bitset-bugs-#497
This commit is contained in:
commit
547b75da08
@ -38,7 +38,7 @@ ETL_CONSTEXPR bool is_zero(T value)
|
||||
**Returns**
|
||||
`true` if `value` is Zero.
|
||||
|
||||
## is_exactly_zero
|
||||
## is_exactly_equal
|
||||
|
||||
```cpp
|
||||
template <typename T>
|
||||
@ -260,7 +260,7 @@ A wrapper around `::powl` in `<math.h>`.
|
||||
If `ETL_NO_LONG_DOUBLE_MATH` is defined then returns
|
||||
`::pow` with casts to `double`.
|
||||
otherwise
|
||||
`::powl(base, intpart)`
|
||||
`::powl(base, exponent)`
|
||||
|
||||
## modf
|
||||
|
||||
|
||||
@ -707,6 +707,7 @@ size_t find(char c, size_t pos = 0) const;
|
||||
|
||||
```cpp
|
||||
size_t rfind(const etl::istring& str, size_t pos = npos) const;
|
||||
size_t rfind(const etl::string_view& view, size_t pos = npos) const;
|
||||
size_t rfind(const char* s, size_t pos = npos) const;
|
||||
size_t rfind(const char* s, size_t pos, size_t n) const;
|
||||
size_t rfind(char c, size_t pos = npos) const;
|
||||
|
||||
@ -126,7 +126,6 @@ struct type_list_contains
|
||||
```
|
||||
**Description**
|
||||
Defines `value` as `true` if the `type_list` contains the specified type, otherwise `false`.
|
||||
From: `C++17`
|
||||
|
||||
---
|
||||
|
||||
@ -135,7 +134,8 @@ template <typename TTypeList, typename T>
|
||||
constexpr bool type_list_contains_v
|
||||
```
|
||||
**Description**
|
||||
Defined as `true` if the `type_list` contains the specified type, otherwise `false`.
|
||||
Defined as `true` if the `type_list` contains the specified type, otherwise `false`.
|
||||
From: `C++17`
|
||||
|
||||
## type_list_has_duplicates_of
|
||||
```cpp
|
||||
|
||||
@ -4,14 +4,14 @@ title: atomic
|
||||
|
||||
{{< callout type="info">}}
|
||||
Header: `atomic.h`
|
||||
Since: `TBC`
|
||||
Since: `11.0.0`
|
||||
Similar to: [atomic](https://en.cppreference.com/cpp/atomic/atomic)
|
||||
{{< /callout >}}
|
||||
|
||||
This header attempts to replicate some of the types from `std::atomic`.
|
||||
|
||||
If `ETL_CPP11_SUPPORTED` is defined as `1` in the profile then `etl::atomic` will be defined in terms of `std::atomic`.
|
||||
Otherwise it will be implemented in terms of the built-in support, if available, from the compiler. For example, early GCC and Arm compilers will use the `__sync` built-ins.
|
||||
If `ETL_USING_CPP11` and `ETL_USING_STL` are defined as `1` then `etl::atomic` will be defined in terms of `std::atomic`.
|
||||
Otherwise it will be implemented in terms of the built-in support, if available, from the compiler. For example, early GCC and Arm compilers will use the `__sync` built-ins, later versions use `__atomic` built-ins.
|
||||
|
||||
If a type cannot be handled by the built-ins then the types are wrapped by `etl::mutex`.
|
||||
|
||||
@ -19,3 +19,273 @@ If there is an ETL atomic type available for your platform then `ETL_HAS_ATOMIC`
|
||||
it will be set to `0`.
|
||||
|
||||
From: `20.40.0` `etl::atomic` supports the `is_always_lock_free` property.
|
||||
|
||||
For GCC and clang built-ins:
|
||||
Integrals and pointers are lock free.
|
||||
All other types are not lock free.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename T>
|
||||
struct atomic;
|
||||
```
|
||||
```cpp
|
||||
template <typename T>
|
||||
struct atomic<T*>;
|
||||
```
|
||||
|
||||
## Memory order
|
||||
|
||||
```cpp
|
||||
memory_order_relaxed
|
||||
memory_order_consume
|
||||
memory_order_acquire
|
||||
memory_order_release
|
||||
memory_order_acq_rel
|
||||
memory_order_seq_cst
|
||||
```
|
||||
|
||||
## Constructors
|
||||
|
||||
```cpp
|
||||
ETL_CONSTEXPR atomic()
|
||||
```
|
||||
**Description**
|
||||
Value initialises `T`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
ETL_CONSTEXPR atomic(T v)
|
||||
```
|
||||
**Description**
|
||||
Initialises `T` with `v`.
|
||||
|
||||
## Assignment
|
||||
|
||||
```cpp
|
||||
T operator=(T v)
|
||||
T operator=(T v) volatile
|
||||
```
|
||||
**Description**
|
||||
Stores the value 'v'.
|
||||
|
||||
## Increment
|
||||
|
||||
```cpp
|
||||
T operator++()
|
||||
T operator++() volatile
|
||||
```
|
||||
**Description**
|
||||
Pre-increments the atomic value by one.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
T operator++(int)
|
||||
T operator++(int) volatile
|
||||
```
|
||||
**Description**
|
||||
Post-increments the atomic value by one.
|
||||
|
||||
## Decrement
|
||||
```cpp
|
||||
T operator--()
|
||||
T operator--() volatile
|
||||
```
|
||||
**Description**
|
||||
Pre-decrements the atomic value by one.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
T operator--(int)
|
||||
T operator--(int) volatile
|
||||
```
|
||||
**Description**
|
||||
Post-decrements the atomic value by one.
|
||||
|
||||
## Add
|
||||
|
||||
```cpp
|
||||
T operator+=(T v)
|
||||
T operator+=(T v) volatile
|
||||
```
|
||||
**Description**
|
||||
Adds to the atomic value.
|
||||
|
||||
## Subtract
|
||||
```cpp
|
||||
T operator-=(T v)
|
||||
T operator-=(T v) volatile
|
||||
```
|
||||
**Description**
|
||||
Subtracts from the atomic value.
|
||||
|
||||
## And
|
||||
|
||||
```cpp
|
||||
T operator&=(T v)
|
||||
T operator&=(T v) volatile
|
||||
```
|
||||
**Description**
|
||||
Performs bitwise AND with the atomic value.
|
||||
|
||||
## Or
|
||||
|
||||
```cpp
|
||||
T operator|=(T v)
|
||||
T operator|=(T v) volatile
|
||||
```
|
||||
**Description**
|
||||
Performs bitwise OR with the atomic value.
|
||||
|
||||
## Exclusive or
|
||||
|
||||
```cpp
|
||||
T operator^=(T v)
|
||||
T operator^=(T v) volatile
|
||||
```
|
||||
**Description**
|
||||
Performs bitwise XOR with the atomic value.
|
||||
|
||||
## Conversion operator
|
||||
|
||||
```cpp
|
||||
operator T() const
|
||||
operator T() volatile const
|
||||
```
|
||||
**Description**
|
||||
Loads a value from an atomic object.
|
||||
|
||||
## Is lock free
|
||||
|
||||
```cpp
|
||||
bool is_lock_free() const
|
||||
bool is_lock_free() const volatile
|
||||
```
|
||||
**Description**
|
||||
Checks if the atomic object is lock-free.
|
||||
|
||||
## Store
|
||||
|
||||
```cpp
|
||||
void store(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
void store(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically replaces the value of the atomic object with a non-atomic argument.
|
||||
|
||||
## Load
|
||||
|
||||
```cpp
|
||||
T load(etl::memory_order order = etl::memory_order_seq_cst) const
|
||||
T load(etl::memory_order order = etl::memory_order_seq_cst) const volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically obtains the value of the atomic object.
|
||||
|
||||
## Fetch add
|
||||
|
||||
```cpp
|
||||
T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
|
||||
```cpp
|
||||
T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically adds the argument to the value stored in the atomic object and obtains the value held previously.
|
||||
|
||||
## Fetch subtract
|
||||
|
||||
```cpp
|
||||
T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
|
||||
```cpp
|
||||
T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically subtracts the argument to the value stored in the atomic object and obtains the value held previously.
|
||||
|
||||
## Fetch or
|
||||
|
||||
```cpp
|
||||
T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically performs bitwise OR between the argument and the value of the atomic object and obtains the value held previously.
|
||||
|
||||
## Fetch and
|
||||
|
||||
```cpp
|
||||
T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically performs bitwise AND between the argument and the value of the atomic object and obtains the value held previously.
|
||||
|
||||
## Fetch exclusive or
|
||||
|
||||
```cpp
|
||||
T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically performs bitwise XOR between the argument and the value of the atomic object and obtains the value held previously.
|
||||
|
||||
## Fetch max
|
||||
|
||||
```cpp
|
||||
T fetch_max(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T fetch_max(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically performs max between the argument and the value of the atomic object and obtains the value held previously.
|
||||
|
||||
## Fetch min
|
||||
|
||||
```cpp
|
||||
T fetch_min(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T fetch_min(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically performs min between the argument and the value of the atomic object and obtains the value held previously.
|
||||
|
||||
## Exchange
|
||||
|
||||
```cpp
|
||||
T exchange(T v, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
T exchange(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically replaces the value of the atomic object and obtains the value held previously.
|
||||
|
||||
## Compare exchange weak
|
||||
|
||||
```cpp
|
||||
bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
|
||||
bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not.
|
||||
|
||||
## Compare exchange strong
|
||||
|
||||
```cpp
|
||||
bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst)
|
||||
bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst) volatile
|
||||
bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure)
|
||||
bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure) volatile
|
||||
```
|
||||
**Description**
|
||||
Atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not.
|
||||
|
||||
@ -28,54 +28,72 @@ second_argument_type;
|
||||
cmp_result;
|
||||
```
|
||||
|
||||
`cmp_result` has the values `Less`, `Equal`, and `Greater`.
|
||||
`cmp_result` defines the values `Less`, `Equal`, and `Greater`.
|
||||
|
||||
## Members
|
||||
```cpp
|
||||
static bool lt(first_argument_type lhs, second_argument_type rhs)
|
||||
```
|
||||
**Description**
|
||||
Less than.
|
||||
|
||||
**Return**
|
||||
`true` if `lhs < rhs`, otherwise `false`.
|
||||
`true` if `TLess()(lhs, rhs)`, otherwise `false`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
static bool lte(first_argument_type lhs, second_argument_type rhs)
|
||||
```
|
||||
**Description**
|
||||
Less than or equal.
|
||||
|
||||
**Return**
|
||||
`true` if `lhs <= rhs`, otherwise `false`.
|
||||
`true` if `lhs` is less than or equal to `rhs`, otherwise `false`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
static bool gt(first_argument_type lhs, second_argument_type rhs)
|
||||
```
|
||||
**Description**
|
||||
Greater than.
|
||||
|
||||
**Return**
|
||||
`true` if `lhs > rhs`, otherwise `false`.
|
||||
`true` if `lhs` is greater than `rhs`, otherwise `false`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
static bool gte(first_argument_type lhs, second_argument_type rhs)
|
||||
```
|
||||
**Description**
|
||||
Greater than or equal.
|
||||
|
||||
**Return**
|
||||
`true` if `lhs >= rhs`, otherwise `false`.
|
||||
`true` if `lhs` is greater than or equal to `rhs`, otherwise `false`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
static bool eq(first_argument_type lhs, second_argument_type rhs)
|
||||
```
|
||||
**Description**
|
||||
Equal.
|
||||
|
||||
**Return**
|
||||
`true` if `lhs == rhs`, otherwise `false`.
|
||||
`true` if neither value compares less than the other, otherwise `false`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
static bool ne(first_argument_type lhs, second_argument_type rhs)
|
||||
```
|
||||
**Description**
|
||||
Not equal.
|
||||
|
||||
**Return**
|
||||
`true` if `lhs != rhs`, otherwise `false`.
|
||||
`true` if if either value compare less than the other, otherwise `false`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -221,10 +221,12 @@ Checks equality of two cyclic values.
|
||||
Previously the first and last limits were also considered.
|
||||
|
||||
<= 20.49.0
|
||||
`etl::cyclic_value<2, 7>(3) != etl::cyclic_value<2, 6>(3)`
|
||||
`etl::cyclic_value<int, 2, 7>(3) != etl::cyclic_value<int, 2, 6>(3)`
|
||||
`etl::cyclic_value<int>(2, 7, 3) != etl::cyclic_value<int>(2, 6, 3)`
|
||||
|
||||
> 20.49.0
|
||||
`etl::cyclic_value<2, 7>(3) == etl::cyclic_value<2, 6>(3)`
|
||||
`etl::cyclic_value<int, 2, 7>(3) == etl::cyclic_value<int, 2, 6>(3)`
|
||||
`etl::cyclic_value<int>(2, 7, 3) == etl::cyclic_value<int>(2, 6, 3)`
|
||||
{{< /callout >}}
|
||||
|
||||
---
|
||||
|
||||
@ -1476,6 +1476,11 @@ namespace etl
|
||||
//*********************************************************************
|
||||
size_type find(T c, size_type position = 0) const
|
||||
{
|
||||
if (position >= size())
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
const_iterator i = etl::find(begin() + position, end(), c);
|
||||
|
||||
if (i != end())
|
||||
@ -1504,7 +1509,7 @@ namespace etl
|
||||
///\param pos The position to start searching from.
|
||||
//*********************************************************************
|
||||
template <typename TOtherTraits>
|
||||
size_type rfind(const etl::basic_string_view<T, TOtherTraits>& view, size_type pos = 0) const
|
||||
size_type rfind(const etl::basic_string_view<T, TOtherTraits>& view, size_type pos = npos) const
|
||||
{
|
||||
return rfind_impl(view.rbegin(), view.rend(), view.size(), pos);
|
||||
}
|
||||
@ -1544,12 +1549,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
size_type rfind(T c, size_type position = npos) const
|
||||
{
|
||||
if (position >= size())
|
||||
{
|
||||
position = size();
|
||||
}
|
||||
|
||||
position = size() - position;
|
||||
// Reverse offset of the first character to check, which is 'position' itself.
|
||||
position = (position >= size()) ? 0 : (size() - position - 1);
|
||||
|
||||
const_reverse_iterator i = etl::find(rbegin() + static_cast<difference_type>(position), rend(), c);
|
||||
|
||||
@ -2851,11 +2852,16 @@ namespace etl
|
||||
template <typename TIterator>
|
||||
size_type find_impl(TIterator first, TIterator last, size_type sz, size_type pos = 0) const
|
||||
{
|
||||
if ((pos + sz) > size())
|
||||
if ((pos > size()) || (sz > (size() - pos)))
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (sz == 0)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
const_iterator iposition = etl::search(begin() + pos, end(), first, last);
|
||||
|
||||
if (iposition == end())
|
||||
@ -2879,12 +2885,18 @@ namespace etl
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (pos >= size())
|
||||
if (pos > (size() - sz))
|
||||
{
|
||||
pos = size();
|
||||
pos = size() - sz;
|
||||
}
|
||||
|
||||
pos = size() - pos;
|
||||
if (sz == 0)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Reverse offset of the last character of a match starting at 'pos'.
|
||||
pos = size() - (pos + sz);
|
||||
|
||||
const_reverse_iterator iposition = etl::search(rbegin() + static_cast<difference_type>(pos), rend(), rfirst, rlast);
|
||||
|
||||
|
||||
@ -724,7 +724,7 @@ namespace etl
|
||||
///\param last The iterator to the last element + 1.
|
||||
//*********************************************************************
|
||||
template <typename TIterator>
|
||||
void assign(TIterator first, TIterator last)
|
||||
typename etl::enable_if<!etl::is_integral<TIterator>::value, void>::type assign(TIterator first, TIterator last)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<typename etl::remove_cv<T>::type,
|
||||
typename etl::remove_cv< typename etl::iterator_traits< TIterator>::value_type>::type>::value),
|
||||
@ -1071,7 +1071,7 @@ namespace etl
|
||||
///\param last The last + 1 element to add.
|
||||
//*********************************************************************
|
||||
template <class TIterator>
|
||||
iterator insert(const_iterator position, TIterator first, TIterator last)
|
||||
typename etl::enable_if<!etl::is_integral<TIterator>::value, iterator>::type insert(const_iterator position, TIterator first, TIterator last)
|
||||
{
|
||||
size_t count = size_t(etl::distance(first, last));
|
||||
|
||||
@ -1462,7 +1462,7 @@ namespace etl
|
||||
///\param last The iterator to the last element + 1.
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
indirect_vector(TIterator first, TIterator last)
|
||||
indirect_vector(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
|
||||
: etl::iindirect_vector<T>(lookup_vector, storage_pool)
|
||||
{
|
||||
this->assign(first, last);
|
||||
@ -1613,7 +1613,8 @@ namespace etl
|
||||
///\param last The iterator to the last element + 1.
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
indirect_vector_ext(TIterator first, TIterator last, etl::ivector<T*>& lookup_, etl::ipool& pool_)
|
||||
indirect_vector_ext(TIterator first, TIterator last, etl::ivector<T*>& lookup_, etl::ipool& pool_,
|
||||
typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
|
||||
: etl::iindirect_vector<T>(lookup_, pool_)
|
||||
{
|
||||
ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
|
||||
|
||||
@ -554,11 +554,16 @@ namespace etl
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 size_type find(etl::basic_string_view<T, TTraits> view, size_type position = 0) const ETL_NOEXCEPT
|
||||
{
|
||||
if ((size() < view.size()))
|
||||
if ((position > size()) || (view.size() > (size() - position)))
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (view.empty())
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
const_iterator iposition = etl::search(begin() + position, end(), view.begin(), view.end());
|
||||
|
||||
if (iposition == end())
|
||||
@ -598,9 +603,11 @@ namespace etl
|
||||
|
||||
position = etl::min(position, size() - view.size());
|
||||
|
||||
const_iterator iposition = etl::find_end(begin(), begin() + position + view.size(), view.begin(), view.end());
|
||||
const_iterator search_end = begin() + position + view.size();
|
||||
const_iterator iposition = etl::find_end(begin(), search_end, view.begin(), view.end());
|
||||
|
||||
if (iposition == end())
|
||||
// find_end returns the end of the searched range when there is no match.
|
||||
if ((iposition == search_end) && !view.empty())
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
@ -1201,6 +1201,42 @@ namespace
|
||||
CHECK_THROW(data.insert(data.begin() + static_cast<ptrdiff_t>(offset), INSERT_SIZE, INITIAL_VALUE), etl::vector_full);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_constructor_two_parameter_same_type_not_iterator)
|
||||
{
|
||||
std::vector<int> compare_data(5, 7);
|
||||
etl::indirect_vector<int, 10> data(5, 7);
|
||||
|
||||
CHECK_EQUAL(compare_data.size(), data.size());
|
||||
CHECK(std::equal(data.begin(), data.end(), compare_data.begin()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_assign_two_parameter_same_type_not_iterator)
|
||||
{
|
||||
std::vector<size_t> compare_data;
|
||||
etl::indirect_vector<size_t, 10> data;
|
||||
|
||||
compare_data.assign(5, 7);
|
||||
data.assign(5, 7);
|
||||
|
||||
CHECK_EQUAL(compare_data.size(), data.size());
|
||||
CHECK(std::equal(data.begin(), data.end(), compare_data.begin()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_insert_three_parameter_same_type_not_iterator)
|
||||
{
|
||||
std::vector<int> compare_data(3UL, 1);
|
||||
etl::indirect_vector<int, 10> data(3UL, 1);
|
||||
|
||||
compare_data.insert(compare_data.begin(), 2, 7);
|
||||
data.insert(data.begin(), 2, 7);
|
||||
|
||||
CHECK_EQUAL(compare_data.size(), data.size());
|
||||
CHECK(std::equal(data.begin(), data.end(), compare_data.begin()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_insert_position_range)
|
||||
{
|
||||
|
||||
@ -335,6 +335,22 @@ namespace
|
||||
CHECK_EQUAL(4U, *data2[3]);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_constructor_two_parameter_same_type_not_iterator)
|
||||
{
|
||||
LookupInt lookup;
|
||||
PoolInt pool;
|
||||
|
||||
etl::indirect_vector_ext<int> data(5, 7, lookup, pool);
|
||||
|
||||
CHECK_EQUAL(5U, data.size());
|
||||
CHECK_EQUAL(7, data[0]);
|
||||
CHECK_EQUAL(7, data[1]);
|
||||
CHECK_EQUAL(7, data[2]);
|
||||
CHECK_EQUAL(7, data[3]);
|
||||
CHECK_EQUAL(7, data[4]);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_assignment)
|
||||
{
|
||||
|
||||
@ -3815,6 +3815,33 @@ namespace
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_find_rfind_all_positions)
|
||||
{
|
||||
const value_t the_haystack[] = STR("A haystack with a needle and another needle");
|
||||
|
||||
TextSTD compare_haystack(the_haystack);
|
||||
TextL haystack(the_haystack);
|
||||
|
||||
const value_t* needles[] = {STR("needle"), STR("e"), STR("")};
|
||||
|
||||
// Every position up to past the end, where the search must not read outside the string.
|
||||
for (size_t position = 0UL; position <= compare_haystack.size() + 2UL; ++position)
|
||||
{
|
||||
for (size_t i = 0UL; i < 3UL; ++i)
|
||||
{
|
||||
CHECK_EQUAL(compare_haystack.find(needles[i], position), haystack.find(needles[i], position));
|
||||
CHECK_EQUAL(compare_haystack.rfind(needles[i], position), haystack.rfind(needles[i], position));
|
||||
}
|
||||
|
||||
CHECK_EQUAL(compare_haystack.find(STR('e'), position), haystack.find(STR('e'), position));
|
||||
CHECK_EQUAL(compare_haystack.rfind(STR('e'), position), haystack.rfind(STR('e'), position));
|
||||
}
|
||||
|
||||
CHECK_EQUAL(TextL::npos, haystack.find(STR('e'), TextL::npos));
|
||||
CHECK_EQUAL(TextL::npos, haystack.find(STR("needle"), TextL::npos));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_contains_string)
|
||||
{
|
||||
@ -3991,6 +4018,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -4362,6 +4362,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -4063,6 +4063,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -4464,6 +4464,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -4063,6 +4063,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -4464,6 +4464,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -4008,6 +4008,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -4383,6 +4383,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -925,6 +925,27 @@ namespace
|
||||
CHECK(View::npos == view.rfind(s4, 0, 11));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_find_rfind_all_positions)
|
||||
{
|
||||
const std::string compare_text("abcdabcdab");
|
||||
View view(compare_text.c_str());
|
||||
|
||||
const char* needles[] = {"cd", "d", "x", ""};
|
||||
|
||||
// Every position up to past the end, where the search must not read outside the view.
|
||||
for (size_t position = 0U; position <= compare_text.size() + 2U; ++position)
|
||||
{
|
||||
for (size_t i = 0U; i < 4U; ++i)
|
||||
{
|
||||
CHECK_EQUAL(compare_text.find(needles[i], position), view.find(needles[i], position));
|
||||
CHECK_EQUAL(compare_text.rfind(needles[i], position), view.rfind(needles[i], position));
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_EQUAL(View::npos, view.find("cd", View::npos));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_find_first_of)
|
||||
{
|
||||
|
||||
@ -4064,6 +4064,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -4467,6 +4467,11 @@ namespace
|
||||
position2 = haystack.rfind(needle_view, haystack.size() - 10);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
// The default position searches the whole string.
|
||||
position1 = compare_haystack.rfind(compare_needle);
|
||||
position2 = haystack.rfind(needle_view);
|
||||
CHECK_EQUAL(position1, position2);
|
||||
|
||||
View pin_view(STR("pin"));
|
||||
position2 = haystack.rfind(pin_view);
|
||||
CHECK_EQUAL(TextL::npos, position2);
|
||||
|
||||
@ -3,6 +3,16 @@ if(CONFIG_ETL)
|
||||
zephyr_link_libraries(etl::etl)
|
||||
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_DEBUG ETL_DEBUG)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_CHECK_PUSH_POP ETL_CHECK_PUSH_POP)
|
||||
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_LOG_ERRORS ETL_LOG_ERRORS)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_USE_ASSERT_FUNCTION ETL_USE_ASSERT_FUNCTION)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_THROW_EXCEPTIONS ETL_THROW_EXCEPTIONS)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_NO_CHECKS ETL_NO_CHECKS)
|
||||
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_VERBOSE_ERRORS ETL_VERBOSE_ERRORS)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_MINIMAL_ERRORS ETL_MINIMAL_ERRORS)
|
||||
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_CHECK_PUSH_POP ETL_CHECK_PUSH_POP)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_CHECK_INDEX_OPERATOR ETL_CHECK_INDEX_OPERATOR)
|
||||
zephyr_compile_definitions_ifdef(CONFIG_ETL_CHECK_EXTRA ETL_CHECK_EXTRA)
|
||||
endif()
|
||||
|
||||
@ -8,12 +8,78 @@ if ETL
|
||||
|
||||
config ETL_DEBUG
|
||||
bool "Build ETL with debugging checks"
|
||||
default y if DEBUG
|
||||
default y if ASSERT
|
||||
|
||||
choice ETL_ERROR_MODE
|
||||
prompt "ETL error handling mode"
|
||||
help
|
||||
What ETL does when one of its checks fails.
|
||||
|
||||
config ETL_ASSERT_ERRORS
|
||||
bool "Assert in ETL_DEBUG builds, otherwise ignore"
|
||||
help
|
||||
With ETL_DEBUG, a failed check calls assert(). Without it, nothing
|
||||
is reported, but checks that guard an operation still skip it.
|
||||
With ETL_LOG_ERRORS, a failed check calls the error handler instead,
|
||||
with or without ETL_DEBUG.
|
||||
|
||||
config ETL_USE_ASSERT_FUNCTION
|
||||
bool "Call a user assert function"
|
||||
help
|
||||
A failed check calls the function registered with
|
||||
etl::set_assert_function(), and checks that guard an operation
|
||||
still skip it. Until one is registered, it calls assert(false).
|
||||
|
||||
config ETL_THROW_EXCEPTIONS
|
||||
bool "Throw an exception"
|
||||
depends on CPP_EXCEPTIONS
|
||||
help
|
||||
A failed check throws an etl::exception.
|
||||
|
||||
config ETL_NO_CHECKS
|
||||
bool "No checks"
|
||||
help
|
||||
Check conditions are not evaluated.
|
||||
|
||||
endchoice # ETL_ERROR_MODE
|
||||
|
||||
config ETL_LOG_ERRORS
|
||||
bool "Call the ETL error handler"
|
||||
depends on !ETL_USE_ASSERT_FUNCTION && !ETL_NO_CHECKS
|
||||
help
|
||||
A failed check calls the callback registered with
|
||||
etl::error_handler::set_callback(). With ETL_THROW_EXCEPTIONS it
|
||||
then throws; otherwise, checks that guard an operation still skip
|
||||
it. With no callback registered, errors are discarded.
|
||||
|
||||
choice ETL_ERROR_DETAIL
|
||||
prompt "ETL error detail level"
|
||||
help
|
||||
What information the etl::exception for a failed check carries,
|
||||
whether it is thrown or passed to the error handler or assert
|
||||
function. Unused when a failed check calls plain assert().
|
||||
|
||||
config ETL_TERSE_ERRORS
|
||||
bool "Short error code only"
|
||||
|
||||
config ETL_VERBOSE_ERRORS
|
||||
bool "Message, file and line"
|
||||
|
||||
config ETL_MINIMAL_ERRORS
|
||||
bool "Nothing"
|
||||
|
||||
endchoice # ETL_ERROR_DETAIL
|
||||
|
||||
config ETL_CHECK_PUSH_POP
|
||||
bool "Enable push/pop checks in ETL"
|
||||
depends on !ETL_NO_CHECKS
|
||||
|
||||
config ETL_LOG_ERRORS
|
||||
bool "Call ETL error handler instead of assert"
|
||||
config ETL_CHECK_INDEX_OPERATOR
|
||||
bool "Enable bounds checks on ETL operator[]"
|
||||
depends on !ETL_NO_CHECKS
|
||||
|
||||
config ETL_CHECK_EXTRA
|
||||
bool "Enable extra bounds and empty checks in ETL containers"
|
||||
depends on !ETL_NO_CHECKS
|
||||
|
||||
endif # ETL
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user