4#ifndef TETL_TUPLE_TUPLE_HPP
5#define TETL_TUPLE_TUPLE_HPP
7#include <etl/_config/all.hpp>
9#include <etl/_mpl/at.hpp>
10#include <etl/_tuple/ignore.hpp>
11#include <etl/_tuple/is_tuple_like.hpp>
12#include <etl/_tuple/tuple_element.hpp>
13#include <etl/_tuple/tuple_size.hpp>
14#include <etl/_type_traits/declval.hpp>
15#include <etl/_type_traits/index_constant.hpp>
16#include <etl/_type_traits/is_convertible.hpp>
17#include <etl/_type_traits/is_copy_constructible.hpp>
18#include <etl/_type_traits/is_default_constructible.hpp>
19#include <etl/_type_traits/is_implicit_default_constructible.hpp>
20#include <etl/_type_traits/is_move_assignable.hpp>
21#include <etl/_type_traits/is_move_constructible.hpp>
22#include <etl/_type_traits/is_nothrow_move_assignable.hpp>
23#include <etl/_type_traits/is_nothrow_move_constructible.hpp>
24#include <etl/_type_traits/is_nothrow_swappable.hpp>
25#include <etl/_type_traits/is_same.hpp>
26#include <etl/_utility/forward.hpp>
27#include <etl/_utility/index_sequence.hpp>
28#include <etl/_utility/move.hpp>
29#include <etl/_utility/swap.hpp>
35template <
etl::size_t I,
typename T>
37 template <
typename... Args>
38 constexpr tuple_leaf(Args&&... args)
39 : _value(
etl::forward<Args>(args)...)
43 [[nodiscard]]
constexpr auto operator[](index_constant<I> ) &
noexcept -> T&
48 [[nodiscard]]
constexpr auto operator[](index_constant<I> )
const&
noexcept -> T
const&
53 [[nodiscard]]
constexpr auto operator[](index_constant<I> ) &&
noexcept -> T&&
55 return etl::move(_value);
58 [[nodiscard]]
constexpr auto operator[](index_constant<I> )
const&&
noexcept -> T
const&&
60 return etl::move(_value);
63 constexpr auto swap(index_constant<I> , T& other)
noexcept(is_nothrow_swappable_v<T>) ->
void
71 TETL_NO_UNIQUE_ADDRESS T _value;
74template <
typename... Ts>
77template <size_t... Idx,
typename... Ts>
78struct tuple_storage<
etl::index_sequence<Idx...>, Ts...> : tuple_leaf<Idx, Ts>... {
79 explicit(
not(is_implicit_default_constructible_v<Ts>
and ...))
constexpr tuple_storage()
80 requires((is_default_constructible_v<Ts>
and ...))
81 : tuple_leaf<Idx, Ts>{}...
86 explicit(
not(is_convertible_v<Ts
const&, Ts>
and ...))
constexpr tuple_storage(Ts
const&... args)
87 requires((is_copy_constructible_v<Ts>
and ...) && (
sizeof...(Ts) > 0))
88 : tuple_leaf<Idx, Ts>(args)...
93 template <
typename... Us>
94 requires((is_constructible_v<Ts, Us &&>
and ...) && (
sizeof...(Ts) > 0) && (
sizeof...(Ts) ==
sizeof...(Us)))
95 explicit(!(is_convertible_v<Us&&, Ts>
and ...))
constexpr tuple_storage(Us&&... args)
96 : tuple_leaf<Idx, Ts>(
etl::forward<Us>(args))...
100 constexpr tuple_storage(tuple_storage
const&) =
default;
101 constexpr tuple_storage(tuple_storage&&)
noexcept =
default;
103 using tuple_leaf<Idx, Ts>::operator[]...;
105 constexpr auto swap(tuple_storage& other)
noexcept((is_nothrow_swappable_v<Ts> && ...)) ->
void
107 (tuple_leaf<Idx, Ts>::swap(
etl::index_v<Idx>, other[
etl::index_v<Idx>]), ...);
113template <
typename... Ts>
116 explicit(
not(is_implicit_default_constructible_v<Ts> && ...))
constexpr tuple()
117 requires((is_default_constructible_v<Ts>
and ...))
124 requires((is_copy_constructible_v<Ts> && ...)
and (
sizeof...(Ts) > 0))
130 template <
typename... Us>
131 requires((is_constructible_v<Ts, Us &&> && ...)
and (
sizeof...(Ts) > 0)
and (
sizeof...(Ts) ==
sizeof...(Us)))
133 : _storage(
etl::forward<Us>(args)...)
140 template <
etl::size_t I>
141 [[nodiscard]]
constexpr auto operator[](
etl::index_constant<I> idx) &
noexcept ->
auto&
143 return _storage[idx];
146 template <
etl::size_t I>
147 [[nodiscard]]
constexpr auto operator[](
etl::index_constant<I> idx)
const&
noexcept ->
auto const&
149 return _storage[idx];
152 template <
etl::size_t I>
153 [[nodiscard]]
constexpr auto operator[](
etl::index_constant<I> idx) &&
noexcept ->
auto&&
155 return etl::move(_storage)[idx];
158 template <
etl::size_t I>
159 [[nodiscard]]
constexpr auto operator[](
etl::index_constant<I> idx)
const&&
noexcept ->
auto const&&
161 return etl::move(_storage)[idx];
166 _storage.swap(other._storage);
170 using storage_type = detail::tuple_storage<
etl::index_sequence_for<Ts...>, Ts...>;
174template <
etl::size_t I,
typename... Ts>
175struct tuple_element<I,
tuple<Ts...>> {
176 static_assert(I <
sizeof...(Ts));
180template <
typename... Ts>
183template <
typename... Ts>
184inline constexpr auto is_tuple_like<etl::tuple<Ts...>> =
true;
186template <
etl::size_t I,
typename... Ts>
187[[nodiscard]]
constexpr auto get(
tuple<Ts...>& t) ->
auto&
189 static_assert(I <
sizeof...(Ts));
190 return t[
etl::index_v<I>];
193template <
etl::size_t I,
typename... Ts>
194[[nodiscard]]
constexpr auto get(
tuple<Ts...>
const& t) ->
auto const&
196 static_assert(I <
sizeof...(Ts));
197 return t[
etl::index_v<I>];
200template <
etl::size_t I,
typename... Ts>
201[[nodiscard]]
constexpr auto get(
tuple<Ts...>&& t) ->
auto&&
203 static_assert(I <
sizeof...(Ts));
204 return etl::move(t)[
etl::index_v<I>];
207template <
etl::size_t I,
typename... Ts>
208[[nodiscard]]
constexpr auto get(
tuple<Ts...>
const&& t) ->
auto const&&
210 static_assert(I <
sizeof...(Ts));
211 return etl::move(t)[
etl::index_v<I>];
214template <
typename... Ts,
typename... Us>
215 requires(
sizeof...(Ts) ==
sizeof...(Us))
218 if constexpr (
sizeof...(Ts) == 0) {
221 return [&]<etl::size_t... Is>(
etl::index_sequence<Is...> ) {
223 return ((get<Is>(lhs) == get<Is>(rhs))
and ...);
224 }(
etl::index_sequence_for<Ts...>{});
Definition adjacent_find.hpp:9
constexpr auto get(tuple< Ts... > const &&t) -> auto const &&
Definition tuple.hpp:208
constexpr auto get(tuple< Ts... > &t) -> auto &
Definition tuple.hpp:187
constexpr auto get(tuple< Ts... > const &t) -> auto const &
Definition tuple.hpp:194
constexpr auto operator==(tuple< Ts... > const &lhs, tuple< Us... > const &rhs) -> bool
Definition tuple.hpp:216
constexpr auto get(tuple< Ts... > &&t) -> auto &&
Definition tuple.hpp:201
Definition integral_constant.hpp:10
constexpr tuple(tuple const &)=default
constexpr auto swap(tuple &other) noexcept((is_nothrow_swappable_v< Ts > and ...)) -> void
Definition tuple.hpp:164
constexpr auto operator[](etl::index_constant< I > idx) const &&noexcept -> auto const &&
Definition tuple.hpp:159
constexpr auto operator[](etl::index_constant< I > idx) &&noexcept -> auto &&
Definition tuple.hpp:153
explicit(!(is_convertible_v< Us &&, Ts > &&...)) const expr tuple(Us &&... args)
Definition tuple.hpp:132
constexpr tuple(tuple &&) noexcept=default
explicit(not(is_convertible_v< Ts const &, Ts > &&...)) const expr tuple(Ts const &... args)
Definition tuple.hpp:123
constexpr auto operator[](etl::index_constant< I > idx) &noexcept -> auto &
Definition tuple.hpp:141
constexpr auto operator[](etl::index_constant< I > idx) const &noexcept -> auto const &
Definition tuple.hpp:147