Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:43:39

0001 /*!
0002 @file
0003 Defines `boost::hana::scan_left`.
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_SCAN_LEFT_HPP
0011 #define BOOST_HANA_SCAN_LEFT_HPP
0012 
0013 #include <boost/hana/fwd/scan_left.hpp>
0014 
0015 #include <boost/hana/at.hpp>
0016 #include <boost/hana/concept/sequence.hpp>
0017 #include <boost/hana/config.hpp>
0018 #include <boost/hana/core/dispatch.hpp>
0019 #include <boost/hana/core/make.hpp>
0020 #include <boost/hana/empty.hpp>
0021 #include <boost/hana/length.hpp>
0022 #include <boost/hana/prepend.hpp>
0023 
0024 #include <cstddef>
0025 #include <utility>
0026 
0027 
0028 namespace boost { namespace hana {
0029     //! @cond
0030     template <typename Xs, typename F>
0031     constexpr auto scan_left_t::operator()(Xs&& xs, F const& f) const {
0032         using S = typename hana::tag_of<Xs>::type;
0033         using ScanLeft = BOOST_HANA_DISPATCH_IF(scan_left_impl<S>,
0034             hana::Sequence<S>::value
0035         );
0036 
0037 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0038         static_assert(hana::Sequence<S>::value,
0039         "hana::scan_left(xs, f) requires 'xs' to be a Sequence");
0040 #endif
0041 
0042         return ScanLeft::apply(static_cast<Xs&&>(xs), f);
0043     }
0044 
0045     template <typename Xs, typename State, typename F>
0046     constexpr auto scan_left_t::operator()(Xs&& xs, State&& state, F const& f) const {
0047         using S = typename hana::tag_of<Xs>::type;
0048         using ScanLeft = BOOST_HANA_DISPATCH_IF(scan_left_impl<S>,
0049             hana::Sequence<S>::value
0050         );
0051 
0052 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0053         static_assert(hana::Sequence<S>::value,
0054         "hana::scan_left(xs, state, f) requires 'xs' to be a Sequence");
0055 #endif
0056 
0057         return ScanLeft::apply(static_cast<Xs&&>(xs),
0058                                static_cast<State&&>(state), f);
0059     }
0060     //! @endcond
0061 
0062     template <typename S, bool condition>
0063     struct scan_left_impl<S, when<condition>> : default_ {
0064         // Without initial state
0065         template <typename Xs, typename F, std::size_t n1, std::size_t n2, std::size_t ...ns>
0066         static constexpr auto
0067         apply1_impl(Xs&& xs, F const& f, std::index_sequence<n1, n2, ns...>) {
0068             static_assert(n1 == 0, "logic error in Boost.Hana: file a bug report");
0069 
0070             // Use scan_left with the first element as an initial state.
0071             return scan_left_impl::apply_impl(
0072                 static_cast<Xs&&>(xs),
0073                 hana::at_c<0>(static_cast<Xs&&>(xs)),
0074                 f, std::index_sequence<n2, ns...>{}
0075             );
0076         }
0077 
0078         template <typename Xs, typename F, std::size_t n>
0079         static constexpr auto apply1_impl(Xs&& xs, F const&, std::index_sequence<n>) {
0080             return hana::make<S>(hana::at_c<n>(static_cast<Xs&&>(xs)));
0081         }
0082 
0083         template <typename Xs, typename F>
0084         static constexpr auto apply1_impl(Xs&&, F const&, std::index_sequence<>) {
0085             return hana::empty<S>();
0086         }
0087 
0088         template <typename Xs, typename F>
0089         static constexpr auto apply(Xs&& xs, F const& f) {
0090             constexpr std::size_t Len = decltype(hana::length(xs))::value;
0091             return scan_left_impl::apply1_impl(static_cast<Xs&&>(xs),
0092                                                f, std::make_index_sequence<Len>{});
0093         }
0094 
0095 
0096         // With initial state
0097         template <typename Xs, typename State, typename F,
0098                   std::size_t n1, std::size_t n2, std::size_t ...ns>
0099         static constexpr auto
0100         apply_impl(Xs&& xs, State&& state, F const& f,
0101                    std::index_sequence<n1, n2, ns...>)
0102         {
0103             auto rest = scan_left_impl::apply_impl(
0104                                 static_cast<Xs&&>(xs),
0105                                 f(state, hana::at_c<n1>(static_cast<Xs&&>(xs))),
0106                                 f, std::index_sequence<n2, ns...>{});
0107             return hana::prepend(std::move(rest), static_cast<State&&>(state));
0108         }
0109 
0110         template <typename Xs, typename State, typename F, std::size_t n>
0111         static constexpr auto
0112         apply_impl(Xs&& xs, State&& state, F const& f, std::index_sequence<n>) {
0113             auto new_state = f(state, hana::at_c<n>(static_cast<Xs&&>(xs)));
0114             return hana::make<S>(static_cast<State&&>(state), std::move(new_state));
0115         }
0116 
0117         template <typename Xs, typename State, typename F>
0118         static constexpr auto
0119         apply_impl(Xs&&, State&& state, F const&, std::index_sequence<>) {
0120             return hana::make<S>(static_cast<State&&>(state));
0121         }
0122 
0123         template <typename Xs, typename State, typename F>
0124         static constexpr auto apply(Xs&& xs, State&& state, F const& f) {
0125             constexpr std::size_t Len = decltype(hana::length(xs))::value;
0126             return scan_left_impl::apply_impl(static_cast<Xs&&>(xs),
0127                                               static_cast<State&&>(state),
0128                                               f, std::make_index_sequence<Len>{});
0129         }
0130     };
0131 }} // end namespace boost::hana
0132 
0133 #endif // !BOOST_HANA_SCAN_LEFT_HPP