1/*!
2@file
3Defines `boost::hana::basic_tuple`.
4
5Copyright Louis Dionne 2013-2022
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/ebo.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/integral_constant.hpp>
25#include <boost/hana/fwd/is_empty.hpp>
26#include <boost/hana/fwd/length.hpp>
27#include <boost/hana/fwd/transform.hpp>
28#include <boost/hana/fwd/unpack.hpp>
29
30#include <cstddef>
31#include <type_traits>
32#include <utility>
33
34
35namespace boost { namespace hana {
36 namespace detail {
37 //////////////////////////////////////////////////////////////////////
38 // basic_tuple_impl<n, Xn>
39 //////////////////////////////////////////////////////////////////////
40 template <std::size_t> struct bti; // basic_tuple_index
41
42 struct from_other { };
43
44 template <typename Indices, typename ...Xn>
45#ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
46 struct __declspec(empty_bases) basic_tuple_impl;
47#else
48 struct basic_tuple_impl;
49#endif
50
51 template <std::size_t ...n, typename ...Xn>
52#ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
53 struct __declspec(empty_bases) basic_tuple_impl<std::index_sequence<n...>, Xn...>
54#else
55 struct basic_tuple_impl<std::index_sequence<n...>, Xn...>
56#endif
57 : detail::ebo<bti<n>, Xn>...
58 {
59 static constexpr std::size_t size_ = sizeof...(Xn);
60
61 constexpr basic_tuple_impl() = default;
62
63 template <typename Other>
64 explicit constexpr basic_tuple_impl(detail::from_other, Other&& other)
65 : detail::ebo<bti<n>, Xn>(detail::ebo_get<bti<n>>(static_cast<Other&&>(other)))...
66 { }
67
68 template <typename ...Yn>
69 explicit constexpr basic_tuple_impl(Yn&& ...yn)
70 : detail::ebo<bti<n>, Xn>(static_cast<Yn&&>(yn))...
71 { }
72 };
73 }
74
75 //////////////////////////////////////////////////////////////////////////
76 // basic_tuple
77 //////////////////////////////////////////////////////////////////////////
78 //! @cond
79 template <typename ...Xn>
80 struct basic_tuple final
81 : detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>
82 {
83 using Base = detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>;
84
85 constexpr basic_tuple() = default;
86
87 // copy constructor
88 template <typename Other, typename = typename std::enable_if<
89 std::is_same<typename detail::decay<Other>::type, basic_tuple>::value
90 >::type>
91 constexpr basic_tuple(Other&& other)
92 : Base(detail::from_other{}, static_cast<Other&&>(other))
93 { }
94
95 template <typename ...Yn>
96 explicit constexpr basic_tuple(Yn&& ...yn)
97 : Base(static_cast<Yn&&>(yn)...)
98 { }
99 };
100 //! @endcond
101
102 template <typename ...Xn>
103 struct tag_of<basic_tuple<Xn...>> {
104 using type = basic_tuple_tag;
105 };
106
107 //////////////////////////////////////////////////////////////////////////
108 // Foldable
109 //////////////////////////////////////////////////////////////////////////
110 template <>
111 struct unpack_impl<basic_tuple_tag> {
112 template <std::size_t ...i, typename ...Xn, typename F>
113 static constexpr decltype(auto)
114 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F&& f) {
115 return static_cast<F&&>(f)(
116 detail::ebo_get<detail::bti<i>>(
117 static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs)
118 )...
119 );
120 }
121
122 template <std::size_t ...i, typename ...Xn, typename F>
123 static constexpr decltype(auto)
124 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F&& f) {
125 return static_cast<F&&>(f)(
126 detail::ebo_get<detail::bti<i>>(
127 static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs)
128 )...
129 );
130 }
131
132 template <std::size_t ...i, typename ...Xn, typename F>
133 static constexpr decltype(auto)
134 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F&& f) {
135 return static_cast<F&&>(f)(
136 detail::ebo_get<detail::bti<i>>(
137 static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs)
138 )...
139 );
140 }
141 };
142
143 //////////////////////////////////////////////////////////////////////////
144 // Functor
145 //////////////////////////////////////////////////////////////////////////
146 template <>
147 struct transform_impl<basic_tuple_tag> {
148 template <std::size_t ...i, typename ...Xn, typename F>
149 static constexpr auto
150 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F const& f) {
151 return hana::make_basic_tuple(
152 f(detail::ebo_get<detail::bti<i>>(
153 static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs)
154 ))...
155 );
156 }
157
158 template <std::size_t ...i, typename ...Xn, typename F>
159 static constexpr auto
160 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F const& f) {
161 return hana::make_basic_tuple(
162 f(detail::ebo_get<detail::bti<i>>(
163 static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs)
164 ))...
165 );
166 }
167
168 template <std::size_t ...i, typename ...Xn, typename F>
169 static constexpr auto
170 apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F const& f) {
171 return hana::make_basic_tuple(
172 f(detail::ebo_get<detail::bti<i>>(
173 static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs)
174 ))...
175 );
176 }
177 };
178
179 //////////////////////////////////////////////////////////////////////////
180 // Iterable
181 //////////////////////////////////////////////////////////////////////////
182 template <>
183 struct at_impl<basic_tuple_tag> {
184 template <typename Xs, typename N>
185 static constexpr decltype(auto) apply(Xs&& xs, N const&) {
186 constexpr std::size_t index = N::value;
187 return detail::ebo_get<detail::bti<index>>(static_cast<Xs&&>(xs));
188 }
189 };
190
191 template <>
192 struct drop_front_impl<basic_tuple_tag> {
193 template <std::size_t N, typename Xs, std::size_t ...i>
194 static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
195 return hana::make_basic_tuple(
196 detail::ebo_get<detail::bti<i+N>>(static_cast<Xs&&>(xs))...
197 );
198 }
199
200 template <typename Xs, typename N>
201 static constexpr auto apply(Xs&& xs, N const&) {
202 constexpr std::size_t len = detail::decay<Xs>::type::size_;
203 return drop_front_helper<N::value>(static_cast<Xs&&>(xs), std::make_index_sequence<
204 (N::value < len) ? len - N::value : 0
205 >{});
206 }
207 };
208
209 template <>
210 struct is_empty_impl<basic_tuple_tag> {
211 template <typename ...Xs>
212 static constexpr hana::bool_<sizeof...(Xs) == 0>
213 apply(basic_tuple<Xs...> const&)
214 { return {}; }
215 };
216
217 // compile-time optimizations (to reduce the # of function instantiations)
218 template <std::size_t n, typename ...Xs>
219 constexpr decltype(auto) at_c(basic_tuple<Xs...> const& xs) {
220 return detail::ebo_get<detail::bti<n>>(xs);
221 }
222
223 template <std::size_t n, typename ...Xs>
224 constexpr decltype(auto) at_c(basic_tuple<Xs...>& xs) {
225 return detail::ebo_get<detail::bti<n>>(xs);
226 }
227
228 template <std::size_t n, typename ...Xs>
229 constexpr decltype(auto) at_c(basic_tuple<Xs...>&& xs) {
230 return detail::ebo_get<detail::bti<n>>(static_cast<basic_tuple<Xs...>&&>(xs));
231 }
232
233 //////////////////////////////////////////////////////////////////////////
234 // Sequence
235 //////////////////////////////////////////////////////////////////////////
236 template <>
237 struct Sequence<basic_tuple_tag> {
238 static constexpr bool value = true;
239 };
240
241 template <>
242 struct make_impl<basic_tuple_tag> {
243 template <typename ...Xn>
244 static constexpr basic_tuple<typename detail::decay<Xn>::type...>
245 apply(Xn&& ...xn) {
246 return basic_tuple<typename detail::decay<Xn>::type...>{
247 static_cast<Xn&&>(xn)...
248 };
249 }
250 };
251
252 //////////////////////////////////////////////////////////////////////////
253 // length
254 //////////////////////////////////////////////////////////////////////////
255 template <>
256 struct length_impl<basic_tuple_tag> {
257 template <typename ...Xn>
258 static constexpr auto apply(basic_tuple<Xn...> const&) {
259 return hana::size_t<sizeof...(Xn)>{};
260 }
261 };
262}} // end namespace boost::hana
263
264#endif // !BOOST_HANA_BASIC_TUPLE_HPP
265

source code of boost/libs/hana/include/boost/hana/basic_tuple.hpp