Horizon
Loading...
Searching...
No Matches
adjacent_filter.hpp
Go to the documentation of this file.
1
2// 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
22
28#include <range/v3/utility/static_const.hpp>
31
32#include <range/v3/detail/prologue.hpp>
33
34namespace 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)(
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
179 RANGES_INLINE_VARIABLE(adjacent_filter_fn, adjacent_filter)
180 } // namespace views
182} // namespace ranges
183
184#include <range/v3/detail/epilogue.hpp>
185
186#include <range/v3/detail/satisfy_boost_range.hpp>
187RANGES_SATISFY_BOOST_RANGE(::ranges::adjacent_filter_view)
188
189#endif
Definition box.hpp:163
The bidirectional_range concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
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