Tatooine
tuple.h
Go to the documentation of this file.
1#ifndef TATOOINE_TUPLE_H
2#define TATOOINE_TUPLE_H
3//==============================================================================
4#include <concepts>
5#include <utility>
7//==============================================================================
8namespace tatooine {
9//==============================================================================
10template <typename... Ts>
11struct tuple;
12//------------------------------------------------------------------------------
13template <typename Head, typename... Tail>
14struct tuple<Head, Tail...> {
15 template <std::size_t I>
16 using type_at = variadic::ith_type<I, Head, Tail...>;
17 Head head;
18 tuple<Tail...> tail;
19 static auto constexpr size() { return 1 + sizeof...(Tail); }
20 //============================================================================
21 template <typename... Tail_>
22 tuple(Head&& head_, Tail_&&... tail_)
23 : head{std::move(head_)}, tail{std::forward<Tail_>(tail_)...} {}
24 //----------------------------------------------------------------------------
25 template <std::convertible_to<Head> Head_, typename... Tail_>
26 tuple(Head_&& head_, Tail_&&... tail_)
27 : head{static_cast<Head>(std::forward<Head_>(head_))},
28 tail{std::forward<Tail_>(tail_)...} {}
29 //----------------------------------------------------------------------------
30 tuple() = default;
31 tuple(tuple const&) = default;
32 tuple(tuple&&) noexcept = default;
33 ~tuple() = default;
34 auto operator=(tuple const&) -> tuple& = default;
35 auto operator=(tuple&&) noexcept -> tuple& = default;
36 //============================================================================
37 template <typename T = Head>
38 auto as_pointer() {
39 return reinterpret_cast<T*>(this);
40 }
41 //----------------------------------------------------------------------------
42 template <std::size_t I> requires (I < size())
43 auto at() const -> auto const& {
44 if constexpr (I == 0) {
45 return head;
46 } else {
47 return tail.template at<I - 1>();
48 }
49 }
50 //----------------------------------------------------------------------------
51 template <std::size_t I> requires (I < size())
52 auto at() -> auto& {
53 if constexpr (I == 0) {
54 return head;
55 } else {
56 return tail.template at<I - 1>();
57 }
58 }
59 //----------------------------------------------------------------------------
60 template <std::invocable<Head> F>
61 requires(std::invocable<F, Tail>&&...)
62 auto iterate(F&& f) {
63 f(head);
64 tail.iterate(std::forward<F>(f));
65 }
66 //----------------------------------------------------------------------------
67 template <std::invocable<Head> F>
68 requires(std::invocable<F, Tail>&&...)
69 auto iterate(F&& f) const {
70 f(static_cast<Head const&>(head));
71 tail.iterate(std::forward<F>(f));
72 }
73};
74// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
75template <typename Head, typename... Tail>
76tuple(Head&&, Tail&&...) -> tuple<std::decay_t<Head>, std::decay_t<Tail>...>;
77//------------------------------------------------------------------------------
78template <typename Head>
79struct tuple<Head> {
80 static auto constexpr size() {return 1;}
81 Head head;
82 //============================================================================
83 template <std::convertible_to<Head> Head_>
84 tuple(Head_&& head_) : head{static_cast<Head>(std::forward<Head_>(head_))} {}
85 //----------------------------------------------------------------------------
86 tuple() = default;
87 tuple(tuple const&) = default;
88 tuple(tuple&&) noexcept = default;
89 ~tuple() = default;
90 auto operator=(tuple const&) -> tuple& = default;
91 auto operator=(tuple&&) noexcept -> tuple& = default;
92 //============================================================================
93 template <typename T = Head>
94 auto as_pointer() {
95 return reinterpret_cast<T*>(this);
96 }
97 //----------------------------------------------------------------------------
98 template <std::size_t I>
99 requires(I == 0)
100 auto at() const -> auto const& { return head; }
101 //----------------------------------------------------------------------------
102 template <std::size_t I>
103 requires(I == 0)
104 auto at() -> auto& { return head; }
105 //----------------------------------------------------------------------------
106 template <std::invocable<Head> F>
107 auto iterate(F&& f) {
108 f(head);
109 }
110 //----------------------------------------------------------------------------
111 template <std::invocable<Head> F>
112 auto iterate(F&& f) const {
113 f(static_cast<Head const&>(head));
114 }
115};
116// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
117template <typename Head>
119//==============================================================================
120template <std::size_t Idx, typename... Ts>
121constexpr auto get(tuple<Ts...> const& t) -> auto const& {
122 return t.template at<Idx>();
123}
124//------------------------------------------------------------------------------
125template <std::size_t Idx, typename... Ts>
126constexpr auto get(tuple<Ts...>& t) -> auto& {
127 return t.template at<Idx>();
128}
129//==============================================================================
130template <typename Tuple1, typename Tuple2>
132//==============================================================================
133template <typename... TsTuple1, typename... TsTuple2>
134struct tuple_concat_types_impl<tuple<TsTuple1...>, tuple<TsTuple2...>> {
135 using type = tuple<TsTuple1..., TsTuple2...>;
136};
137template <typename Tuple1, typename Tuple2>
140//==============================================================================
141} // namespace tatooine
142//==============================================================================
143#endif
typename ith_type_impl< I, Types... >::type ith_type
Definition: ith_type.h:15
Definition: algorithm.h:6
typename get_impl< Container, I >::type get
Definition: get.h:11
typename tuple_concat_types_impl< Tuple1, Tuple2 >::type tuple_concat_types
Definition: tuple.h:139
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
static constexpr forward_tag forward
Definition: tags.h:9
T type
Definition: common_type.h:13
static auto constexpr size()
Definition: tuple.h:19
auto at() -> auto &
Definition: tuple.h:52
Head head
Definition: tuple.h:17
tuple(Head &&head_, Tail_ &&... tail_)
Definition: tuple.h:22
auto iterate(F &&f) const
Definition: tuple.h:69
auto iterate(F &&f)
Definition: tuple.h:62
tuple< Tail... > tail
Definition: tuple.h:18
tuple(tuple const &)=default
auto at() const -> auto const &
Definition: tuple.h:43
variadic::ith_type< I, Head, Tail... > type_at
Definition: tuple.h:16
tuple(tuple &&) noexcept=default
tuple(Head_ &&head_, Tail_ &&... tail_)
Definition: tuple.h:26
auto iterate(F &&f) const
Definition: tuple.h:112
tuple(tuple &&) noexcept=default
auto at() const -> auto const &
Definition: tuple.h:100
tuple(Head_ &&head_)
Definition: tuple.h:84
auto at() -> auto &
Definition: tuple.h:104
tuple(tuple const &)=default
static auto constexpr size()
Definition: tuple.h:80
Head head
Definition: tuple.h:81
auto iterate(F &&f)
Definition: tuple.h:107
Definition: tuple.h:131
Definition: tuple.h:11