]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/include/boost/hana/basic_tuple.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / basic_tuple.hpp
CommitLineData
7c673cae
FG
1/*!
2@file
3Defines `boost::hana::basic_tuple`.
4
5@copyright Louis Dionne 2013-2016
6Distributed under the Boost Software License, Version 1.0.
7(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9
10#ifndef BOOST_HANA_BASIC_TUPLE_HPP
11#define BOOST_HANA_BASIC_TUPLE_HPP
12
13#include <boost/hana/fwd/basic_tuple.hpp>
14
15#include <boost/hana/config.hpp>
16#include <boost/hana/detail/decay.hpp>
17#include <boost/hana/detail/intrinsics.hpp>
18#include <boost/hana/fwd/at.hpp>
19#include <boost/hana/fwd/bool.hpp>
20#include <boost/hana/fwd/concept/sequence.hpp>
21#include <boost/hana/fwd/core/make.hpp>
22#include <boost/hana/fwd/core/tag_of.hpp>
23#include <boost/hana/fwd/drop_front.hpp>
24#include <boost/hana/fwd/is_empty.hpp>
25#include <boost/hana/fwd/transform.hpp>
26#include <boost/hana/fwd/unpack.hpp>
27
28#if 0 //! @todo Until we strip down headers, this includes too much
29#include <boost/hana/fwd/integral_constant.hpp>
30#include <boost/hana/fwd/length.hpp>
31#endif
32
33#include <cstddef>
34#include <type_traits>
35#include <utility>
36
37
38BOOST_HANA_NAMESPACE_BEGIN
39 namespace detail {
40 //////////////////////////////////////////////////////////////////////
41 // elt<n, Xn>
42 //
43 // `elt` stands for `tuple_element`; the name is compressed to reduce
44 // symbol lengths.
45 //
46 // Wrapper holding the actual elements of a tuple. It takes care of
47 // optimizing the storage for empty types.
48 //
49 // When available, we use compiler intrinsics to reduce the number
50 // of instantiations.
51 //////////////////////////////////////////////////////////////////////
52 template <std::size_t n, typename Xn, bool =
53 BOOST_HANA_TT_IS_EMPTY(Xn) && !BOOST_HANA_TT_IS_FINAL(Xn)
54 >
55 struct elt;
56
57 // Specialize storage for empty types
58 template <std::size_t n, typename Xn>
59 struct elt<n, Xn, true> : Xn {
60 constexpr elt() = default;
61
62 template <typename Yn>
63 explicit constexpr elt(Yn&& yn)
64 : Xn(static_cast<Yn&&>(yn))
65 { }
66 };
67
68 // Specialize storage for non-empty types
69 template <std::size_t n, typename Xn>
70 struct elt<n, Xn, false> {
71 constexpr elt() = default;
72
73 template <typename Yn>
74 explicit constexpr elt(Yn&& yn)
75 : data_(static_cast<Yn&&>(yn))
76 { }
77
78 Xn data_;
79 };
80 }
81
82 //////////////////////////////////////////////////////////////////////////
83 // get_impl
84 //////////////////////////////////////////////////////////////////////////
85 template <std::size_t n, typename Xn>
86 constexpr Xn const& get_impl(detail::elt<n, Xn, true> const& xn)
87 { return xn; }
88
89 template <std::size_t n, typename Xn>
90 constexpr Xn& get_impl(detail::elt<n, Xn, true>& xn)
91 { return xn; }
92
93 template <std::size_t n, typename Xn>
94 constexpr Xn&& get_impl(detail::elt<n, Xn, true>&& xn)
95 { return static_cast<Xn&&>(xn); }
96
97
98 template <std::size_t n, typename Xn>
99 constexpr Xn const& get_impl(detail::elt<n, Xn, false> const& xn)
100 { return xn.data_; }
101
102 template <std::size_t n, typename Xn>
103 constexpr Xn& get_impl(detail::elt<n, Xn, false>& xn)
104 { return xn.data_; }
105
106 template <std::size_t n, typename Xn>
107 constexpr Xn&& get_impl(detail::elt<n, Xn, false>&& xn)
108 { return static_cast<Xn&&>(xn.data_); }
109
110 namespace detail {
111 //////////////////////////////////////////////////////////////////////
112 // basic_tuple_impl<n, Xn>
113 //////////////////////////////////////////////////////////////////////
114 struct from_other { };
115
116 template <typename Indices, typename ...Xn>
117 struct basic_tuple_impl;
118
119 template <std::size_t ...n, typename ...Xn>
120 struct basic_tuple_impl<std::index_sequence<n...>, Xn...>
121 : detail::elt<n, Xn>...
122 {
123 static constexpr std::size_t size_ = sizeof...(Xn);
124
125 constexpr basic_tuple_impl() = default;
126
127 template <typename Other>
128 explicit constexpr basic_tuple_impl(detail::from_other, Other&& other)
129 : detail::elt<n, Xn>(get_impl<n>(static_cast<Other&&>(other)))...
130 { }
131
132 template <typename ...Yn>
133 explicit constexpr basic_tuple_impl(Yn&& ...yn)
134 : detail::elt<n, Xn>(static_cast<Yn&&>(yn))...
135 { }
136 };
137 }
138
139 //////////////////////////////////////////////////////////////////////////
140 // basic_tuple
141 //////////////////////////////////////////////////////////////////////////
142 //! @cond
143 template <typename ...Xn>
144 struct basic_tuple final
145 : detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>
146 {
147 using Base = detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>;
148
149 constexpr basic_tuple() = default;
150
151 // copy constructor
152 template <typename Other, typename = typename std::enable_if<
153 std::is_same<typename detail::decay<Other>::type, basic_tuple>::value
154 >::type>
155 constexpr basic_tuple(Other&& other)
156 : Base(detail::from_other{}, static_cast<Other&&>(other))
157 { }
158
159 template <typename ...Yn>
160 explicit constexpr basic_tuple(Yn&& ...yn)
161 : Base(static_cast<Yn&&>(yn)...)
162 { }
163 };
164 //! @endcond
165
166 template <typename ...Xn>
167 struct tag_of<basic_tuple<Xn...>> {
168 using type = basic_tuple_tag;
169 };
170
171 //////////////////////////////////////////////////////////////////////////
172 // Foldable
173 //////////////////////////////////////////////////////////////////////////
174 template <>
175 struct unpack_impl<basic_tuple_tag> {
176 template <std::size_t ...i, typename ...Xn, typename F>
177 static constexpr decltype(auto)
178 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F&& f) {
179 return static_cast<F&&>(f)(
180 get_impl<i>(static_cast<detail::elt<i, Xn> const&>(xs))...
181 );
182 }
183
184 template <std::size_t ...i, typename ...Xn, typename F>
185 static constexpr decltype(auto)
186 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F&& f) {
187 return static_cast<F&&>(f)(
188 get_impl<i>(static_cast<detail::elt<i, Xn>&>(xs))...
189 );
190 }
191
192 template <std::size_t ...i, typename ...Xn, typename F>
193 static constexpr decltype(auto)
194 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F&& f) {
195 return static_cast<F&&>(f)(
196 get_impl<i>(static_cast<detail::elt<i, Xn>&&>(xs))...
197 );
198 }
199 };
200
201 //////////////////////////////////////////////////////////////////////////
202 // Functor
203 //////////////////////////////////////////////////////////////////////////
204 template <>
205 struct transform_impl<basic_tuple_tag> {
206 template <std::size_t ...i, typename ...Xn, typename F>
207 static constexpr auto
208 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F const& f) {
209 return hana::make_basic_tuple(
210 f(get_impl<i>(static_cast<detail::elt<i, Xn> const&>(xs)))...
211 );
212 }
213
214 template <std::size_t ...i, typename ...Xn, typename F>
215 static constexpr auto
216 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F const& f) {
217 return hana::make_basic_tuple(
218 f(get_impl<i>(static_cast<detail::elt<i, Xn>&>(xs)))...
219 );
220 }
221
222 template <std::size_t ...i, typename ...Xn, typename F>
223 static constexpr auto
224 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F const& f) {
225 return hana::make_basic_tuple(
226 f(get_impl<i>(static_cast<detail::elt<i, Xn>&&>(xs)))...
227 );
228 }
229 };
230
231 //////////////////////////////////////////////////////////////////////////
232 // Iterable
233 //////////////////////////////////////////////////////////////////////////
234 template <>
235 struct at_impl<basic_tuple_tag> {
236 template <typename Xs, typename N>
237 static constexpr decltype(auto) apply(Xs&& xs, N const&) {
238 constexpr std::size_t index = N::value;
239 return hana::get_impl<index>(static_cast<Xs&&>(xs));
240 }
241 };
242
243 template <>
244 struct drop_front_impl<basic_tuple_tag> {
245 template <std::size_t N, typename Xs, std::size_t ...i>
246 static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
247 return hana::make_basic_tuple(hana::get_impl<i+N>(static_cast<Xs&&>(xs))...);
248 }
249
250 template <typename Xs, typename N>
251 static constexpr auto apply(Xs&& xs, N const&) {
252 constexpr std::size_t len = detail::decay<Xs>::type::size_;
253 return drop_front_helper<N::value>(static_cast<Xs&&>(xs), std::make_index_sequence<
254 N::value < len ? len - N::value : 0
255 >{});
256 }
257 };
258
259 template <>
260 struct is_empty_impl<basic_tuple_tag> {
261 template <typename ...Xs>
262 static constexpr hana::bool_<sizeof...(Xs) == 0>
263 apply(basic_tuple<Xs...> const&)
264 { return {}; }
265 };
266
267 //////////////////////////////////////////////////////////////////////////
268 // Sequence
269 //////////////////////////////////////////////////////////////////////////
270 template <>
271 struct Sequence<basic_tuple_tag> {
272 static constexpr bool value = true;
273 };
274
275 template <>
276 struct make_impl<basic_tuple_tag> {
277 template <typename ...Xn>
278 static constexpr basic_tuple<typename detail::decay<Xn>::type...>
279 apply(Xn&& ...xn) {
280 return basic_tuple<typename detail::decay<Xn>::type...>{
281 static_cast<Xn&&>(xn)...
282 };
283 }
284 };
285
286#if 0
287 //////////////////////////////////////////////////////////////////////////
288 // length
289 //////////////////////////////////////////////////////////////////////////
290 template <>
291 struct length_impl<basic_tuple_tag> {
292 template <typename ...Xn>
293 static constexpr auto apply(basic_tuple<Xn...> const&) {
294 return hana::size_c<sizeof...(Xn)>;
295 }
296 };
297#endif
298BOOST_HANA_NAMESPACE_END
299
300#endif // !BOOST_HANA_BASIC_TUPLE_HPP