LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/hana - tuple.hpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 2 2 100.0 %
Date: 2026-06-25 07:23:43 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*!
       2             : @file
       3             : Defines `boost::hana::tuple`.
       4             : 
       5             : Copyright Louis Dionne 2013-2022
       6             : Copyright Jason Rice 2017
       7             : Distributed under the Boost Software License, Version 1.0.
       8             : (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
       9             :  */
      10             : 
      11             : #ifndef BOOST_HANA_TUPLE_HPP
      12             : #define BOOST_HANA_TUPLE_HPP
      13             : 
      14             : #include <boost/hana/fwd/tuple.hpp>
      15             : 
      16             : #include <boost/hana/basic_tuple.hpp>
      17             : #include <boost/hana/bool.hpp>
      18             : #include <boost/hana/config.hpp>
      19             : #include <boost/hana/detail/decay.hpp>
      20             : #include <boost/hana/detail/fast_and.hpp>
      21             : #include <boost/hana/detail/index_if.hpp>
      22             : #include <boost/hana/detail/intrinsics.hpp>
      23             : #include <boost/hana/detail/operators/adl.hpp>
      24             : #include <boost/hana/detail/operators/comparable.hpp>
      25             : #include <boost/hana/detail/operators/iterable.hpp>
      26             : #include <boost/hana/detail/operators/monad.hpp>
      27             : #include <boost/hana/detail/operators/orderable.hpp>
      28             : #include <boost/hana/fwd/at.hpp>
      29             : #include <boost/hana/fwd/core/make.hpp>
      30             : #include <boost/hana/fwd/drop_front.hpp>
      31             : #include <boost/hana/fwd/index_if.hpp>
      32             : #include <boost/hana/fwd/is_empty.hpp>
      33             : #include <boost/hana/fwd/length.hpp>
      34             : #include <boost/hana/fwd/optional.hpp>
      35             : #include <boost/hana/fwd/unpack.hpp>
      36             : #include <boost/hana/type.hpp> // required by fwd decl of tuple_t
      37             : 
      38             : #include <cstddef>
      39             : #include <type_traits>
      40             : #include <utility>
      41             : 
      42             : 
      43             : namespace boost { namespace hana {
      44             :     namespace detail {
      45             :         template <typename Xs, typename Ys, std::size_t ...n>
      46             :         constexpr void assign(Xs& xs, Ys&& ys, std::index_sequence<n...>) {
      47             :             int sequence[] = {int{}, ((void)(
      48             :                 hana::at_c<n>(xs) = hana::at_c<n>(static_cast<Ys&&>(ys))
      49             :             ), int{})...};
      50             :             (void)sequence;
      51             :         }
      52             : 
      53             :         struct from_index_sequence_t { };
      54             : 
      55             :         template <typename Tuple, typename ...Yn>
      56             :         struct is_same_tuple : std::false_type { };
      57             : 
      58             :         template <typename Tuple>
      59             :         struct is_same_tuple<typename detail::decay<Tuple>::type, Tuple>
      60             :             : std::true_type
      61             :         { };
      62             : 
      63             :         template <bool SameTuple, bool SameNumberOfElements, typename Tuple, typename ...Yn>
      64             :         struct enable_tuple_variadic_ctor;
      65             : 
      66             :         template <typename ...Xn, typename ...Yn>
      67             :         struct enable_tuple_variadic_ctor<false, true, hana::tuple<Xn...>, Yn...>
      68             :             : std::enable_if<
      69             :                 detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Yn&&)...>::value
      70             :             >
      71             :         { };
      72             :     }
      73             : 
      74             :     //////////////////////////////////////////////////////////////////////////
      75             :     // tuple
      76             :     //////////////////////////////////////////////////////////////////////////
      77             :     template <>
      78             : #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
      79             :     struct __declspec(empty_bases) tuple<> final
      80             : #else
      81             :     struct tuple<> final
      82             : #endif
      83             :         : detail::operators::adl<tuple<>>
      84             :         , detail::iterable_operators<tuple<>>
      85             :     {
      86             :         constexpr tuple() { }
      87             :         using hana_tag = tuple_tag;
      88             :     };
      89             : 
      90             :     template <typename ...Xn>
      91             : #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
      92             :     struct __declspec(empty_bases) tuple final
      93             : #else
      94             :     struct tuple final
      95             : #endif
      96             :         : detail::operators::adl<tuple<Xn...>>
      97             :         , detail::iterable_operators<tuple<Xn...>>
      98             :     {
      99             :         basic_tuple<Xn...> storage_;
     100             :         using hana_tag = tuple_tag;
     101             : 
     102             :     private:
     103             :         template <typename Other, std::size_t ...n>
     104             :         explicit constexpr tuple(detail::from_index_sequence_t, std::index_sequence<n...>, Other&& other)
     105             :             : storage_(hana::at_c<n>(static_cast<Other&&>(other))...)
     106             :         { }
     107             : 
     108             :     public:
     109             :         template <typename ...dummy, typename = typename std::enable_if<
     110             :             detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, dummy...)...>::value
     111             :         >::type>
     112             :         constexpr tuple()
     113             :             : storage_()
     114             :         { }
     115             : 
     116             :         template <typename ...dummy, typename = typename std::enable_if<
     117             :             detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value
     118             :         >::type>
     119             :         constexpr tuple(Xn const& ...xn)
     120             :             : storage_(xn...)
     121             :         { }
     122             : 
     123             :         template <typename ...Yn, typename = typename detail::enable_tuple_variadic_ctor<
     124             :             detail::is_same_tuple<tuple, Yn...>::value,
     125             :             sizeof...(Xn) == sizeof...(Yn), tuple, Yn...
     126             :         >::type>
     127             :         constexpr tuple(Yn&& ...yn)
     128             :             : storage_(static_cast<Yn&&>(yn)...)
     129             :         { }
     130             : 
     131             :         template <typename ...Yn, typename = typename std::enable_if<
     132             :             detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Yn const&)...>::value
     133             :         >::type>
     134             :         constexpr tuple(tuple<Yn...> const& other)
     135             :             : tuple(detail::from_index_sequence_t{},
     136             :                     std::make_index_sequence<sizeof...(Xn)>{},
     137             :                     other.storage_)
     138             :         { }
     139             : 
     140             :         template <typename ...Yn, typename = typename std::enable_if<
     141             :             detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Yn&&)...>::value
     142             :         >::type>
     143             :         constexpr tuple(tuple<Yn...>&& other)
     144             :             : tuple(detail::from_index_sequence_t{},
     145             :                     std::make_index_sequence<sizeof...(Xn)>{},
     146             :                     static_cast<tuple<Yn...>&&>(other).storage_)
     147             :         { }
     148             : 
     149             :         // The three following constructors are required to make sure that
     150             :         // the tuple(Yn&&...) constructor is _not_ preferred over the copy
     151             :         // constructor for unary tuples containing a type that is constructible
     152             :         // from tuple<...>. See test/tuple/cnstr.trap.cpp
     153             :         template <typename ...dummy, typename = typename std::enable_if<
     154             :             detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value
     155             :         >::type>
     156             :         constexpr tuple(tuple const& other)
     157             :             : tuple(detail::from_index_sequence_t{},
     158             :                     std::make_index_sequence<sizeof...(Xn)>{},
     159             :                     other.storage_)
     160             :         { }
     161             : 
     162             :         template <typename ...dummy, typename = typename std::enable_if<
     163             :             detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value
     164             :         >::type>
     165             :         constexpr tuple(tuple& other)
     166             :             : tuple(const_cast<tuple const&>(other))
     167             :         { }
     168             : 
     169             :         template <typename ...dummy, typename = typename std::enable_if<
     170             :             detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn&&, dummy...)...>::value
     171             :         >::type>
     172             :         constexpr tuple(tuple&& other)
     173             :             : tuple(detail::from_index_sequence_t{},
     174             :                     std::make_index_sequence<sizeof...(Xn)>{},
     175             :                     static_cast<tuple&&>(other).storage_)
     176             :         { }
     177             : 
     178             : 
     179             :         template <typename ...Yn, typename = typename std::enable_if<
     180             :             detail::fast_and<BOOST_HANA_TT_IS_ASSIGNABLE(Xn&, Yn const&)...>::value
     181             :         >::type>
     182             :         constexpr tuple& operator=(tuple<Yn...> const& other) {
     183             :             detail::assign(this->storage_, other.storage_,
     184             :                            std::make_index_sequence<sizeof...(Xn)>{});
     185             :             return *this;
     186             :         }
     187             : 
     188             :         template <typename ...Yn, typename = typename std::enable_if<
     189             :             detail::fast_and<BOOST_HANA_TT_IS_ASSIGNABLE(Xn&, Yn&&)...>::value
     190             :         >::type>
     191             :         constexpr tuple& operator=(tuple<Yn...>&& other) {
     192             :             detail::assign(this->storage_, static_cast<tuple<Yn...>&&>(other).storage_,
     193             :                            std::make_index_sequence<sizeof...(Xn)>{});
     194             :             return *this;
     195             :         }
     196             :     };
     197             : 
     198             :     //////////////////////////////////////////////////////////////////////////
     199             :     // Operators
     200             :     //////////////////////////////////////////////////////////////////////////
     201             :     namespace detail {
     202             :         template <>
     203             :         struct comparable_operators<tuple_tag> {
     204             :             static constexpr bool value = true;
     205             :         };
     206             :         template <>
     207             :         struct orderable_operators<tuple_tag> {
     208             :             static constexpr bool value = true;
     209             :         };
     210             :         template <>
     211             :         struct monad_operators<tuple_tag> {
     212             :             static constexpr bool value = true;
     213             :         };
     214             :     }
     215             : 
     216             :     //////////////////////////////////////////////////////////////////////////
     217             :     // Foldable
     218             :     //////////////////////////////////////////////////////////////////////////
     219             :     template <>
     220             :     struct unpack_impl<tuple_tag> {
     221             :         template <typename F>
     222             :         static constexpr decltype(auto) apply(tuple<>&&, F&& f)
     223             :         { return static_cast<F&&>(f)(); }
     224             :         template <typename F>
     225             :         static constexpr decltype(auto) apply(tuple<>&, F&& f)
     226             :         { return static_cast<F&&>(f)(); }
     227             :         template <typename F>
     228             :         static constexpr decltype(auto) apply(tuple<> const&, F&& f)
     229             :         { return static_cast<F&&>(f)(); }
     230             : 
     231             :         template <typename Xs, typename F>
     232      983945 :         static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
     233      983945 :             return hana::unpack(static_cast<Xs&&>(xs).storage_, static_cast<F&&>(f));
     234             :         }
     235             :     };
     236             : 
     237             :     template <>
     238             :     struct length_impl<tuple_tag> {
     239             :         template <typename ...Xs>
     240             :         static constexpr auto apply(tuple<Xs...> const&)
     241             :         { return hana::size_c<sizeof...(Xs)>; }
     242             :     };
     243             : 
     244             :     //////////////////////////////////////////////////////////////////////////
     245             :     // Iterable
     246             :     //////////////////////////////////////////////////////////////////////////
     247             :     template <>
     248             :     struct at_impl<tuple_tag> {
     249             :         template <typename Xs, typename N>
     250             :         static constexpr decltype(auto) apply(Xs&& xs, N const&) {
     251             :             constexpr std::size_t index = N::value;
     252             :             return hana::at_c<index>(static_cast<Xs&&>(xs).storage_);
     253             :         }
     254             :     };
     255             : 
     256             :     template <>
     257             :     struct drop_front_impl<tuple_tag> {
     258             :         template <std::size_t N, typename Xs, std::size_t ...i>
     259             :         static constexpr auto helper(Xs&& xs, std::index_sequence<i...>) {
     260             :             return hana::make<tuple_tag>(hana::at_c<i+N>(static_cast<Xs&&>(xs))...);
     261             :         }
     262             : 
     263             :         template <typename Xs, typename N>
     264             :         static constexpr auto apply(Xs&& xs, N const&) {
     265             :             constexpr std::size_t len = decltype(hana::length(xs))::value;
     266             :             return helper<N::value>(static_cast<Xs&&>(xs), std::make_index_sequence<
     267             :                 (N::value < len) ? len - N::value : 0
     268             :             >{});
     269             :         }
     270             :     };
     271             : 
     272             :     template <>
     273             :     struct is_empty_impl<tuple_tag> {
     274             :         template <typename ...Xs>
     275             :         static constexpr auto apply(tuple<Xs...> const&)
     276             :         { return hana::bool_c<sizeof...(Xs) == 0>; }
     277             :     };
     278             : 
     279             :     // compile-time optimizations (to reduce the # of function instantiations)
     280             :     template <std::size_t n, typename ...Xs>
     281             :     constexpr decltype(auto) at_c(tuple<Xs...> const& xs) {
     282             :         return hana::at_c<n>(xs.storage_);
     283             :     }
     284             : 
     285             :     template <std::size_t n, typename ...Xs>
     286             :     constexpr decltype(auto) at_c(tuple<Xs...>& xs) {
     287             :         return hana::at_c<n>(xs.storage_);
     288             :     }
     289             : 
     290             :     template <std::size_t n, typename ...Xs>
     291             :     constexpr decltype(auto) at_c(tuple<Xs...>&& xs) {
     292             :         return hana::at_c<n>(static_cast<tuple<Xs...>&&>(xs).storage_);
     293             :     }
     294             : 
     295             :     template <>
     296             :     struct index_if_impl<tuple_tag> {
     297             :         template <typename ...Xs, typename Pred>
     298             :         static constexpr auto apply(tuple<Xs...> const&, Pred const&)
     299             :             -> typename detail::index_if<Pred, Xs...>::type
     300             :         { return {}; }
     301             :     };
     302             : 
     303             :     //////////////////////////////////////////////////////////////////////////
     304             :     // Sequence
     305             :     //////////////////////////////////////////////////////////////////////////
     306             :     template <>
     307             :     struct Sequence<tuple_tag> {
     308             :         static constexpr bool value = true;
     309             :     };
     310             : 
     311             :     template <>
     312             :     struct make_impl<tuple_tag> {
     313             :         template <typename ...Xs>
     314             :         static constexpr
     315             :         tuple<typename detail::decay<Xs>::type...> apply(Xs&& ...xs)
     316             :         { return {static_cast<Xs&&>(xs)...}; }
     317             :     };
     318             : }} // end namespace boost::hana
     319             : 
     320             : #endif // !BOOST_HANA_TUPLE_HPP

Generated by: LCOV version 1.16