summaryrefslogtreecommitdiff
path: root/boost/hana/basic_tuple.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/hana/basic_tuple.hpp')
-rw-r--r--boost/hana/basic_tuple.hpp129
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
//////////////////////////////////////////////////////////////////////////