mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Support structured bindings for array (#1505)
This commit is contained in:
parent
875c9782d7
commit
66f904b1a3
@ -314,3 +314,42 @@ operator >=
|
|||||||
```
|
```
|
||||||
**Description**
|
**Description**
|
||||||
`true` if the contents of the lhs are lexicographically greater than or equal to the contents of the rhs, otherwise `false`.
|
`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 "static_assert.h"
|
||||||
#include "type_traits.h"
|
#include "type_traits.h"
|
||||||
|
|
||||||
|
#include "private/tuple_element.h"
|
||||||
|
#include "private/tuple_size.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
///\defgroup array array
|
///\defgroup array array
|
||||||
@ -1206,7 +1209,70 @@ namespace etl
|
|||||||
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
|
ETL_STATIC_ASSERT(Index < Size, "Index out of bounds");
|
||||||
return static_cast<const T&&>(a[Index]);
|
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
|
#endif
|
||||||
} // namespace etl
|
} // 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
|
#endif
|
||||||
|
|||||||
@ -35,6 +35,9 @@ SOFTWARE.
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#if ETL_USING_CPP11
|
||||||
|
#include <tuple>
|
||||||
|
#endif
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "etl/integral_limits.h"
|
#include "etl/integral_limits.h"
|
||||||
@ -436,6 +439,60 @@ namespace
|
|||||||
CHECK_EQUAL(3, result);
|
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)
|
TEST(test_assign)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user