Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:52:46

0001 /*!
0002 @file
0003 Defines `boost::hana::detail::ebo`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_DETAIL_EBO_HPP
0011 #define BOOST_HANA_DETAIL_EBO_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 #include <boost/hana/detail/intrinsics.hpp>
0015 
0016 
0017 namespace _hana {
0018     //////////////////////////////////////////////////////////////////////////
0019     // ebo<K, V>
0020     //
0021     // Building block to implement the Empty Base Optimization (EBO). We
0022     // use a short name and define it in a short namespace to reduce
0023     // symbol lengths, since this type is used as a building block for
0024     // other widely used types such as `hana::pair`.
0025     //
0026     // When available, we use compiler intrinsics to reduce the number
0027     // of instantiations.
0028     //
0029     // `ebo` provides a limited set of constructors to reduce instantiations.
0030     // Also, the constructors are open-ended and they do not check for the
0031     // validity of their arguments, again to reduce compile-time costs.
0032     // Users of `ebo` should make sure that they only try to construct an
0033     // `ebo` from a compatible value.
0034     //
0035     // EBOs can be indexed using an arbitrary type. The recommended usage is
0036     // to define an integrap constant wrapper for the specific container using
0037     // EBO, and then index using that wrapper:
0038     //
0039     //      template <int> struct idx; // wrapper for tuple
0040     //      template <typename ...T>
0041     //      struct tuple : ebo<idx<0>, T0>, ebo<idx<1>, T1>, ... { };
0042     //
0043     // The reason for defining one wrapper per container is to avoid any issues
0044     // that can arise when using `ebo_get`, which casts to the base class. If
0045     // `tuple` and `pair` are inheritting from `ebo`s with the same indexing
0046     // scheme, trying to use `ebo_get` on a tuple of pairs will trigger an
0047     // ambiguous base class conversion, since both tuple and pair inherit
0048     // from `ebo`s with the same keys.
0049     //////////////////////////////////////////////////////////////////////////
0050     template <typename K, typename V, bool =
0051         BOOST_HANA_TT_IS_EMPTY(V) && !BOOST_HANA_TT_IS_FINAL(V)
0052     >
0053     struct ebo;
0054 
0055     // Specialize storage for empty types
0056     template <typename K, typename V>
0057     struct ebo<K, V, true> : V {
0058         constexpr ebo() { }
0059 
0060         template <typename T>
0061         explicit constexpr ebo(T&& t)
0062             : V(static_cast<T&&>(t))
0063         { }
0064     };
0065 
0066     // Specialize storage for non-empty types
0067     template <typename K, typename V>
0068     struct ebo<K, V, false> {
0069         constexpr ebo() : data_() { }
0070 
0071         template <typename T>
0072         explicit constexpr ebo(T&& t)
0073             : data_(static_cast<T&&>(t))
0074         { }
0075 
0076         V data_;
0077     };
0078 
0079     //////////////////////////////////////////////////////////////////////////
0080     // ebo_get
0081     //////////////////////////////////////////////////////////////////////////
0082     template <typename K, typename V>
0083     constexpr V const& ebo_get(ebo<K, V, true> const& x)
0084     { return x; }
0085 
0086     template <typename K, typename V>
0087     constexpr V& ebo_get(ebo<K, V, true>& x)
0088     { return x; }
0089 
0090     template <typename K, typename V>
0091     constexpr V&& ebo_get(ebo<K, V, true>&& x)
0092     { return static_cast<V&&>(x); }
0093 
0094 
0095     template <typename K, typename V>
0096     constexpr V const& ebo_get(ebo<K, V, false> const& x)
0097     { return x.data_; }
0098 
0099     template <typename K, typename V>
0100     constexpr V& ebo_get(ebo<K, V, false>& x)
0101     { return x.data_; }
0102 
0103     template <typename K, typename V>
0104     constexpr V&& ebo_get(ebo<K, V, false>&& x)
0105     { return static_cast<V&&>(x.data_); }
0106 } // end namespace _hana
0107 
0108 namespace boost { namespace hana {
0109     namespace detail {
0110         using ::_hana::ebo;
0111         using ::_hana::ebo_get;
0112     }
0113 }} // end namespace boost::hana
0114 
0115 #endif // !BOOST_HANA_DETAIL_EBO_HPP