Tatooine
invoke_unpacked.h
Go to the documentation of this file.
1#ifndef TATOOINE_INVOKE_UNPACKED_H
2#define TATOOINE_INVOKE_UNPACKED_H
3//==============================================================================
4#include <functional>
5#include <tatooine/bind.h>
6#include <array>
7//==============================================================================
8namespace tatooine {
9//==============================================================================
10template <typename Container>
11struct unpack;
12//==============================================================================
14template <typename F>
15constexpr decltype(auto) invoke_unpacked(F&& f) {
16 return f();
17}
18
19//------------------------------------------------------------------------------
23template <typename F, typename T, typename... Ts>
24constexpr decltype(auto) invoke_unpacked(F&& f, T&& t, Ts&&... ts) {
25 return invoke_unpacked(bind(std::forward<F>(f), std::forward<T>(t)),
26 std::forward<Ts>(ts)...);
27}
28
29//------------------------------------------------------------------------------
31template <std::size_t... Is, typename F, typename T, typename... Ts>
32constexpr decltype(auto) invoke_unpacked(std::index_sequence<Is...> /*is*/,
33 F&& f, unpack<T> t, Ts&&... ts) {
34 return invoke_unpacked(std::forward<F>(f), t.template get<Is>()...,
35 std::forward<Ts>(ts)...);
36}
37
38//------------------------------------------------------------------------------
39template <typename F, typename T, typename... Ts>
40constexpr decltype(auto) invoke_unpacked(F&& f, unpack<T> t, Ts&&... ts) {
41 return invoke_unpacked(std::make_index_sequence<unpack<T>::n>{},
42 std::forward<F>(f), std::move(t),
43 std::forward<Ts>(ts)...);
44}
45
46//==============================================================================
47// some unpack implementations
48template <typename T, size_t N>
49struct unpack<std::array<T, N>> {
50 static constexpr size_t n = N;
51 std::array<T, N>& container;
52 //----------------------------------------------------------------------------
53 explicit constexpr unpack(std::array<T, N>& c) : container{c} {}
54 //----------------------------------------------------------------------------
55 template <size_t I>
56 constexpr auto get() -> auto& { return container[I]; }
57 template <size_t I>
58 constexpr auto get() const -> const auto& { return container[I]; }
59};
60//==============================================================================
61template <typename T, size_t N>
62unpack(std::array<T, N>& c)->unpack<std::array<T, N>>;
63//==============================================================================
64template <typename T, size_t N>
65struct unpack<const std::array<T, N>> {
66 static constexpr size_t n = N;
67 const std::array<T, N>& container;
68
69 //----------------------------------------------------------------------------
70 explicit constexpr unpack(const std::array<T, N>& c) : container{c} {}
71
72 //----------------------------------------------------------------------------
73 template <size_t I>
74 constexpr auto get() const -> const auto& {
75 return container[I];
76 }
77};
78//==============================================================================
79template <typename T, size_t N>
80unpack(const std::array<T, N>& c)->unpack<const std::array<T, N>>;
81
82//==============================================================================
83template <typename... Ts>
84struct unpack<std::tuple<Ts...>> {
85 static constexpr size_t n = sizeof...(Ts);
86 std::tuple<Ts...>& container;
87 //----------------------------------------------------------------------------
88 explicit constexpr unpack(std::tuple<Ts...>&& c) : container{c} {}
89 //----------------------------------------------------------------------------
90 template <size_t I>
91 constexpr auto get() -> auto& {
92 return std::get<I>(container);
93 }
94 //----------------------------------------------------------------------------
95 template <size_t I>
96 constexpr auto get() const -> const auto& {
97 return std::get<I>(container);
98 }
99};
100//==============================================================================
101template <typename... Ts>
102unpack(std::tuple<Ts...>&& c)->unpack<std::tuple<Ts...>>;
103
104//==============================================================================
105template <typename... Ts>
106struct unpack<const std::tuple<Ts...>> {
107 static constexpr size_t n = sizeof...(Ts);
108 const std::tuple<Ts...>& container;
109 //----------------------------------------------------------------------------
110 explicit constexpr unpack(std::tuple<Ts...>&& c) : container{c} {}
111 //----------------------------------------------------------------------------
112 template <size_t I>
113 constexpr auto get() const -> const auto& {
114 return std::get<I>(container);
115 }
116};
117//==============================================================================
118template <typename... Ts>
119unpack(const std::tuple<Ts...>& c)->unpack<const std::tuple<Ts...>>;
120
121//==============================================================================
122template <typename A, typename B>
123struct unpack<std::pair<A, B>> {
124 static constexpr size_t n = 2;
125 std::pair<A, B>& container;
126 //----------------------------------------------------------------------------
127 explicit constexpr unpack(std::pair<A, B>& c) : container{c} {}
128 //----------------------------------------------------------------------------
129 template <size_t I>
130 constexpr auto get() -> auto& {
131 return std::get<I>(container);
132 }
133 //----------------------------------------------------------------------------
134 template <size_t I>
135 constexpr auto get() const -> const auto& {
136 return std::get<I>(container);
137 }
138};
139//==============================================================================
140template <typename A, typename B>
141unpack(std::pair<A, B>& c)->unpack<std::pair<A, B>>;
142
143//==============================================================================
144template <typename A, typename B>
145struct unpack<const std::pair<A, B>> {
146 static constexpr size_t n = 2;
147 const std::pair<A, B>& container;
148 //----------------------------------------------------------------------------
149 explicit constexpr unpack(std::pair<A, B>&& c) : container{c} {}
150 //----------------------------------------------------------------------------
151 template <size_t I>
152 constexpr auto get() const -> const auto& {
153 return std::get<I>(container);
154 }
155};
156//==============================================================================
157template <typename A, typename B>
158unpack(const std::pair<A, B>& c)->unpack<const std::pair<A, B>>;
159//==============================================================================
160} // namespace tatooine
161//==============================================================================
162#endif
Definition: algorithm.h:6
typename get_impl< Container, I >::type get
Definition: get.h:11
constexpr auto bind(F &&f, Args &&... args)
Binds first arguments of f (either all or only partially).
Definition: bind.h:10
constexpr decltype(auto) invoke_unpacked(F &&f)
All arguments are bound -> just call f.
Definition: invoke_unpacked.h:15
Definition: tuple.h:11
const std::array< T, N > & container
Definition: invoke_unpacked.h:67
constexpr auto get() const -> const auto &
Definition: invoke_unpacked.h:74
constexpr unpack(const std::array< T, N > &c)
Definition: invoke_unpacked.h:70
constexpr auto get() const -> const auto &
Definition: invoke_unpacked.h:152
const std::pair< A, B > & container
Definition: invoke_unpacked.h:147
constexpr unpack(std::pair< A, B > &&c)
Definition: invoke_unpacked.h:149
const std::tuple< Ts... > & container
Definition: invoke_unpacked.h:108
constexpr auto get() const -> const auto &
Definition: invoke_unpacked.h:113
constexpr unpack(std::tuple< Ts... > &&c)
Definition: invoke_unpacked.h:110
std::array< T, N > & container
Definition: invoke_unpacked.h:51
constexpr unpack(std::array< T, N > &c)
Definition: invoke_unpacked.h:53
constexpr auto get() -> auto &
Definition: invoke_unpacked.h:56
constexpr auto get() const -> const auto &
Definition: invoke_unpacked.h:58
constexpr unpack(std::pair< A, B > &c)
Definition: invoke_unpacked.h:127
std::pair< A, B > & container
Definition: invoke_unpacked.h:125
constexpr auto get() const -> const auto &
Definition: invoke_unpacked.h:135
constexpr auto get() -> auto &
Definition: invoke_unpacked.h:130
constexpr auto get() const -> const auto &
Definition: invoke_unpacked.h:96
constexpr auto get() -> auto &
Definition: invoke_unpacked.h:91
std::tuple< Ts... > & container
Definition: invoke_unpacked.h:86
constexpr unpack(std::tuple< Ts... > &&c)
Definition: invoke_unpacked.h:88
Definition: invoke_unpacked.h:11