Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:05

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