File indexing completed on 2025-01-30 09:43:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_SLICE_HPP
0011 #define BOOST_HANA_SLICE_HPP
0012
0013 #include <boost/hana/fwd/slice.hpp>
0014
0015 #include <boost/hana/at.hpp>
0016 #include <boost/hana/concept/foldable.hpp>
0017 #include <boost/hana/concept/sequence.hpp>
0018 #include <boost/hana/config.hpp>
0019 #include <boost/hana/core/dispatch.hpp>
0020 #include <boost/hana/core/make.hpp>
0021 #include <boost/hana/range.hpp>
0022 #include <boost/hana/unpack.hpp>
0023
0024 #include <cstddef>
0025 #include <utility>
0026
0027
0028 namespace boost { namespace hana {
0029
0030 template <typename Xs, typename Indices>
0031 constexpr auto slice_t::operator()(Xs&& xs, Indices&& indices) const {
0032 using S = typename hana::tag_of<Xs>::type;
0033 using Slice = BOOST_HANA_DISPATCH_IF(slice_impl<S>,
0034 hana::Sequence<S>::value &&
0035 hana::Foldable<Indices>::value
0036 );
0037
0038 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0039 static_assert(hana::Sequence<S>::value,
0040 "hana::slice(xs, indices) requires 'xs' to be a Sequence");
0041
0042 static_assert(hana::Foldable<Indices>::value,
0043 "hana::slice(xs, indices) requires 'indices' to be Foldable");
0044 #endif
0045
0046 return Slice::apply(static_cast<Xs&&>(xs), static_cast<Indices&&>(indices));
0047 }
0048
0049
0050 namespace detail {
0051 template <typename Xs>
0052 struct take_arbitrary {
0053 Xs& xs;
0054 using S = typename hana::tag_of<Xs>::type;
0055
0056 template <typename ...N>
0057 constexpr auto operator()(N const& ...) const {
0058 return hana::make<S>(hana::at_c<N::value>(xs)...);
0059 }
0060 };
0061 }
0062
0063 template <typename S, bool condition>
0064 struct slice_impl<S, when<condition>> : default_ {
0065 template <std::size_t from, typename Xs, std::size_t ...i>
0066 static constexpr auto from_offset(Xs&& xs, std::index_sequence<i...>) {
0067 return hana::make<S>(hana::at_c<from + i>(static_cast<Xs&&>(xs))...);
0068 }
0069
0070 template <typename Xs, typename T, T from, T to>
0071 static constexpr auto apply(Xs&& xs, hana::range<T, from, to> const&) {
0072 return slice_impl::from_offset<from>(
0073 static_cast<Xs&&>(xs), std::make_index_sequence<to - from>{}
0074 );
0075 }
0076
0077
0078
0079
0080
0081
0082
0083 template <typename Xs, typename Indices>
0084 static constexpr auto apply(Xs const& xs, Indices const& indices) {
0085 return hana::unpack(indices, detail::take_arbitrary<Xs const>{xs});
0086 }
0087 };
0088
0089 template <std::size_t from, std::size_t to>
0090 struct slice_c_t {
0091 template <typename Xs>
0092 constexpr auto operator()(Xs&& xs) const {
0093 return hana::slice(static_cast<Xs&&>(xs),
0094 hana::range_c<std::size_t, from, to>);
0095 }
0096 };
0097 }}
0098
0099 #endif