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

          Line data    Source code
       1             : /*!
       2             : @file
       3             : Defines `boost::hana::unpack`.
       4             : 
       5             : Copyright Louis Dionne 2013-2022
       6             : Distributed under the Boost Software License, Version 1.0.
       7             : (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
       8             :  */
       9             : 
      10             : #ifndef BOOST_HANA_UNPACK_HPP
      11             : #define BOOST_HANA_UNPACK_HPP
      12             : 
      13             : #include <boost/hana/fwd/unpack.hpp>
      14             : 
      15             : #include <boost/hana/accessors.hpp>
      16             : #include <boost/hana/at.hpp>
      17             : #include <boost/hana/concept/foldable.hpp>
      18             : #include <boost/hana/concept/iterable.hpp>
      19             : #include <boost/hana/concept/struct.hpp>
      20             : #include <boost/hana/config.hpp>
      21             : #include <boost/hana/core/dispatch.hpp>
      22             : #include <boost/hana/first.hpp>
      23             : #include <boost/hana/functional/partial.hpp>
      24             : #include <boost/hana/fwd/fold_left.hpp>
      25             : #include <boost/hana/length.hpp>
      26             : #include <boost/hana/pair.hpp>
      27             : #include <boost/hana/second.hpp>
      28             : 
      29             : #include <cstddef>
      30             : #include <utility>
      31             : 
      32             : 
      33             : namespace boost { namespace hana {
      34             :     //! @cond
      35             :     template <typename Xs, typename F>
      36     1967890 :     constexpr decltype(auto) unpack_t::operator()(Xs&& xs, F&& f) const {
      37             :         using S = typename hana::tag_of<Xs>::type;
      38             :         using Unpack = BOOST_HANA_DISPATCH_IF(unpack_impl<S>,
      39             :             hana::Foldable<S>::value
      40             :         );
      41             : 
      42             :     #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
      43             :         static_assert(hana::Foldable<S>::value,
      44             :         "hana::unpack(xs, f) requires 'xs' to be Foldable");
      45             :     #endif
      46             : 
      47     1967890 :         return Unpack::apply(static_cast<Xs&&>(xs), static_cast<F&&>(f));
      48             :     }
      49             :     //! @endcond
      50             : 
      51             :     template <typename T, bool condition>
      52             :     struct unpack_impl<T, when<condition>> : default_ {
      53             :         template <typename Xs, typename F>
      54             :         static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
      55             :             return hana::fold_left(static_cast<Xs&&>(xs),
      56             :                                    static_cast<F&&>(f),
      57             :                                    hana::partial)();
      58             :         }
      59             :     };
      60             : 
      61             :     template <typename It>
      62             :     struct unpack_impl<It, when<
      63             :         hana::Iterable<It>::value && !is_default<length_impl<It>>::value
      64             :     >> {
      65             :         template <typename Xs, typename F, std::size_t ...i>
      66             :         static constexpr decltype(auto)
      67             :         unpack_helper(Xs&& xs, F&& f, std::index_sequence<i...>) {
      68             :             return static_cast<F&&>(f)(hana::at_c<i>(static_cast<Xs&&>(xs))...);
      69             :         }
      70             : 
      71             :         template <typename Xs, typename F>
      72             :         static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
      73             :             constexpr std::size_t N = decltype(hana::length(xs))::value;
      74             :             return unpack_helper(static_cast<Xs&&>(xs), static_cast<F&&>(f),
      75             :                                  std::make_index_sequence<N>{});
      76             :         }
      77             :     };
      78             : 
      79             :     template <typename T, std::size_t N>
      80             :     struct unpack_impl<T[N]> {
      81             :         template <typename Xs, typename F, std::size_t ...i>
      82             :         static constexpr decltype(auto)
      83             :         unpack_helper(Xs&& xs, F&& f, std::index_sequence<i...>) {
      84             :             return static_cast<F&&>(f)(static_cast<Xs&&>(xs)[i]...);
      85             :         }
      86             : 
      87             :         template <typename Xs, typename F>
      88             :         static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
      89             :             return unpack_impl::unpack_helper(static_cast<Xs&&>(xs),
      90             :                                               static_cast<F&&>(f),
      91             :                                               std::make_index_sequence<N>{});
      92             :         }
      93             :     };
      94             : 
      95             :     //////////////////////////////////////////////////////////////////////////
      96             :     // Model for Products
      97             :     //////////////////////////////////////////////////////////////////////////
      98             :     template <typename T>
      99             :     struct unpack_impl<T, when<hana::Product<T>::value>> {
     100             :         template <typename P, typename F>
     101             :         static constexpr decltype(auto) apply(P&& p, F&& f) {
     102             :             return static_cast<F&&>(f)(
     103             :                 hana::first(static_cast<P&&>(p)),
     104             :                 hana::second(static_cast<P&&>(p))
     105             :             );
     106             :         }
     107             :     };
     108             : 
     109             :     //////////////////////////////////////////////////////////////////////////
     110             :     // Model for Structs
     111             :     //////////////////////////////////////////////////////////////////////////
     112             :     namespace struct_detail {
     113             :         // This is equivalent to `demux`, except that `demux` can't forward
     114             :         // the `udt` because it does not know the `g`s are accessors. Hence,
     115             :         // this can result in faster code.
     116             :         struct almost_demux {
     117             :             template <typename F, typename Udt, typename ...Members>
     118             :             constexpr decltype(auto)
     119             :             operator()(F&& f, Udt&& udt, Members&& ...g) const {
     120             :                 return static_cast<F&&>(f)(hana::make_pair(
     121             :                     hana::first(static_cast<Members&&>(g)),
     122             :                     hana::second(static_cast<Members&&>(g))
     123             :                                                 (static_cast<Udt&&>(udt))
     124             :                 )...);
     125             :             }
     126             :         };
     127             :     }
     128             : 
     129             :     template <typename S>
     130             :     struct unpack_impl<S, when<hana::Struct<S>::value>> {
     131             :         template <typename Udt, typename F>
     132             :         static constexpr decltype(auto) apply(Udt&& udt, F&& f) {
     133             :             return hana::unpack(hana::accessors<S>(),
     134             :                 hana::partial(struct_detail::almost_demux{},
     135             :                               static_cast<F&&>(f),
     136             :                               static_cast<Udt&&>(udt)));
     137             :         }
     138             :     };
     139             : }} // end namespace boost::hana
     140             : 
     141             : #endif // !BOOST_HANA_UNPACK_HPP

Generated by: LCOV version 1.16