Add missing array get<> overloads, and noexcept/constexpr (#1504)

Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
Roland Reichwein 2026-07-16 11:55:01 +02:00 committed by GitHub
parent f84d2e4af2
commit 875c9782d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 116 additions and 8 deletions

View File

@ -709,7 +709,7 @@ namespace etl
//*************************************************************************
/// Returns a const reference to the last element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reference back() const
ETL_NODISCARD ETL_CONSTEXPR const_reference back() const ETL_NOEXCEPT
{
return *data();
}
@ -1063,7 +1063,7 @@ namespace etl
///\param rhs The second array.
//*************************************************************************
template <typename T, const size_t SIZE>
void swap(etl::array<T, SIZE>& lhs, etl::array<T, SIZE>& rhs)
ETL_CONSTEXPR14 void swap(etl::array<T, SIZE>& lhs, etl::array<T, SIZE>& rhs) ETL_NOEXCEPT_FROM(ETL_OR_STD::swap(etl::declval<T&>(), etl::declval<T&>()))
{
lhs.swap(rhs);
}
@ -1100,7 +1100,7 @@ namespace etl
/// second, otherwise <b>false</b>
//*************************************************************************
template <typename T, size_t SIZE>
bool operator<(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs)
ETL_CONSTEXPR14 bool operator<(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs)
{
return etl::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
}
@ -1114,7 +1114,7 @@ namespace etl
///< b>false</b>
//*************************************************************************
template <typename T, size_t SIZE>
bool operator<=(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs)
ETL_CONSTEXPR14 bool operator<=(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs)
{
return !(lhs > rhs);
}
@ -1127,7 +1127,7 @@ namespace etl
/// the second, otherwise <b>false</b>
template <typename T, size_t SIZE>
//*************************************************************************
bool operator>(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs)
ETL_CONSTEXPR14 bool operator>(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs)
{
return (rhs < lhs);
}
@ -1141,7 +1141,7 @@ namespace etl
///< b>false</b>
//*************************************************************************
template <typename T, size_t SIZE>
bool operator>=(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs)
ETL_CONSTEXPR14 bool operator>=(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs)
{
return !(lhs < rhs);
}
@ -1155,7 +1155,7 @@ namespace etl
///\return A reference to the element
//*************************************************************************
template <size_t Index, typename T, size_t Size>
inline T& get(array<T, Size>& a)
ETL_NODISCARD ETL_CONSTEXPR14 T& get(array<T, Size>& a) ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
return a[Index];
@ -1170,11 +1170,43 @@ namespace etl
///\return A const reference to the element
//*************************************************************************
template <size_t Index, typename T, size_t Size>
inline const T& get(const array<T, Size>& a)
ETL_NODISCARD ETL_CONSTEXPR14 const T& get(const array<T, Size>& a) ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
return a[Index];
}
#if ETL_USING_CPP11
//*************************************************************************
/// Gets an rvalue reference to an element in the array.
///\tparam Index The index.
///\tparam T The type.
///\tparam Size The array size.
///\param a The array.
///\return An rvalue reference to the element
//*************************************************************************
template <size_t Index, typename T, size_t Size>
ETL_NODISCARD ETL_CONSTEXPR14 T&& get(array<T, Size>&& a) ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
return static_cast<T&&>(a[Index]);
}
//*************************************************************************
/// Gets a const rvalue reference to an element in the array.
///\tparam Index The index.
///\tparam T The type.
///\tparam Size The array size.
///\param a The array.
///\return A const rvalue reference to the element
//*************************************************************************
template <size_t Index, typename T, size_t Size>
ETL_NODISCARD ETL_CONSTEXPR14 const T&& get(const array<T, Size>&& a) ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
return static_cast<const T&&>(a[Index]);
}
#endif
} // namespace etl
#endif

View File

@ -400,6 +400,42 @@ namespace
// int i = etl::get<11>(data2);
}
#if ETL_USING_CPP11
//*************************************************************************
TEST(test_get_rvalue)
{
Data data1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
const Data data2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int&& r0 = etl::get<3>(std::move(data1));
const int&& r1 = etl::get<3>(std::move(data2));
CHECK_EQUAL(3, r0);
CHECK_EQUAL(3, r1);
// The rvalue overloads must be selected and return rvalue references.
CHECK((std::is_same<int&&, decltype(etl::get<3>(std::move(data1)))>::value));
CHECK((std::is_same<const int&&, decltype(etl::get<3>(std::move(data2)))>::value));
// Moving out of an rvalue array element actually moves.
etl::array<Moveable, 2U> data3 = {Moveable(1), Moveable(2)};
Moveable moved(etl::get<0>(std::move(data3)));
CHECK_EQUAL(1, moved.value);
CHECK(!data3[0].valid);
}
#endif
//*************************************************************************
TEST(test_get_constexpr)
{
ETL_CONSTEXPR14 Data data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ETL_CONSTEXPR14 int result = etl::get<3>(data);
CHECK_EQUAL(3, result);
}
//*************************************************************************
TEST(test_assign)
{
@ -691,6 +727,16 @@ namespace
CHECK(!(greater < data));
}
//*************************************************************************
TEST(test_less_than_constexpr)
{
ETL_CONSTEXPR14 Data lesser = {0, 1, 2, 3, 4, 4, 6, 7, 8, 9};
ETL_CONSTEXPR14 Data data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ETL_CONSTEXPR14 bool result = (lesser < data);
CHECK(result);
}
//*************************************************************************
TEST(test_less_than_equal)
{
@ -703,6 +749,16 @@ namespace
CHECK(!(greater <= data));
}
//*************************************************************************
TEST(test_less_than_equal_constexpr)
{
ETL_CONSTEXPR14 Data lesser = {0, 1, 2, 3, 4, 4, 6, 7, 8, 9};
ETL_CONSTEXPR14 Data data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ETL_CONSTEXPR14 bool result = (lesser <= data);
CHECK(result);
}
//*************************************************************************
TEST(test_greater_than)
{
@ -715,6 +771,16 @@ namespace
CHECK(!(lesser > data));
}
//*************************************************************************
TEST(test_greater_than_constexpr)
{
ETL_CONSTEXPR14 Data greater = {0, 1, 2, 3, 5, 5, 6, 7, 8, 9};
ETL_CONSTEXPR14 Data data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ETL_CONSTEXPR14 bool result = (greater > data);
CHECK(result);
}
//*************************************************************************
TEST(test_greater_than_equal)
{
@ -727,6 +793,16 @@ namespace
CHECK(!(lesser >= data));
}
//*************************************************************************
TEST(test_greater_than_equal_constexpr)
{
ETL_CONSTEXPR14 Data greater = {0, 1, 2, 3, 5, 5, 6, 7, 8, 9};
ETL_CONSTEXPR14 Data data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ETL_CONSTEXPR14 bool result = (greater >= data);
CHECK(result);
}
//*************************************************************************
#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST && !defined(ETL_TEMPLATE_DEDUCTION_GUIDE_TESTS_DISABLED)
TEST(test_array_template_deduction)