@@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
15
15
#include < boost/hana/config.hpp>
16
16
#include < boost/hana/detail/decay.hpp>
17
17
#include < boost/hana/detail/ebo.hpp>
18
+ #include < boost/hana/detail/type_at.hpp>
18
19
#include < boost/hana/fwd/at.hpp>
19
20
#include < boost/hana/fwd/bool.hpp>
20
21
#include < boost/hana/fwd/concept/sequence.hpp>
@@ -72,7 +73,7 @@ BOOST_HANA_NAMESPACE_BEGIN
72
73
// ////////////////////////////////////////////////////////////////////////
73
74
// ! @cond
74
75
template <typename ...Xn>
75
- struct basic_tuple final
76
+ struct basic_tuple
76
77
: detail::basic_tuple_impl<std::make_index_sequence<sizeof ...(Xn)>, Xn...>
77
78
{
78
79
using Base = detail::basic_tuple_impl<std::make_index_sequence<sizeof ...(Xn)>, Xn...>;
@@ -176,28 +177,75 @@ BOOST_HANA_NAMESPACE_BEGIN
176
177
// ////////////////////////////////////////////////////////////////////////
177
178
template <>
178
179
struct at_impl <basic_tuple_tag> {
179
- template <typename Xs, typename N>
180
- static constexpr decltype (auto ) apply(Xs&& xs, N const &) {
180
+ template <typename ...T, typename N>
181
+ static constexpr decltype (auto ) apply(hana::basic_tuple<T...>& xs, N const &) {
182
+ constexpr std::size_t index = N::value;
183
+ using Nth = typename detail::type_at<index , T...>::type;
184
+ return detail::ebo_get<detail::bti<index >>(
185
+ static_cast <detail::ebo<detail::bti<index >, Nth>&>(xs)
186
+ );
187
+ }
188
+
189
+ template <typename ...T, typename N>
190
+ static constexpr decltype (auto ) apply(hana::basic_tuple<T...>&& xs, N const &) {
181
191
constexpr std::size_t index = N::value;
182
- return detail::ebo_get<detail::bti<index >>(static_cast <Xs&&>(xs));
192
+ using Nth = typename detail::type_at<index , T...>::type;
193
+ return detail::ebo_get<detail::bti<index >>(
194
+ static_cast <detail::ebo<detail::bti<index >, Nth>&&>(xs)
195
+ );
196
+ }
197
+
198
+ template <typename ...T, typename N>
199
+ static constexpr decltype (auto ) apply(hana::basic_tuple<T...> const & xs, N const &) {
200
+ constexpr std::size_t index = N::value;
201
+ using Nth = typename detail::type_at<index , T...>::type;
202
+ return detail::ebo_get<detail::bti<index >>(
203
+ static_cast <detail::ebo<detail::bti<index >, Nth> const &>(xs)
204
+ );
183
205
}
184
206
};
185
207
186
208
template <>
187
209
struct drop_front_impl <basic_tuple_tag> {
188
- template <std::size_t N, typename Xs, std::size_t ...i>
189
- static constexpr auto drop_front_helper (Xs&& xs, std::index_sequence<i...>) {
210
+ template <std::size_t N, typename ...Xs, std::size_t ...i>
211
+ static constexpr auto
212
+ drop_front_helper (hana::basic_tuple<Xs...>&& xs, std::index_sequence<i...>) {
190
213
return hana::make_basic_tuple (
191
- detail::ebo_get<detail::bti<i+N>>(static_cast <Xs&&>(xs))...
214
+ detail::ebo_get<detail::bti<i+N>>(
215
+ static_cast <detail::ebo<
216
+ detail::bti<i+N>, typename detail::type_at<i+N, Xs...>::type
217
+ >&&>(xs)
218
+ )...
219
+ );
220
+ }
221
+ template <std::size_t N, typename ...Xs, std::size_t ...i>
222
+ static constexpr auto
223
+ drop_front_helper (hana::basic_tuple<Xs...>& xs, std::index_sequence<i...>) {
224
+ return hana::make_basic_tuple (
225
+ detail::ebo_get<detail::bti<i+N>>(
226
+ static_cast <detail::ebo<
227
+ detail::bti<i+N>, typename detail::type_at<i+N, Xs...>::type
228
+ >&>(xs)
229
+ )...
230
+ );
231
+ }
232
+ template <std::size_t N, typename ...Xs, std::size_t ...i>
233
+ static constexpr auto
234
+ drop_front_helper (hana::basic_tuple<Xs...> const & xs, std::index_sequence<i...>) {
235
+ return hana::make_basic_tuple (
236
+ detail::ebo_get<detail::bti<i+N>>(
237
+ static_cast <detail::ebo<
238
+ detail::bti<i+N>, typename detail::type_at<i+N, Xs...>::type
239
+ > const &>(xs)
240
+ )...
192
241
);
193
242
}
194
243
195
244
template <typename Xs, typename N>
196
245
static constexpr auto apply (Xs&& xs, N const &) {
197
246
constexpr std::size_t len = detail::decay<Xs>::type::size_;
198
- return drop_front_helper<N::value>(static_cast <Xs&&>(xs), std::make_index_sequence<
199
- N::value < len ? len - N::value : 0
200
- >{});
247
+ using Indices = std::make_index_sequence<N::value < len ? len - N::value : 0 >;
248
+ return drop_front_helper<N::value>(static_cast <Xs&&>(xs), Indices{});
201
249
}
202
250
};
203
251
@@ -212,17 +260,26 @@ BOOST_HANA_NAMESPACE_BEGIN
212
260
// compile-time optimizations (to reduce the # of function instantiations)
213
261
template <std::size_t n, typename ...Xs>
214
262
constexpr decltype (auto ) at_c(basic_tuple<Xs...> const & xs) {
215
- return detail::ebo_get<detail::bti<n>>(xs);
263
+ using Nth = typename detail::type_at<n, Xs...>::type;
264
+ return detail::ebo_get<detail::bti<n>>(
265
+ static_cast <detail::ebo<detail::bti<n>, Nth> const &>(xs)
266
+ );
216
267
}
217
268
218
269
template <std::size_t n, typename ...Xs>
219
270
constexpr decltype (auto ) at_c(basic_tuple<Xs...>& xs) {
220
- return detail::ebo_get<detail::bti<n>>(xs);
271
+ using Nth = typename detail::type_at<n, Xs...>::type;
272
+ return detail::ebo_get<detail::bti<n>>(
273
+ static_cast <detail::ebo<detail::bti<n>, Nth>&>(xs)
274
+ );
221
275
}
222
276
223
277
template <std::size_t n, typename ...Xs>
224
278
constexpr decltype (auto ) at_c(basic_tuple<Xs...>&& xs) {
225
- return detail::ebo_get<detail::bti<n>>(static_cast <basic_tuple<Xs...>&&>(xs));
279
+ using Nth = typename detail::type_at<n, Xs...>::type;
280
+ return detail::ebo_get<detail::bti<n>>(
281
+ static_cast <detail::ebo<detail::bti<n>, Nth>&&>(xs)
282
+ );
226
283
}
227
284
228
285
// ////////////////////////////////////////////////////////////////////////
0 commit comments