@@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
1515#include < boost/hana/config.hpp>
1616#include < boost/hana/detail/decay.hpp>
1717#include < boost/hana/detail/ebo.hpp>
18+ #include < boost/hana/detail/type_at.hpp>
1819#include < boost/hana/fwd/at.hpp>
1920#include < boost/hana/fwd/bool.hpp>
2021#include < boost/hana/fwd/concept/sequence.hpp>
@@ -72,7 +73,7 @@ BOOST_HANA_NAMESPACE_BEGIN
7273 // ////////////////////////////////////////////////////////////////////////
7374 // ! @cond
7475 template <typename ...Xn>
75- struct basic_tuple final
76+ struct basic_tuple
7677 : detail::basic_tuple_impl<std::make_index_sequence<sizeof ...(Xn)>, Xn...>
7778 {
7879 using Base = detail::basic_tuple_impl<std::make_index_sequence<sizeof ...(Xn)>, Xn...>;
@@ -176,28 +177,75 @@ BOOST_HANA_NAMESPACE_BEGIN
176177 // ////////////////////////////////////////////////////////////////////////
177178 template <>
178179 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 &) {
181191 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+ );
183205 }
184206 };
185207
186208 template <>
187209 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...>) {
190213 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+ )...
192241 );
193242 }
194243
195244 template <typename Xs, typename N>
196245 static constexpr auto apply (Xs&& xs, N const &) {
197246 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{});
201249 }
202250 };
203251
@@ -212,17 +260,26 @@ BOOST_HANA_NAMESPACE_BEGIN
212260 // compile-time optimizations (to reduce the # of function instantiations)
213261 template <std::size_t n, typename ...Xs>
214262 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+ );
216267 }
217268
218269 template <std::size_t n, typename ...Xs>
219270 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+ );
221275 }
222276
223277 template <std::size_t n, typename ...Xs>
224278 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+ );
226283 }
227284
228285 // ////////////////////////////////////////////////////////////////////////
0 commit comments