File indexing completed on 2025-01-18 10:09:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_VIEW_REPLACE_HPP
0015 #define RANGES_V3_VIEW_REPLACE_HPP
0016
0017 #include <type_traits>
0018 #include <utility>
0019
0020 #include <meta/meta.hpp>
0021
0022 #include <concepts/concepts.hpp>
0023
0024 #include <range/v3/range_fwd.hpp>
0025
0026 #include <range/v3/functional/bind_back.hpp>
0027 #include <range/v3/utility/static_const.hpp>
0028 #include <range/v3/view/all.hpp>
0029 #include <range/v3/view/transform.hpp>
0030 #include <range/v3/view/view.hpp>
0031
0032 #include <range/v3/detail/prologue.hpp>
0033
0034 namespace ranges
0035 {
0036
0037 namespace detail
0038 {
0039 template<typename Val1, typename Val2>
0040 struct replacer_fn
0041 {
0042 private:
0043 Val1 old_value_;
0044 Val2 new_value_;
0045
0046 public:
0047 replacer_fn() = default;
0048 constexpr replacer_fn(Val1 old_value, Val2 new_value)
0049 : old_value_(std::move(old_value))
0050 , new_value_(std::move(new_value))
0051 {}
0052
0053 template<typename I>
0054 [[noreturn]] common_type_t<decay_t<unwrap_reference_t<Val2 const &>>,
0055 iter_value_t<I>> &
0056 operator()(copy_tag, I const &) const
0057 {
0058 RANGES_EXPECT(false);
0059 }
0060
0061 template<typename I>
0062 common_reference_t<unwrap_reference_t<Val2 const &>, iter_reference_t<I>>
0063 operator()(I const & i) const
0064 {
0065 auto && x = *i;
0066 if(x == unwrap_reference(old_value_))
0067 return unwrap_reference(new_value_);
0068 return ((decltype(x) &&)x);
0069 }
0070
0071 template<typename I>
0072 common_reference_t<unwrap_reference_t<Val2 const &>,
0073 iter_rvalue_reference_t<I>>
0074 operator()(move_tag, I const & i) const
0075 {
0076 auto && x = iter_move(i);
0077 if(x == unwrap_reference(old_value_))
0078 return unwrap_reference(new_value_);
0079 return ((decltype(x) &&)x);
0080 }
0081 };
0082 }
0083
0084
0085
0086
0087 namespace views
0088 {
0089 struct replace_base_fn
0090 {
0091 template(typename Rng, typename Val1, typename Val2)(
0092 requires viewable_range<Rng> AND input_range<Rng> AND
0093 same_as<
0094 detail::decay_t<unwrap_reference_t<Val1>>,
0095 detail::decay_t<unwrap_reference_t<Val2>>> AND
0096 equality_comparable_with<
0097 detail::decay_t<unwrap_reference_t<Val1>>,
0098 range_value_t<Rng>> AND
0099 common_with<detail::decay_t<unwrap_reference_t<Val2 const &>>,
0100 range_value_t<Rng>> AND
0101 common_reference_with<unwrap_reference_t<Val2 const &>,
0102 range_reference_t<Rng>> AND
0103 common_reference_with<
0104 unwrap_reference_t<Val2 const &>,
0105 range_rvalue_reference_t<Rng>>)
0106 constexpr replace_view<
0107 all_t<Rng>,
0108 detail::decay_t<Val1>,
0109 detail::decay_t<Val2>>
0110 operator()(Rng && rng, Val1 && old_value,
0111 Val2 && new_value) const
0112 {
0113 return {
0114 all(static_cast<Rng &&>(rng)),
0115 {static_cast<Val1 &&>(old_value), static_cast<Val2 &&>(new_value)}};
0116 }
0117 };
0118
0119 struct replace_fn : replace_base_fn
0120 {
0121 using replace_base_fn::operator();
0122
0123 template(typename Val1, typename Val2)(
0124 requires same_as<detail::decay_t<unwrap_reference_t<Val1>>,
0125 detail::decay_t<unwrap_reference_t<Val2>>>)
0126 constexpr auto operator()(Val1 old_value, Val2 new_value) const
0127 {
0128 return make_view_closure(bind_back(
0129 replace_base_fn{}, std::move(old_value), std::move(new_value)));
0130 }
0131 };
0132
0133
0134
0135 RANGES_INLINE_VARIABLE(replace_fn, replace)
0136 }
0137
0138 }
0139
0140 #include <range/v3/detail/epilogue.hpp>
0141
0142 #endif