/*! @file Defines `boost::hana::detail::ebo`. @copyright Louis Dionne 2013-2016 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_HANA_DETAIL_EBO_HPP #define BOOST_HANA_DETAIL_EBO_HPP #include #include namespace _hana { ////////////////////////////////////////////////////////////////////////// // ebo // // Building block to implement the Empty Base Optimization (EBO). We // use a short name and define it in a short namespace to reduce // symbol lengths, since this type is used as a building block for // other widely used types such as `hana::pair`. // // When available, we use compiler intrinsics to reduce the number // of instantiations. // // `ebo` provides a limited set of constructors to reduce instantiations. // Also, the constructors are open-ended and they do not check for the // validity of their arguments, again to reduce compile-time costs. // Users of `ebo` should make sure that they only try to construct an // `ebo` from a compatible value. // // EBOs can be indexed using an arbitrary type. The recommended usage is // to define an integrap constant wrapper for the specific container using // EBO, and then index using that wrapper: // // template struct idx; // wrapper for tuple // template // struct tuple : ebo, T0>, ebo, T1>, ... { }; // // The reason for defining one wrapper per container is to avoid any issues // that can arise when using `ebo_get`, which casts to the base class. If // `tuple` and `pair` are inheritting from `ebo`s with the same indexing // scheme, trying to use `ebo_get` on a tuple of pairs will trigger an // ambiguous base class conversion, since both tuple and pair inherit // from `ebo`s with the same keys. ////////////////////////////////////////////////////////////////////////// template struct ebo; // Specialize storage for empty types template struct ebo : V { constexpr ebo() { } template explicit constexpr ebo(T&& t) : V(static_cast(t)) { } }; // Specialize storage for non-empty types template struct ebo { constexpr ebo() : data_() { } template explicit constexpr ebo(T&& t) : data_(static_cast(t)) { } V data_; }; ////////////////////////////////////////////////////////////////////////// // ebo_get ////////////////////////////////////////////////////////////////////////// template constexpr V const& ebo_get(ebo const& x) { return x; } template constexpr V& ebo_get(ebo& x) { return x; } template constexpr V&& ebo_get(ebo&& x) { return static_cast(x); } template constexpr V const& ebo_get(ebo const& x) { return x.data_; } template constexpr V& ebo_get(ebo& x) { return x.data_; } template constexpr V&& ebo_get(ebo&& x) { return static_cast(x.data_); } } // end namespace _hana BOOST_HANA_NAMESPACE_BEGIN namespace detail { using ::_hana::ebo; using ::_hana::ebo_get; } BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_DETAIL_EBO_HPP