Horizon
adjacent_filter.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_VIEW_ADJACENT_FILTER_HPP
15 #define RANGES_V3_VIEW_ADJACENT_FILTER_HPP
16 
17 #include <utility>
18 
19 #include <meta/meta.hpp>
20 
21 #include <range/v3/range_fwd.hpp>
22 
28 #include <range/v3/utility/static_const.hpp>
30 #include <range/v3/view/view.hpp>
31 
32 #include <range/v3/detail/prologue.hpp>
33 
34 namespace ranges
35 {
37  namespace detail
38  {
39  // clang-format off
42  template(typename Rng, typename Pred)(
43  concept (adjacent_filter_constraints_)(Rng, Pred),
44  indirect_binary_predicate_<Pred, iterator_t<Rng>, iterator_t<Rng>>
45  );
48  template<typename Rng, typename Pred>
49  CPP_concept adjacent_filter_constraints =
50  viewable_range<Rng> && forward_range<Rng> &&
51  CPP_concept_ref(detail::adjacent_filter_constraints_, Rng, Pred);
52  // clang-format on
53  } // namespace detail
55 
58  template<typename Rng, typename Pred>
59  struct RANGES_EMPTY_BASES adjacent_filter_view
61  is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
63  {
64  private:
65  friend range_access;
66 
67  template<bool Const>
68  struct adaptor : adaptor_base
69  {
70  private:
71  friend struct adaptor<!Const>;
72  using CRng = meta::const_if_c<Const, Rng>;
73  using Parent = meta::const_if_c<Const, adjacent_filter_view>;
74  Parent * rng_;
75 
76  public:
77  adaptor() = default;
78  constexpr adaptor(Parent * rng) noexcept
79  : rng_(rng)
80  {}
81  template(bool Other)(
82  requires Const && CPP_NOT(Other)) //
83  constexpr adaptor(adaptor<Other> that)
84  : rng_(that.rng_)
85  {}
86  constexpr void next(iterator_t<CRng> & it) const
87  {
88  auto const last = ranges::end(rng_->base());
89  auto & pred = rng_->adjacent_filter_view::box::get();
90  RANGES_EXPECT(it != last);
91  for(auto tmp = it; ++it != last; tmp = it)
92  if(invoke(pred, *tmp, *it))
93  break;
94  }
95  CPP_member
96  constexpr auto prev(iterator_t<CRng> & it) const //
97  -> CPP_ret(void)(
98  requires bidirectional_range<CRng>)
99  {
100  auto const first = ranges::begin(rng_->base());
101  auto & pred = rng_->adjacent_filter_view::box::get();
102  RANGES_EXPECT(it != first);
103  --it;
104  while(it != first)
105  {
106  auto tmp = it;
107  if(invoke(pred, *--tmp, *it))
108  break;
109  it = tmp;
110  }
111  }
112  void distance_to() = delete;
113  };
114  constexpr adaptor<false> begin_adaptor() noexcept
115  {
116  return {this};
117  }
118  CPP_member
119  constexpr auto begin_adaptor() const noexcept //
120  -> CPP_ret(adaptor<true>)(
121  requires detail::adjacent_filter_constraints<Rng const, Pred const>)
122  {
123  return {this};
124  }
125  constexpr adaptor<false> end_adaptor() noexcept
126  {
127  return {this};
128  }
129  CPP_member
130  constexpr auto end_adaptor() const noexcept //
131  -> CPP_ret(adaptor<true>)(
132  requires detail::adjacent_filter_constraints<Rng const, Pred const>)
133  {
134  return {this};
135  }
136 
137  public:
138  adjacent_filter_view() = default;
139  constexpr adjacent_filter_view(Rng rng, Pred pred)
140  : adjacent_filter_view::view_adaptor{detail::move(rng)}
141  , adjacent_filter_view::box(detail::move(pred))
142  {}
143  };
144 
145 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
146  template(typename Rng, typename Fun)(
147  requires copy_constructible<Rng>)
148  adjacent_filter_view(Rng &&, Fun)
149  ->adjacent_filter_view<views::all_t<Rng>, Fun>;
150 #endif
151 
152  namespace views
153  {
155  {
156  template(typename Rng, typename Pred)(
157  requires detail::adjacent_filter_constraints<Rng, Pred>)
158  constexpr adjacent_filter_view<all_t<Rng>, Pred> //
159  operator()(Rng && rng, Pred pred) const
160  {
161  return {all(static_cast<Rng &&>(rng)), std::move(pred)};
162  }
163  };
164 
166  {
167  using adjacent_filter_base_fn::operator();
168 
169  template<typename Pred>
170  constexpr auto operator()(Pred pred) const
171  {
172  return make_view_closure(
173  bind_back(adjacent_filter_base_fn{}, std::move(pred)));
174  }
175  };
176 
180  } // namespace views
182 } // namespace ranges
183 
184 #include <range/v3/detail/epilogue.hpp>
185 
186 #include <range/v3/detail/satisfy_boost_range.hpp>
187 RANGES_SATISFY_BOOST_RANGE(::ranges::adjacent_filter_view)
188 
189 #endif
Definition: box.hpp:163
CPP_concept indirect_binary_predicate_
\concept indirect_binary_predicate_
Definition: concepts.hpp:651
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
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition: meta.hpp:541
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:994
front< Pair > first
Retrieve the first element of the pair Pair.
Definition: meta.hpp:2251
Tiny meta-programming library.
Definition: adaptor.hpp:110
Definition: adjacent_filter.hpp:63
Definition: traits.hpp:128
Definition: adaptor.hpp:475
Definition: adjacent_filter.hpp:155
Definition: adjacent_filter.hpp:166