mirror of
https://github.com/ETLCPP/etl.git
synced 2026-07-30 16:26:17 +08:00
Support structured bindings for array
This commit is contained in:
parent
875c9782d7
commit
bdb1ce31fe
@ -314,3 +314,42 @@ operator >=
|
||||
```
|
||||
**Description**
|
||||
`true` if the contents of the lhs are lexicographically greater than or equal to the contents of the rhs, otherwise `false`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <size_t Index, typename T, size_t Size>
|
||||
T& get(etl::array<T, Size>& a)
|
||||
|
||||
template <size_t Index, typename T, size_t Size>
|
||||
const T& get(const etl::array<T, Size>& a)
|
||||
```
|
||||
**Description**
|
||||
Gets a reference to the element at `Index` in the array.
|
||||
|
||||
## Structured bindings
|
||||
`etl::array` provides the tuple-like interface required for C++17 structured bindings.
|
||||
|
||||
```cpp
|
||||
etl::array<int, 3> a = { 1, 2, 3 };
|
||||
|
||||
auto& [x, y, z] = a; // x, y, z are references to a[0], a[1], a[2]
|
||||
```
|
||||
|
||||
```cpp
|
||||
template <typename T, size_t Size>
|
||||
struct tuple_size<etl::array<T, Size>>
|
||||
```
|
||||
**Description**
|
||||
Gets the number of elements in the array.
|
||||
Specialised in namespaces `etl` and `std` (the `std` specialisation allows the use of C++ structured bindings).
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <size_t Index, typename T, size_t Size>
|
||||
struct tuple_element<Index, etl::array<T, Size>>
|
||||
```
|
||||
**Description**
|
||||
Gets the type of the element at `Index` in the array.
|
||||
Specialised in namespaces `etl` and `std` (the `std` specialisation allows the use of C++ structured bindings).
|
||||
|
||||
@ -40,6 +40,9 @@ SOFTWARE.
|
||||
#include "static_assert.h"
|
||||
#include "type_traits.h"
|
||||
|
||||
#include "private/tuple_element.h"
|
||||
#include "private/tuple_size.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
///\defgroup array array
|
||||
@ -1206,7 +1209,70 @@ namespace etl
|
||||
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
|
||||
return static_cast<const T&&>(a[Index]);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the number of elements in an array.
|
||||
///\tparam T The type.
|
||||
///\tparam Size The array size.
|
||||
//*************************************************************************
|
||||
template <typename T, size_t Size>
|
||||
struct tuple_size<etl::array<T, Size> > : etl::integral_constant<size_t, Size>
|
||||
{
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the type of the element at Index in an array.
|
||||
///\tparam Index The index.
|
||||
///\tparam T The type.
|
||||
///\tparam Size The array size.
|
||||
//*************************************************************************
|
||||
template <size_t Index, typename T, size_t Size>
|
||||
struct tuple_element<Index, etl::array<T, Size> >
|
||||
{
|
||||
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
|
||||
|
||||
using type = T;
|
||||
};
|
||||
#endif
|
||||
} // namespace etl
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
namespace std
|
||||
{
|
||||
// libc++ already declares std::tuple_size / std::tuple_element in its inline
|
||||
// namespace (std::__1), so re-declaring them here would make the name
|
||||
// ambiguous. Detect libc++ via _LIBCPP_VERSION and skip the forward
|
||||
// declarations in that case, even when not using the STL.
|
||||
#if ETL_NOT_USING_STL && !defined(_LIBCPP_VERSION) \
|
||||
&& !((defined(ETL_DEVELOPMENT_OS_APPLE) || (ETL_COMPILER_FULL_VERSION >= 190000) && (ETL_COMPILER_FULL_VERSION < 210000)) \
|
||||
&& defined(ETL_COMPILER_CLANG))
|
||||
template <typename T>
|
||||
struct tuple_size;
|
||||
|
||||
template <size_t Index, typename TType>
|
||||
struct tuple_element;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation of tuple_size to allow the use of C++ structured bindings.
|
||||
//***************************************************************************
|
||||
template <typename T, size_t Size>
|
||||
struct tuple_size<etl::array<T, Size> > : etl::integral_constant<size_t, Size>
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation of tuple_element to allow the use of C++ structured
|
||||
/// bindings.
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename T, size_t Size>
|
||||
struct tuple_element<Index, etl::array<T, Size> >
|
||||
{
|
||||
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
|
||||
|
||||
using type = T;
|
||||
};
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -35,6 +35,9 @@ SOFTWARE.
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <iterator>
|
||||
#if ETL_USING_CPP11
|
||||
#include <tuple>
|
||||
#endif
|
||||
#include <type_traits>
|
||||
|
||||
#include "etl/integral_limits.h"
|
||||
@ -436,6 +439,60 @@ namespace
|
||||
CHECK_EQUAL(3, result);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
TEST(test_tuple_size)
|
||||
{
|
||||
CHECK_EQUAL(SIZE, (etl::tuple_size<Data>::value));
|
||||
CHECK_EQUAL(SIZE, (std::tuple_size<Data>::value));
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
CHECK_EQUAL(SIZE, (etl::tuple_size_v<Data>));
|
||||
CHECK_EQUAL(SIZE, (std::tuple_size_v<Data>));
|
||||
#endif
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_tuple_element)
|
||||
{
|
||||
CHECK_TRUE((std::is_same<int, etl::tuple_element_t<0, Data>>::value));
|
||||
CHECK_TRUE((std::is_same<int, etl::tuple_element_t<SIZE - 1, Data>>::value));
|
||||
|
||||
CHECK_TRUE((std::is_same<int, std::tuple_element<0, Data>::type>::value));
|
||||
CHECK_TRUE((std::is_same<int, std::tuple_element<SIZE - 1, Data>::type>::value));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
//*************************************************************************
|
||||
TEST(test_structured_bindings)
|
||||
{
|
||||
etl::array<int, 3> data = {1, 2, 3};
|
||||
|
||||
// Bind by reference and modify.
|
||||
auto& [a, b, c] = data;
|
||||
|
||||
CHECK_EQUAL(1, a);
|
||||
CHECK_EQUAL(2, b);
|
||||
CHECK_EQUAL(3, c);
|
||||
|
||||
a = 10;
|
||||
b = 20;
|
||||
c = 30;
|
||||
|
||||
CHECK_EQUAL(10, data[0]);
|
||||
CHECK_EQUAL(20, data[1]);
|
||||
CHECK_EQUAL(30, data[2]);
|
||||
|
||||
// Bind by const reference.
|
||||
const auto& [x, y, z] = data;
|
||||
|
||||
CHECK_EQUAL(10, x);
|
||||
CHECK_EQUAL(20, y);
|
||||
CHECK_EQUAL(30, z);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_assign)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user