Horizon
trim.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Johel Guerrero 2019
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_TRIM_HPP
15 #define RANGES_V3_VIEW_TRIM_HPP
16 
17 #include <utility>
18 
19 #include <concepts/concepts.hpp>
20 
22 #include <range/v3/detail/config.hpp>
32 #include <range/v3/view/all.hpp>
34 #include <range/v3/view/view.hpp>
35 
36 #include <range/v3/detail/prologue.hpp>
37 
38 namespace ranges
39 {
42  template<typename Rng, typename Pred>
43  struct trim_view : view_interface<trim_view<Rng, Pred>>
44  {
45  private:
46  Rng rng_;
47  semiregular_box_t<Pred> pred_;
48  detail::non_propagating_cache<iterator_t<Rng>> begin_;
49  detail::non_propagating_cache<iterator_t<Rng>> end_;
50 
51  public:
52  CPP_assert(bidirectional_range<Rng> && view_<Rng> && indirect_unary_predicate<
53  Pred, iterator_t<Rng>> && common_range<Rng>);
54 
55  trim_view() = default;
56  constexpr trim_view(Rng rng, Pred pred)
57  : rng_(std::move(rng))
58  , pred_(std::move(pred))
59  {}
60 
61  iterator_t<Rng> begin()
62  {
63  if(!begin_)
64  begin_ = find_if_not(rng_, std::ref(pred_));
65  return *begin_;
66  }
67  iterator_t<Rng> end()
68  {
69  if(!end_)
70  {
71  const auto first = begin();
72  auto last = ranges::end(rng_);
73  while(last != first)
74  if(!invoke(pred_, *--last))
75  {
76  ++last;
77  break;
78  }
79  end_ = std::move(last);
80  }
81  return *end_;
82  }
83 
84  Rng base() const
85  {
86  return rng_;
87  }
88  };
89 
90  template<typename Rng, typename Pred>
91  RANGES_INLINE_VAR constexpr bool enable_borrowed_range<trim_view<Rng, Pred>> = //
92  enable_borrowed_range<Rng>;
93 
94 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
95  template<typename Rng, typename Pred>
96  trim_view(Rng &&, Pred) //
98 #endif
99 
100  template<typename Rng, typename Pred>
101  RANGES_INLINE_VAR constexpr bool disable_sized_range<trim_view<Rng, Pred>> = true;
102 
103  namespace views
104  {
106  {
107  template(typename Rng, typename Pred)(
108  requires viewable_range<Rng> AND bidirectional_range<Rng> AND
110  common_range<Rng>)
111  constexpr trim_view<all_t<Rng>, Pred> //
112  operator()(Rng && rng, Pred pred) const //
113  {
114  return {all(static_cast<Rng &&>(rng)), std::move(pred)};
115  }
116  template(typename Rng, typename Pred, typename Proj)(
117  requires viewable_range<Rng> AND bidirectional_range<Rng> AND
119  common_range<Rng>)
121  operator()(Rng && rng, Pred pred, Proj proj) const
122  {
123  return {all(static_cast<Rng &&>(rng)),
124  compose(std::move(pred), std::move(proj))};
125  }
126  };
127 
129  {
130  template<typename Pred>
131  constexpr auto operator()(Pred pred) const // TODO: underconstrained
132  {
133  return make_view_closure(bind_back(trim_base_fn{}, std::move(pred)));
134  }
135  template(typename Pred, typename Proj)(
136  requires (!range<Pred>)) // TODO: underconstrained
137  constexpr auto operator()(Pred && pred, Proj proj) const
138  {
139  return make_view_closure(bind_back(
140  trim_base_fn{}, static_cast<Pred &&>(pred), std::move(proj)));
141  }
142  };
143 
144  struct RANGES_EMPTY_BASES trim_fn
146  {
147  using trim_base_fn::operator();
148  using trim_bind_fn::operator();
149  };
150 
154  } // namespace views
156 } // namespace ranges
157 
158 #include <range/v3/detail/epilogue.hpp>
159 #include <range/v3/detail/satisfy_boost_range.hpp>
160 RANGES_SATISFY_BOOST_RANGE(::ranges::trim_view)
161 
162 #endif // RANGES_V3_VIEW_TRIM_HPP
CPP_concept indirect_unary_predicate
\concept indirect_unary_predicate
Definition: concepts.hpp:632
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
Definition: compose.hpp:33
Definition: trim.hpp:44
Definition: interface.hpp:129
Definition: trim.hpp:106
Definition: trim.hpp:129
Definition: trim.hpp:146