]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/hana/tuple.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / hana / tuple.hpp
CommitLineData
7c673cae
FG
1/*!
2@file
3Defines `boost::hana::tuple`.
4
b32b8144
FG
5@copyright Louis Dionne 2013-2017
6@copyright Jason Rice 2017
7c673cae
FG
7Distributed under the Boost Software License, Version 1.0.
8(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
9 */
10
11#ifndef BOOST_HANA_TUPLE_HPP
12#define BOOST_HANA_TUPLE_HPP
13
14#include <boost/hana/fwd/tuple.hpp>
15
16#include <boost/hana/basic_tuple.hpp>
17#include <boost/hana/bool.hpp>
18#include <boost/hana/config.hpp>
19#include <boost/hana/detail/decay.hpp>
20#include <boost/hana/detail/fast_and.hpp>
21#include <boost/hana/detail/index_if.hpp>
22#include <boost/hana/detail/intrinsics.hpp>
23#include <boost/hana/detail/operators/adl.hpp>
24#include <boost/hana/detail/operators/comparable.hpp>
25#include <boost/hana/detail/operators/iterable.hpp>
26#include <boost/hana/detail/operators/monad.hpp>
27#include <boost/hana/detail/operators/orderable.hpp>
28#include <boost/hana/fwd/at.hpp>
29#include <boost/hana/fwd/core/make.hpp>
30#include <boost/hana/fwd/drop_front.hpp>
b32b8144 31#include <boost/hana/fwd/index_if.hpp>
7c673cae
FG
32#include <boost/hana/fwd/is_empty.hpp>
33#include <boost/hana/fwd/length.hpp>
34#include <boost/hana/fwd/optional.hpp>
35#include <boost/hana/fwd/unpack.hpp>
36#include <boost/hana/type.hpp> // required by fwd decl of tuple_t
37
38#include <cstddef>
39#include <type_traits>
40#include <utility>
41
42
43BOOST_HANA_NAMESPACE_BEGIN
44 namespace detail {
45 template <typename Xs, typename Ys, std::size_t ...n>
46 constexpr void assign(Xs& xs, Ys&& ys, std::index_sequence<n...>) {
47 int sequence[] = {int{}, ((void)(
b32b8144 48 hana::at_c<n>(xs) = hana::at_c<n>(static_cast<Ys&&>(ys))
7c673cae
FG
49 ), int{})...};
50 (void)sequence;
51 }
52
53 struct from_index_sequence_t { };
b32b8144
FG
54
55 template <typename Tuple, typename ...Yn>
56 struct is_same_tuple : std::false_type { };
57
58 template <typename Tuple>
59 struct is_same_tuple<typename detail::decay<Tuple>::type, Tuple>
60 : std::true_type
61 { };
62
63 template <bool SameTuple, bool SameNumberOfElements, typename Tuple, typename ...Yn>
64 struct enable_tuple_variadic_ctor;
65
66 template <typename ...Xn, typename ...Yn>
67 struct enable_tuple_variadic_ctor<false, true, hana::tuple<Xn...>, Yn...>
68 : std::enable_if<
69 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Yn&&)...>::value
70 >
71 { };
7c673cae
FG
72 }
73
74 //////////////////////////////////////////////////////////////////////////
75 // tuple
76 //////////////////////////////////////////////////////////////////////////
77 template <>
92f5a8d4
TL
78#ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
79 struct __declspec(empty_bases) tuple<> final
80#else
81 struct tuple<> final
82#endif
7c673cae
FG
83 : detail::operators::adl<tuple<>>
84 , detail::iterable_operators<tuple<>>
85 {
86 constexpr tuple() { }
87 using hana_tag = tuple_tag;
88 };
89
90 template <typename ...Xn>
92f5a8d4
TL
91#ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
92 struct __declspec(empty_bases) tuple final
93#else
94 struct tuple final
95#endif
7c673cae
FG
96 : detail::operators::adl<tuple<Xn...>>
97 , detail::iterable_operators<tuple<Xn...>>
98 {
99 basic_tuple<Xn...> storage_;
100 using hana_tag = tuple_tag;
101
102 private:
103 template <typename Other, std::size_t ...n>
104 explicit constexpr tuple(detail::from_index_sequence_t, std::index_sequence<n...>, Other&& other)
b32b8144 105 : storage_(hana::at_c<n>(static_cast<Other&&>(other))...)
7c673cae
FG
106 { }
107
108 public:
109 template <typename ...dummy, typename = typename std::enable_if<
110 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, dummy...)...>::value
111 >::type>
112 constexpr tuple()
113 : storage_()
114 { }
115
116 template <typename ...dummy, typename = typename std::enable_if<
117 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value
118 >::type>
119 constexpr tuple(Xn const& ...xn)
120 : storage_(xn...)
121 { }
122
b32b8144
FG
123 template <typename ...Yn, typename = typename detail::enable_tuple_variadic_ctor<
124 detail::is_same_tuple<tuple, Yn...>::value,
125 sizeof...(Xn) == sizeof...(Yn), tuple, Yn...
7c673cae
FG
126 >::type>
127 constexpr tuple(Yn&& ...yn)
128 : storage_(static_cast<Yn&&>(yn)...)
129 { }
130
131 template <typename ...Yn, typename = typename std::enable_if<
132 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Yn const&)...>::value
133 >::type>
134 constexpr tuple(tuple<Yn...> const& other)
135 : tuple(detail::from_index_sequence_t{},
136 std::make_index_sequence<sizeof...(Xn)>{},
137 other.storage_)
138 { }
139
140 template <typename ...Yn, typename = typename std::enable_if<
141 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Yn&&)...>::value
142 >::type>
143 constexpr tuple(tuple<Yn...>&& other)
144 : tuple(detail::from_index_sequence_t{},
145 std::make_index_sequence<sizeof...(Xn)>{},
146 static_cast<tuple<Yn...>&&>(other).storage_)
147 { }
148
149 // The three following constructors are required to make sure that
150 // the tuple(Yn&&...) constructor is _not_ preferred over the copy
151 // constructor for unary tuples containing a type that is constructible
b32b8144 152 // from tuple<...>. See test/tuple/cnstr.trap.cpp
7c673cae
FG
153 template <typename ...dummy, typename = typename std::enable_if<
154 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value
155 >::type>
156 constexpr tuple(tuple const& other)
157 : tuple(detail::from_index_sequence_t{},
158 std::make_index_sequence<sizeof...(Xn)>{},
159 other.storage_)
160 { }
161
162 template <typename ...dummy, typename = typename std::enable_if<
163 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value
164 >::type>
165 constexpr tuple(tuple& other)
166 : tuple(const_cast<tuple const&>(other))
167 { }
168
169 template <typename ...dummy, typename = typename std::enable_if<
170 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn&&, dummy...)...>::value
171 >::type>
172 constexpr tuple(tuple&& other)
173 : tuple(detail::from_index_sequence_t{},
174 std::make_index_sequence<sizeof...(Xn)>{},
175 static_cast<tuple&&>(other).storage_)
176 { }
177
178
179 template <typename ...Yn, typename = typename std::enable_if<
180 detail::fast_and<BOOST_HANA_TT_IS_ASSIGNABLE(Xn&, Yn const&)...>::value
181 >::type>
182 constexpr tuple& operator=(tuple<Yn...> const& other) {
183 detail::assign(this->storage_, other.storage_,
184 std::make_index_sequence<sizeof...(Xn)>{});
185 return *this;
186 }
187
188 template <typename ...Yn, typename = typename std::enable_if<
189 detail::fast_and<BOOST_HANA_TT_IS_ASSIGNABLE(Xn&, Yn&&)...>::value
190 >::type>
191 constexpr tuple& operator=(tuple<Yn...>&& other) {
192 detail::assign(this->storage_, static_cast<tuple<Yn...>&&>(other).storage_,
193 std::make_index_sequence<sizeof...(Xn)>{});
194 return *this;
195 }
196 };
197
198 //////////////////////////////////////////////////////////////////////////
199 // Operators
200 //////////////////////////////////////////////////////////////////////////
201 namespace detail {
202 template <>
203 struct comparable_operators<tuple_tag> {
204 static constexpr bool value = true;
205 };
206 template <>
207 struct orderable_operators<tuple_tag> {
208 static constexpr bool value = true;
209 };
210 template <>
211 struct monad_operators<tuple_tag> {
212 static constexpr bool value = true;
213 };
214 }
215
216 //////////////////////////////////////////////////////////////////////////
217 // Foldable
218 //////////////////////////////////////////////////////////////////////////
219 template <>
220 struct unpack_impl<tuple_tag> {
221 template <typename F>
222 static constexpr decltype(auto) apply(tuple<>&&, F&& f)
223 { return static_cast<F&&>(f)(); }
224 template <typename F>
225 static constexpr decltype(auto) apply(tuple<>&, F&& f)
226 { return static_cast<F&&>(f)(); }
227 template <typename F>
228 static constexpr decltype(auto) apply(tuple<> const&, F&& f)
229 { return static_cast<F&&>(f)(); }
230
231 template <typename Xs, typename F>
232 static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
233 return hana::unpack(static_cast<Xs&&>(xs).storage_, static_cast<F&&>(f));
234 }
235 };
236
237 template <>
238 struct length_impl<tuple_tag> {
239 template <typename ...Xs>
240 static constexpr auto apply(tuple<Xs...> const&)
241 { return hana::size_c<sizeof...(Xs)>; }
242 };
243
244 //////////////////////////////////////////////////////////////////////////
245 // Iterable
246 //////////////////////////////////////////////////////////////////////////
247 template <>
248 struct at_impl<tuple_tag> {
249 template <typename Xs, typename N>
250 static constexpr decltype(auto) apply(Xs&& xs, N const&) {
251 constexpr std::size_t index = N::value;
b32b8144 252 return hana::at_c<index>(static_cast<Xs&&>(xs).storage_);
7c673cae
FG
253 }
254 };
255
256 template <>
257 struct drop_front_impl<tuple_tag> {
258 template <std::size_t N, typename Xs, std::size_t ...i>
259 static constexpr auto helper(Xs&& xs, std::index_sequence<i...>) {
260 return hana::make<tuple_tag>(hana::at_c<i+N>(static_cast<Xs&&>(xs))...);
261 }
262
263 template <typename Xs, typename N>
264 static constexpr auto apply(Xs&& xs, N const&) {
265 constexpr std::size_t len = decltype(hana::length(xs))::value;
266 return helper<N::value>(static_cast<Xs&&>(xs), std::make_index_sequence<
92f5a8d4 267 (N::value < len) ? len - N::value : 0
7c673cae
FG
268 >{});
269 }
270 };
271
272 template <>
273 struct is_empty_impl<tuple_tag> {
274 template <typename ...Xs>
275 static constexpr auto apply(tuple<Xs...> const&)
276 { return hana::bool_c<sizeof...(Xs) == 0>; }
277 };
278
279 // compile-time optimizations (to reduce the # of function instantiations)
280 template <std::size_t n, typename ...Xs>
281 constexpr decltype(auto) at_c(tuple<Xs...> const& xs) {
b32b8144 282 return hana::at_c<n>(xs.storage_);
7c673cae
FG
283 }
284
285 template <std::size_t n, typename ...Xs>
286 constexpr decltype(auto) at_c(tuple<Xs...>& xs) {
b32b8144 287 return hana::at_c<n>(xs.storage_);
7c673cae
FG
288 }
289
290 template <std::size_t n, typename ...Xs>
291 constexpr decltype(auto) at_c(tuple<Xs...>&& xs) {
b32b8144 292 return hana::at_c<n>(static_cast<tuple<Xs...>&&>(xs).storage_);
7c673cae
FG
293 }
294
b32b8144
FG
295 template <>
296 struct index_if_impl<tuple_tag> {
297 template <typename ...Xs, typename Pred>
298 static constexpr auto apply(tuple<Xs...> const&, Pred const&)
299 -> typename detail::index_if<Pred, Xs...>::type
300 { return {}; }
301 };
302
7c673cae
FG
303 //////////////////////////////////////////////////////////////////////////
304 // Sequence
305 //////////////////////////////////////////////////////////////////////////
306 template <>
307 struct Sequence<tuple_tag> {
308 static constexpr bool value = true;
309 };
310
311 template <>
312 struct make_impl<tuple_tag> {
313 template <typename ...Xs>
314 static constexpr
315 tuple<typename detail::decay<Xs>::type...> apply(Xs&& ...xs)
316 { return {static_cast<Xs&&>(xs)...}; }
317 };
7c673cae
FG
318BOOST_HANA_NAMESPACE_END
319
320#endif // !BOOST_HANA_TUPLE_HPP