File indexing completed on 2025-01-30 09:43:39
0001
0002
0003
0004
0005
0006
0007
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
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
0061
0062 template <typename S, bool condition>
0063 struct scan_left_impl<S, when<condition>> : default_ {
0064
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
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
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 }}
0132
0133 #endif