diff options
Diffstat (limited to 'boost/hana/basic_tuple.hpp')
-rw-r--r-- | boost/hana/basic_tuple.hpp | 129 |
1 files changed, 45 insertions, 84 deletions
diff --git a/boost/hana/basic_tuple.hpp b/boost/hana/basic_tuple.hpp index 8651e464bf..dbc762fb1b 100644 --- a/boost/hana/basic_tuple.hpp +++ b/boost/hana/basic_tuple.hpp @@ -2,7 +2,7 @@ @file Defines `boost::hana::basic_tuple`. -@copyright Louis Dionne 2013-2016 +@copyright Louis Dionne 2013-2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ @@ -14,7 +14,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/hana/config.hpp> #include <boost/hana/detail/decay.hpp> -#include <boost/hana/detail/intrinsics.hpp> +#include <boost/hana/detail/ebo.hpp> #include <boost/hana/fwd/at.hpp> #include <boost/hana/fwd/bool.hpp> #include <boost/hana/fwd/concept/sequence.hpp> @@ -38,79 +38,10 @@ Distributed under the Boost Software License, Version 1.0. BOOST_HANA_NAMESPACE_BEGIN namespace detail { ////////////////////////////////////////////////////////////////////// - // elt<n, Xn> - // - // `elt` stands for `tuple_element`; the name is compressed to reduce - // symbol lengths. - // - // Wrapper holding the actual elements of a tuple. It takes care of - // optimizing the storage for empty types. - // - // When available, we use compiler intrinsics to reduce the number - // of instantiations. - ////////////////////////////////////////////////////////////////////// - template <std::size_t n, typename Xn, bool = - BOOST_HANA_TT_IS_EMPTY(Xn) && !BOOST_HANA_TT_IS_FINAL(Xn) - > - struct elt; - - // Specialize storage for empty types - template <std::size_t n, typename Xn> - struct elt<n, Xn, true> : Xn { - constexpr elt() = default; - - template <typename Yn> - explicit constexpr elt(Yn&& yn) - : Xn(static_cast<Yn&&>(yn)) - { } - }; - - // Specialize storage for non-empty types - template <std::size_t n, typename Xn> - struct elt<n, Xn, false> { - constexpr elt() = default; - - template <typename Yn> - explicit constexpr elt(Yn&& yn) - : data_(static_cast<Yn&&>(yn)) - { } - - Xn data_; - }; - } - - ////////////////////////////////////////////////////////////////////////// - // get_impl - ////////////////////////////////////////////////////////////////////////// - template <std::size_t n, typename Xn> - constexpr Xn const& get_impl(detail::elt<n, Xn, true> const& xn) - { return xn; } - - template <std::size_t n, typename Xn> - constexpr Xn& get_impl(detail::elt<n, Xn, true>& xn) - { return xn; } - - template <std::size_t n, typename Xn> - constexpr Xn&& get_impl(detail::elt<n, Xn, true>&& xn) - { return static_cast<Xn&&>(xn); } - - - template <std::size_t n, typename Xn> - constexpr Xn const& get_impl(detail::elt<n, Xn, false> const& xn) - { return xn.data_; } - - template <std::size_t n, typename Xn> - constexpr Xn& get_impl(detail::elt<n, Xn, false>& xn) - { return xn.data_; } - - template <std::size_t n, typename Xn> - constexpr Xn&& get_impl(detail::elt<n, Xn, false>&& xn) - { return static_cast<Xn&&>(xn.data_); } - - namespace detail { - ////////////////////////////////////////////////////////////////////// // basic_tuple_impl<n, Xn> ////////////////////////////////////////////////////////////////////// + template <std::size_t> struct bti; // basic_tuple_index + struct from_other { }; template <typename Indices, typename ...Xn> @@ -118,7 +49,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <std::size_t ...n, typename ...Xn> struct basic_tuple_impl<std::index_sequence<n...>, Xn...> - : detail::elt<n, Xn>... + : detail::ebo<bti<n>, Xn>... { static constexpr std::size_t size_ = sizeof...(Xn); @@ -126,12 +57,12 @@ BOOST_HANA_NAMESPACE_BEGIN template <typename Other> explicit constexpr basic_tuple_impl(detail::from_other, Other&& other) - : detail::elt<n, Xn>(get_impl<n>(static_cast<Other&&>(other)))... + : detail::ebo<bti<n>, Xn>(detail::ebo_get<bti<n>>(static_cast<Other&&>(other)))... { } template <typename ...Yn> explicit constexpr basic_tuple_impl(Yn&& ...yn) - : detail::elt<n, Xn>(static_cast<Yn&&>(yn))... + : detail::ebo<bti<n>, Xn>(static_cast<Yn&&>(yn))... { } }; } @@ -177,7 +108,9 @@ BOOST_HANA_NAMESPACE_BEGIN static constexpr decltype(auto) apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F&& f) { return static_cast<F&&>(f)( - get_impl<i>(static_cast<detail::elt<i, Xn> const&>(xs))... + detail::ebo_get<detail::bti<i>>( + static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs) + )... ); } @@ -185,7 +118,9 @@ BOOST_HANA_NAMESPACE_BEGIN static constexpr decltype(auto) apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F&& f) { return static_cast<F&&>(f)( - get_impl<i>(static_cast<detail::elt<i, Xn>&>(xs))... + detail::ebo_get<detail::bti<i>>( + static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs) + )... ); } @@ -193,7 +128,9 @@ BOOST_HANA_NAMESPACE_BEGIN static constexpr decltype(auto) apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F&& f) { return static_cast<F&&>(f)( - get_impl<i>(static_cast<detail::elt<i, Xn>&&>(xs))... + detail::ebo_get<detail::bti<i>>( + static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs) + )... ); } }; @@ -207,7 +144,9 @@ BOOST_HANA_NAMESPACE_BEGIN static constexpr auto apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F const& f) { return hana::make_basic_tuple( - f(get_impl<i>(static_cast<detail::elt<i, Xn> const&>(xs)))... + f(detail::ebo_get<detail::bti<i>>( + static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs) + ))... ); } @@ -215,7 +154,9 @@ BOOST_HANA_NAMESPACE_BEGIN static constexpr auto apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F const& f) { return hana::make_basic_tuple( - f(get_impl<i>(static_cast<detail::elt<i, Xn>&>(xs)))... + f(detail::ebo_get<detail::bti<i>>( + static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs) + ))... ); } @@ -223,7 +164,9 @@ BOOST_HANA_NAMESPACE_BEGIN static constexpr auto apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F const& f) { return hana::make_basic_tuple( - f(get_impl<i>(static_cast<detail::elt<i, Xn>&&>(xs)))... + f(detail::ebo_get<detail::bti<i>>( + static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs) + ))... ); } }; @@ -236,7 +179,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <typename Xs, typename N> static constexpr decltype(auto) apply(Xs&& xs, N const&) { constexpr std::size_t index = N::value; - return hana::get_impl<index>(static_cast<Xs&&>(xs)); + return detail::ebo_get<detail::bti<index>>(static_cast<Xs&&>(xs)); } }; @@ -244,7 +187,9 @@ BOOST_HANA_NAMESPACE_BEGIN struct drop_front_impl<basic_tuple_tag> { template <std::size_t N, typename Xs, std::size_t ...i> static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) { - return hana::make_basic_tuple(hana::get_impl<i+N>(static_cast<Xs&&>(xs))...); + return hana::make_basic_tuple( + detail::ebo_get<detail::bti<i+N>>(static_cast<Xs&&>(xs))... + ); } template <typename Xs, typename N> @@ -264,6 +209,22 @@ BOOST_HANA_NAMESPACE_BEGIN { return {}; } }; + // compile-time optimizations (to reduce the # of function instantiations) + template <std::size_t n, typename ...Xs> + constexpr decltype(auto) at_c(basic_tuple<Xs...> const& xs) { + return detail::ebo_get<detail::bti<n>>(xs); + } + + template <std::size_t n, typename ...Xs> + constexpr decltype(auto) at_c(basic_tuple<Xs...>& xs) { + return detail::ebo_get<detail::bti<n>>(xs); + } + + template <std::size_t n, typename ...Xs> + constexpr decltype(auto) at_c(basic_tuple<Xs...>&& xs) { + return detail::ebo_get<detail::bti<n>>(static_cast<basic_tuple<Xs...>&&>(xs)); + } + ////////////////////////////////////////////////////////////////////////// // Sequence ////////////////////////////////////////////////////////////////////////// |