Horizon
replace.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_HPP
15 #define RANGES_V3_VIEW_REPLACE_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 
27 #include <range/v3/utility/static_const.hpp>
28 #include <range/v3/view/all.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  template<typename Val1, typename Val2>
40  struct replacer_fn
41  {
42  private:
43  Val1 old_value_;
44  Val2 new_value_;
45 
46  public:
47  replacer_fn() = default;
48  constexpr replacer_fn(Val1 old_value, Val2 new_value)
49  : old_value_(std::move(old_value))
50  , new_value_(std::move(new_value))
51  {}
52 
53  template<typename I>
54  [[noreturn]] common_type_t<decay_t<unwrap_reference_t<Val2 const &>>,
55  iter_value_t<I>> &
56  operator()(copy_tag, I const &) const
57  {
58  RANGES_EXPECT(false);
59  }
60 
61  template<typename I>
62  common_reference_t<unwrap_reference_t<Val2 const &>, iter_reference_t<I>>
63  operator()(I const & i) const
64  {
65  auto && x = *i;
66  if(x == unwrap_reference(old_value_))
67  return unwrap_reference(new_value_);
68  return ((decltype(x) &&)x);
69  }
70 
71  template<typename I>
72  common_reference_t<unwrap_reference_t<Val2 const &>,
73  iter_rvalue_reference_t<I>>
74  operator()(move_tag, I const & i) const
75  {
76  auto && x = iter_move(i);
77  if(x == unwrap_reference(old_value_))
78  return unwrap_reference(new_value_);
79  return ((decltype(x) &&)x);
80  }
81  };
82  } // namespace detail
84 
87  namespace views
88  {
90  {
91  template(typename Rng, typename Val1, typename Val2)(
92  requires viewable_range<Rng> AND input_range<Rng> AND
93  same_as<
94  detail::decay_t<unwrap_reference_t<Val1>>,
95  detail::decay_t<unwrap_reference_t<Val2>>> AND
96  equality_comparable_with<
97  detail::decay_t<unwrap_reference_t<Val1>>,
98  range_value_t<Rng>> AND
99  common_with<detail::decay_t<unwrap_reference_t<Val2 const &>>,
100  range_value_t<Rng>> AND
101  common_reference_with<unwrap_reference_t<Val2 const &>,
102  range_reference_t<Rng>> AND
103  common_reference_with<
105  range_rvalue_reference_t<Rng>>)
106  constexpr replace_view< //
107  all_t<Rng>, //
108  detail::decay_t<Val1>, //
109  detail::decay_t<Val2>> //
110  operator()(Rng && rng, Val1 && old_value,
111  Val2 && new_value) const //
112  {
113  return {
114  all(static_cast<Rng &&>(rng)),
115  {static_cast<Val1 &&>(old_value), static_cast<Val2 &&>(new_value)}};
116  }
117  };
118 
120  {
121  using replace_base_fn::operator();
122 
123  template(typename Val1, typename Val2)(
124  requires same_as<detail::decay_t<unwrap_reference_t<Val1>>,
125  detail::decay_t<unwrap_reference_t<Val2>>>)
126  constexpr auto operator()(Val1 old_value, Val2 new_value) const
127  {
128  return make_view_closure(bind_back(
129  replace_base_fn{}, std::move(old_value), std::move(new_value)));
130  }
131  };
132 
136  } // namespace views
138 } // namespace ranges
139 
140 #include <range/v3/detail/epilogue.hpp>
141 
142 #endif
decltype(unwrap_reference(std::declval< T >())) unwrap_reference_t
Definition: reference_wrapper.hpp:178
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: transform.hpp:111
Definition: replace.hpp:90
Definition: replace.hpp:120