File indexing completed on 2025-01-18 09:37:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_EXPERIMENTAL_VIEW_HPP
0011 #define BOOST_HANA_EXPERIMENTAL_VIEW_HPP
0012
0013 #include <boost/hana/and.hpp>
0014 #include <boost/hana/at.hpp>
0015 #include <boost/hana/bool.hpp>
0016 #include <boost/hana/detail/decay.hpp>
0017 #include <boost/hana/fold_left.hpp>
0018 #include <boost/hana/functional/compose.hpp>
0019 #include <boost/hana/functional/on.hpp>
0020 #include <boost/hana/fwd/ap.hpp>
0021 #include <boost/hana/fwd/concat.hpp>
0022 #include <boost/hana/fwd/drop_front.hpp>
0023 #include <boost/hana/fwd/empty.hpp>
0024 #include <boost/hana/fwd/equal.hpp>
0025 #include <boost/hana/fwd/flatten.hpp>
0026 #include <boost/hana/fwd/is_empty.hpp>
0027 #include <boost/hana/fwd/less.hpp>
0028 #include <boost/hana/fwd/lift.hpp>
0029 #include <boost/hana/fwd/transform.hpp>
0030 #include <boost/hana/integral_constant.hpp>
0031 #include <boost/hana/length.hpp>
0032 #include <boost/hana/lexicographical_compare.hpp>
0033 #include <boost/hana/range.hpp>
0034 #include <boost/hana/tuple.hpp>
0035 #include <boost/hana/unpack.hpp>
0036
0037 #include <cstddef>
0038 #include <type_traits>
0039 #include <utility>
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 namespace boost { namespace hana {
0060
0061 namespace experimental {
0062 struct view_tag;
0063
0064 namespace detail {
0065 template <typename Sequence>
0066 struct is_view {
0067 static constexpr bool value = false;
0068 };
0069
0070 template <typename Sequence>
0071 using view_storage = typename std::conditional<
0072 detail::is_view<Sequence>::value, Sequence, Sequence&
0073 >::type;
0074 }
0075
0076
0077
0078
0079 template <typename Sequence, std::size_t ...indices>
0080 struct sliced_view_t {
0081 detail::view_storage<Sequence> sequence_;
0082 using hana_tag = view_tag;
0083 };
0084
0085 template <typename Sequence, typename Indices>
0086 constexpr auto sliced(Sequence& sequence, Indices const& indices) {
0087 return hana::unpack(indices, [&](auto ...i) {
0088 return sliced_view_t<Sequence, decltype(i)::value...>{sequence};
0089 });
0090 }
0091
0092 namespace detail {
0093 template <typename Sequence, std::size_t ...i>
0094 struct is_view<sliced_view_t<Sequence, i...>> {
0095 static constexpr bool value = true;
0096 };
0097 }
0098
0099
0100
0101
0102 template <typename Sequence, typename F>
0103 struct transformed_view_t {
0104 detail::view_storage<Sequence> sequence_;
0105 F f_;
0106 using hana_tag = view_tag;
0107 };
0108
0109 template <typename Sequence, typename F>
0110 constexpr transformed_view_t<Sequence, typename hana::detail::decay<F>::type>
0111 transformed(Sequence& sequence, F&& f) {
0112 return {sequence, static_cast<F&&>(f)};
0113 }
0114
0115 namespace detail {
0116 template <typename Sequence, typename F>
0117 struct is_view<transformed_view_t<Sequence, F>> {
0118 static constexpr bool value = true;
0119 };
0120 }
0121
0122
0123
0124
0125 #if 0
0126 template <typename Sequence, typename Pred>
0127 using filtered_view_t = sliced_view_t<Sequence, detail::filtered_indices<...>>;
0128
0129 template <typename Sequence, typename Pred>
0130 constexpr filtered_view_t<Sequence, Pred> filtered(Sequence& sequence, Pred&& pred) {
0131 return {sequence};
0132 }
0133 #endif
0134
0135
0136
0137
0138 template <typename Sequence1, typename Sequence2>
0139 struct joined_view_t {
0140 detail::view_storage<Sequence1> sequence1_;
0141 detail::view_storage<Sequence2> sequence2_;
0142 using hana_tag = view_tag;
0143 };
0144
0145 struct make_joined_view_t {
0146 template <typename Sequence1, typename Sequence2>
0147 constexpr joined_view_t<Sequence1, Sequence2> operator()(Sequence1& s1, Sequence2& s2) const {
0148 return {s1, s2};
0149 }
0150 };
0151 BOOST_HANA_INLINE_VARIABLE constexpr make_joined_view_t joined{};
0152
0153 namespace detail {
0154 template <typename Sequence1, typename Sequence2>
0155 struct is_view<joined_view_t<Sequence1, Sequence2>> {
0156 static constexpr bool value = true;
0157 };
0158 }
0159
0160
0161
0162
0163 template <typename T>
0164 struct single_view_t {
0165 T value_;
0166 using hana_tag = view_tag;
0167 };
0168
0169 template <typename T>
0170 constexpr single_view_t<typename hana::detail::decay<T>::type> single_view(T&& t) {
0171 return {static_cast<T&&>(t)};
0172 }
0173
0174 namespace detail {
0175 template <typename T>
0176 struct is_view<single_view_t<T>> {
0177 static constexpr bool value = true;
0178 };
0179 }
0180
0181
0182
0183
0184 struct empty_view_t {
0185 using hana_tag = view_tag;
0186 };
0187
0188 constexpr empty_view_t empty_view() {
0189 return {};
0190 }
0191
0192 namespace detail {
0193 template <>
0194 struct is_view<empty_view_t> {
0195 static constexpr bool value = true;
0196 };
0197 }
0198 }
0199
0200
0201
0202
0203 template <>
0204 struct unpack_impl<experimental::view_tag> {
0205
0206 template <typename Sequence, std::size_t ...i, typename F>
0207 static constexpr decltype(auto)
0208 apply(experimental::sliced_view_t<Sequence, i...> view, F&& f) {
0209 (void)view;
0210 return static_cast<F&&>(f)(hana::at_c<i>(view.sequence_)...);
0211 }
0212
0213
0214 template <typename Sequence, typename F, typename G>
0215 static constexpr decltype(auto)
0216 apply(experimental::transformed_view_t<Sequence, F> view, G&& g) {
0217 return hana::unpack(view.sequence_, hana::on(static_cast<G&&>(g), view.f_));
0218 }
0219
0220
0221 template <typename View, typename F, std::size_t ...i1, std::size_t ...i2>
0222 static constexpr decltype(auto)
0223 unpack_joined(View view, F&& f, std::index_sequence<i1...>,
0224 std::index_sequence<i2...>)
0225 {
0226 (void)view;
0227 return static_cast<F&&>(f)(hana::at_c<i1>(view.sequence1_)...,
0228 hana::at_c<i2>(view.sequence2_)...);
0229 }
0230
0231 template <typename S1, typename S2, typename F>
0232 static constexpr decltype(auto)
0233 apply(experimental::joined_view_t<S1, S2> view, F&& f) {
0234 constexpr auto N1 = decltype(hana::length(view.sequence1_))::value;
0235 constexpr auto N2 = decltype(hana::length(view.sequence2_))::value;
0236 return unpack_joined(view, static_cast<F&&>(f),
0237 std::make_index_sequence<N1>{},
0238 std::make_index_sequence<N2>{});
0239 }
0240
0241
0242 template <typename T, typename F>
0243 static constexpr decltype(auto) apply(experimental::single_view_t<T> view, F&& f) {
0244 return static_cast<F&&>(f)(view.value_);
0245 }
0246
0247
0248 template <typename F>
0249 static constexpr decltype(auto) apply(experimental::empty_view_t, F&& f) {
0250 return static_cast<F&&>(f)();
0251 }
0252 };
0253
0254
0255
0256
0257 template <>
0258 struct at_impl<experimental::view_tag> {
0259
0260 template <typename Sequence, std::size_t ...i, typename N>
0261 static constexpr decltype(auto)
0262 apply(experimental::sliced_view_t<Sequence, i...> view, N const&) {
0263 constexpr std::size_t indices[] = {i...};
0264 constexpr std::size_t n = indices[N::value];
0265 return hana::at_c<n>(view.sequence_);
0266 }
0267
0268
0269 template <typename Sequence, typename F, typename N>
0270 static constexpr decltype(auto)
0271 apply(experimental::transformed_view_t<Sequence, F> view, N const& n) {
0272 return view.f_(hana::at(view.sequence_, n));
0273 }
0274
0275
0276 template <std::size_t Left, typename View, typename N>
0277 static constexpr decltype(auto) at_joined_view(View view, N const&, hana::true_) {
0278 return hana::at_c<N::value>(view.sequence1_);
0279 }
0280
0281 template <std::size_t Left, typename View, typename N>
0282 static constexpr decltype(auto) at_joined_view(View view, N const&, hana::false_) {
0283 return hana::at_c<N::value - Left>(view.sequence2_);
0284 }
0285
0286 template <typename S1, typename S2, typename N>
0287 static constexpr decltype(auto)
0288 apply(experimental::joined_view_t<S1, S2> view, N const& n) {
0289 constexpr auto Left = decltype(hana::length(view.sequence1_))::value;
0290 return at_joined_view<Left>(view, n, hana::bool_c<(N::value < Left)>);
0291 }
0292
0293
0294 template <typename T, typename N>
0295 static constexpr decltype(auto) apply(experimental::single_view_t<T> view, N const&) {
0296 static_assert(N::value == 0,
0297 "trying to fetch an out-of-bounds element in a hana::single_view");
0298 return view.value_;
0299 }
0300
0301
0302 template <typename N>
0303 static constexpr decltype(auto) apply(experimental::empty_view_t, N const&) = delete;
0304 };
0305
0306 template <>
0307 struct length_impl<experimental::view_tag> {
0308
0309 template <typename Sequence, std::size_t ...i>
0310 static constexpr auto
0311 apply(experimental::sliced_view_t<Sequence, i...>) {
0312 return hana::size_c<sizeof...(i)>;
0313 }
0314
0315
0316 template <typename Sequence, typename F>
0317 static constexpr auto apply(experimental::transformed_view_t<Sequence, F> view) {
0318 return hana::length(view.sequence_);
0319 }
0320
0321
0322 template <typename S1, typename S2>
0323 static constexpr auto apply(experimental::joined_view_t<S1, S2> view) {
0324 return hana::size_c<
0325 decltype(hana::length(view.sequence1_))::value +
0326 decltype(hana::length(view.sequence2_))::value
0327 >;
0328 }
0329
0330
0331 template <typename T>
0332 static constexpr auto apply(experimental::single_view_t<T>) {
0333 return hana::size_c<1>;
0334 }
0335
0336
0337 static constexpr auto apply(experimental::empty_view_t) {
0338 return hana::size_c<0>;
0339 }
0340 };
0341
0342 template <>
0343 struct is_empty_impl<experimental::view_tag> {
0344
0345 template <typename Sequence, std::size_t ...i>
0346 static constexpr auto
0347 apply(experimental::sliced_view_t<Sequence, i...>) {
0348 return hana::bool_c<sizeof...(i) == 0>;
0349 }
0350
0351
0352 template <typename Sequence, typename F>
0353 static constexpr auto apply(experimental::transformed_view_t<Sequence, F> view) {
0354 return hana::is_empty(view.sequence_);
0355 }
0356
0357
0358 template <typename S1, typename S2>
0359 static constexpr auto apply(experimental::joined_view_t<S1, S2> view) {
0360 return hana::and_(hana::is_empty(view.sequence1_),
0361 hana::is_empty(view.sequence2_));
0362 }
0363
0364
0365 template <typename T>
0366 static constexpr auto apply(experimental::single_view_t<T>) {
0367 return hana::false_c;
0368 }
0369
0370
0371 static constexpr auto apply(experimental::empty_view_t) {
0372 return hana::true_c;
0373 }
0374 };
0375
0376 template <>
0377 struct drop_front_impl<experimental::view_tag> {
0378 template <typename View, typename N>
0379 static constexpr auto apply(View view, N const&) {
0380 constexpr auto n = N::value;
0381 constexpr auto Length = decltype(hana::length(view))::value;
0382 return experimental::sliced(view, hana::range_c<std::size_t, n, Length>);
0383 }
0384 };
0385
0386
0387
0388
0389 template <>
0390 struct transform_impl<experimental::view_tag> {
0391 template <typename Sequence, typename F, typename G>
0392 static constexpr auto
0393 apply(experimental::transformed_view_t<Sequence, F> view, G&& g) {
0394 return experimental::transformed(view.sequence_,
0395 hana::compose(static_cast<G&&>(g), view.f_));
0396 }
0397
0398 template <typename View, typename F>
0399 static constexpr auto apply(View view, F&& f) {
0400 return experimental::transformed(view, static_cast<F&&>(f));
0401 }
0402 };
0403
0404
0405
0406
0407 template <>
0408 struct lift_impl<experimental::view_tag> {
0409 template <typename T>
0410 static constexpr auto apply(T&& t) {
0411 return experimental::single_view(static_cast<T&&>(t));
0412 }
0413 };
0414
0415 template <>
0416 struct ap_impl<experimental::view_tag> {
0417 template <typename F, typename X>
0418 static constexpr auto apply(F&& f, X&& x) {
0419
0420
0421 return hana::ap(hana::to_tuple(f), hana::to_tuple(x));
0422 }
0423 };
0424
0425
0426
0427
0428 template <>
0429 struct flatten_impl<experimental::view_tag> {
0430 template <typename View>
0431 static constexpr auto apply(View view) {
0432
0433 return hana::fold_left(view, experimental::empty_view(),
0434 experimental::joined);
0435 }
0436 };
0437
0438
0439
0440
0441 template <>
0442 struct concat_impl<experimental::view_tag> {
0443 template <typename View1, typename View2>
0444 static constexpr auto apply(View1 view1, View2 view2) {
0445 return experimental::joined(view1, view2);
0446 }
0447 };
0448
0449 template <>
0450 struct empty_impl<experimental::view_tag> {
0451 static constexpr auto apply() {
0452 return experimental::empty_view();
0453 }
0454 };
0455
0456
0457
0458
0459 template <>
0460 struct equal_impl<experimental::view_tag, experimental::view_tag> {
0461 template <typename View1, typename View2>
0462 static constexpr auto apply(View1 v1, View2 v2) {
0463
0464 return hana::equal(hana::to_tuple(v1), hana::to_tuple(v2));
0465 }
0466 };
0467
0468 template <typename S>
0469 struct equal_impl<experimental::view_tag, S, hana::when<hana::Sequence<S>::value>> {
0470 template <typename View1, typename Seq>
0471 static constexpr auto apply(View1 v1, Seq const& s) {
0472
0473 return hana::equal(hana::to_tuple(v1), hana::to_tuple(s));
0474 }
0475 };
0476
0477 template <typename S>
0478 struct equal_impl<S, experimental::view_tag, hana::when<hana::Sequence<S>::value>> {
0479 template <typename Seq, typename View2>
0480 static constexpr auto apply(Seq const& s, View2 v2) {
0481
0482 return hana::equal(hana::to_tuple(s), hana::to_tuple(v2));
0483 }
0484 };
0485
0486
0487
0488
0489 template <>
0490 struct less_impl<experimental::view_tag, experimental::view_tag> {
0491 template <typename View1, typename View2>
0492 static constexpr auto apply(View1 v1, View2 v2) {
0493 return hana::lexicographical_compare(v1, v2);
0494 }
0495 };
0496
0497 template <typename S>
0498 struct less_impl<experimental::view_tag, S, hana::when<hana::Sequence<S>::value>> {
0499 template <typename View1, typename Seq>
0500 static constexpr auto apply(View1 v1, Seq const& s) {
0501 return hana::lexicographical_compare(v1, s);
0502 }
0503 };
0504
0505 template <typename S>
0506 struct less_impl<S, experimental::view_tag, hana::when<hana::Sequence<S>::value>> {
0507 template <typename Seq, typename View2>
0508 static constexpr auto apply(Seq const& s, View2 v2) {
0509 return hana::lexicographical_compare(s, v2);
0510 }
0511 };
0512
0513 }}
0514
0515 #endif