File indexing completed on 2025-01-18 09:38:05
0001
0002
0003
0004
0005
0006
0007
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
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
0062
0063 template <typename S, bool condition>
0064 struct scan_right_impl<S, when<condition>> : default_ {
0065
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
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 }}
0129
0130 #endif