]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/basic_tuple.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / basic_tuple.hpp
1 /*!
2 @file
3 Defines `boost::hana::basic_tuple`.
4
5 @copyright Louis Dionne 2013-2016
6 Distributed 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
38 BOOST_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
298 BOOST_HANA_NAMESPACE_END
299
300 #endif // !BOOST_HANA_BASIC_TUPLE_HPP