Horizon
replace_if.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_REPLACE_IF_HPP
15 #define RANGES_V3_VIEW_REPLACE_IF_HPP
16 
17 #include <type_traits>
18 #include <utility>
19 
20 #include <meta/meta.hpp>
21 
22 #include <concepts/concepts.hpp>
23 
24 #include <range/v3/range_fwd.hpp>
25 
30 #include <range/v3/utility/static_const.hpp>
31 #include <range/v3/view/all.hpp>
33 #include <range/v3/view/view.hpp>
34 
35 #include <range/v3/detail/prologue.hpp>
36 
37 namespace ranges
38 {
40  namespace detail
41  {
42  template<typename Pred, typename Val>
43  struct replacer_if_fn : compressed_pair<semiregular_box_t<Pred>, Val>
44  {
45  private:
46  using base_t = compressed_pair<semiregular_box_t<Pred>, Val>;
47  using base_t::first;
48  using base_t::second;
49 
50  public:
51  replacer_if_fn() = default;
52  constexpr replacer_if_fn(Pred pred, Val new_value)
53  : base_t{std::move(pred), std::move(new_value)}
54  {}
55 
56  template<typename I>
57  [[noreturn]] common_type_t<decay_t<unwrap_reference_t<Val const &>>,
58  iter_value_t<I>> &
59  operator()(copy_tag, I const &) const
60  {
61  RANGES_EXPECT(false);
62  }
63 
64  template(typename I)(
65  requires (!invocable<Pred const &, iter_reference_t<I>>))
66  common_reference_t<unwrap_reference_t<Val const &>, iter_reference_t<I>> //
67  operator()(I const & i)
68  {
69  auto && x = *i;
70  if(invoke(first(), (decltype(x) &&)x)) //
71  return unwrap_reference(second());
72  return (decltype(x) &&)x;
73  }
74  template(typename I)(
75  requires invocable<Pred const &, iter_reference_t<I>>)
76  common_reference_t<unwrap_reference_t<Val const &>, iter_reference_t<I>> //
77  operator()(I const & i) const
78  {
79  auto && x = *i;
80  if(invoke(first(), (decltype(x) &&)x)) //
81  return unwrap_reference(second());
82  return (decltype(x) &&)x;
83  }
84 
85  template(typename I)(
86  requires (!invocable<Pred const &, iter_rvalue_reference_t<I>>))
87  common_reference_t<
88  unwrap_reference_t<Val const &>, //
89  iter_rvalue_reference_t<I>> //
90  operator()(move_tag, I const & i)
91  {
92  auto && x = iter_move(i);
93  if(invoke(first(), (decltype(x) &&)x)) //
94  return unwrap_reference(second());
95  return (decltype(x) &&)x;
96  }
97  template(typename I)(
98  requires invocable<Pred const &, iter_rvalue_reference_t<I>>)
99  common_reference_t< //
100  unwrap_reference_t<Val const &>, //
101  iter_rvalue_reference_t<I>> //
102  operator()(move_tag, I const & i) const
103  {
104  auto && x = iter_move(i);
105  if(invoke(first(), (decltype(x) &&)x)) //
106  return unwrap_reference(second());
107  return (decltype(x) &&)x;
108  }
109  };
110  } // namespace detail
112 
115  namespace views
116  {
118  {
119  template(typename Rng, typename Pred, typename Val)(
120  requires viewable_range<Rng> AND input_range<Rng> AND
122  common_with<detail::decay_t<unwrap_reference_t<Val const &>>,
123  range_value_t<Rng>> AND
124  common_reference_with<unwrap_reference_t<Val const &>,
125  range_reference_t<Rng>> AND
126  common_reference_with<unwrap_reference_t<Val const &>,
127  range_rvalue_reference_t<Rng>>)
128  constexpr replace_if_view<all_t<Rng>, Pred, Val> //
129  operator()(Rng && rng, Pred pred, Val new_value) const
130  {
131  return {all(static_cast<Rng &&>(rng)),
132  {std::move(pred), std::move(new_value)}};
133  }
134  };
135 
137  {
138  using replace_if_base_fn::operator();
139 
140  template<typename Pred, typename Val>
141  constexpr auto operator()(Pred pred, Val new_value) const
142  {
143  return make_view_closure(bind_back(
144  replace_if_base_fn{}, std::move(pred), std::move(new_value)));
145  }
146  };
147 
151  } // namespace views
153 } // namespace ranges
154 
155 #include <range/v3/detail/epilogue.hpp>
156 
157 #endif
decltype(unwrap_reference(std::declval< T >())) unwrap_reference_t
Definition: reference_wrapper.hpp:178
CPP_concept invocable
\concept invocable
Definition: concepts.hpp:48
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
front< pop_front< Pair > > second
Retrieve the first element of the pair Pair.
Definition: meta.hpp:2256
Tiny meta-programming library.
Definition: transform.hpp:111
Definition: replace_if.hpp:118
Definition: replace_if.hpp:137