Horizon
split.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2013-present
5 //
6 // Use, modification and distribution is subject to the
7 // Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Project home: https://github.com/ericniebler/range-v3
12 //
13 
14 #ifndef RANGES_V3_ACTION_SPLIT_HPP
15 #define RANGES_V3_ACTION_SPLIT_HPP
16 
17 #include <vector>
18 
19 #include <meta/meta.hpp>
20 
21 #include <range/v3/range_fwd.hpp>
22 
29 #include <range/v3/utility/static_const.hpp>
30 #include <range/v3/view/split.hpp>
31 
32 #include <range/v3/detail/prologue.hpp>
33 
34 namespace ranges
35 {
38  namespace actions
39  {
40  struct split_fn
41  {
42  template<typename Rng>
43  using split_value_t =
44  meta::if_c<(bool)ranges::container<Rng>, //
45  uncvref_t<Rng>, std::vector<range_value_t<Rng>>>;
46 
47  template(typename T)(
48  requires range<T &>)
49  constexpr auto operator()(T & t) const
50  {
51  return make_action_closure(
52  bind_back(split_fn{}, detail::reference_wrapper_<T>(t)));
53  }
54 
55  template<typename T>
56  constexpr auto operator()(T && t) const
57  {
58  return make_action_closure(bind_back(split_fn{}, static_cast<T &&>(t)));
59  }
60 
61  // BUGBUG something is not right with the actions. It should be possible
62  // to move a container into a split and have elements moved into the result.
63  template(typename Rng)(
64  requires input_range<Rng> AND indirectly_comparable<
65  iterator_t<Rng>, range_value_t<Rng> const *, ranges::equal_to>)
66  std::vector<split_value_t<Rng>> //
67  operator()(Rng && rng, range_value_t<Rng> val) const
68  {
69  return views::split(rng, std::move(val)) |
70  to<std::vector<split_value_t<Rng>>>();
71  }
72 
73  template(typename Rng, typename Pattern)(
74  requires input_range<Rng> AND viewable_range<Pattern> AND
75  forward_range<Pattern> AND
79  ranges::equal_to> AND
80  (forward_range<Rng> || detail::tiny_range<Pattern>)) //
81  std::vector<split_value_t<Rng>> operator()(Rng && rng, Pattern && pattern)
82  const
83  {
84  return views::split(rng, static_cast<Pattern &&>(pattern)) |
85  to<std::vector<split_value_t<Rng>>>();
86  }
87 
89  template<typename Rng, typename T>
90  invoke_result_t<split_fn, Rng, T &> //
91  operator()(Rng && rng, detail::reference_wrapper_<T> r) const
92  {
93  return (*this)(static_cast<Rng &&>(rng), r.get());
94  }
96  };
97 
100  } // namespace actions
102 } // namespace ranges
103 
104 #include <range/v3/detail/epilogue.hpp>
105 
106 #endif
CPP_concept indirectly_comparable
\concept indirectly_comparable
Definition: concepts.hpp:832
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:994
Tiny meta-programming library.
Definition: split.hpp:41
Definition: comparisons.hpp:28