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_IF_HPP
0015 #define RANGES_V3_VIEW_REPLACE_IF_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/functional/invoke.hpp>
0028 #include <range/v3/utility/compressed_pair.hpp>
0029 #include <range/v3/utility/semiregular_box.hpp>
0030 #include <range/v3/utility/static_const.hpp>
0031 #include <range/v3/view/all.hpp>
0032 #include <range/v3/view/transform.hpp>
0033 #include <range/v3/view/view.hpp>
0034
0035 #include <range/v3/detail/prologue.hpp>
0036
0037 namespace ranges
0038 {
0039
0040 namespace detail
0041 {
0042 template<typename Pred, typename Val>
0043 struct replacer_if_fn : compressed_pair<semiregular_box_t<Pred>, Val>
0044 {
0045 private:
0046 using base_t = compressed_pair<semiregular_box_t<Pred>, Val>;
0047 using base_t::first;
0048 using base_t::second;
0049
0050 public:
0051 replacer_if_fn() = default;
0052 constexpr replacer_if_fn(Pred pred, Val new_value)
0053 : base_t{std::move(pred), std::move(new_value)}
0054 {}
0055
0056 template<typename I>
0057 [[noreturn]] common_type_t<decay_t<unwrap_reference_t<Val const &>>,
0058 iter_value_t<I>> &
0059 operator()(copy_tag, I const &) const
0060 {
0061 RANGES_EXPECT(false);
0062 }
0063
0064 template(typename I)(
0065 requires (!invocable<Pred const &, iter_reference_t<I>>))
0066 common_reference_t<unwrap_reference_t<Val const &>, iter_reference_t<I>>
0067 operator()(I const & i)
0068 {
0069 auto && x = *i;
0070 if(invoke(first(), (decltype(x) &&)x))
0071 return unwrap_reference(second());
0072 return (decltype(x) &&)x;
0073 }
0074 template(typename I)(
0075 requires invocable<Pred const &, iter_reference_t<I>>)
0076 common_reference_t<unwrap_reference_t<Val const &>, iter_reference_t<I>>
0077 operator()(I const & i) const
0078 {
0079 auto && x = *i;
0080 if(invoke(first(), (decltype(x) &&)x))
0081 return unwrap_reference(second());
0082 return (decltype(x) &&)x;
0083 }
0084
0085 template(typename I)(
0086 requires (!invocable<Pred const &, iter_rvalue_reference_t<I>>))
0087 common_reference_t<
0088 unwrap_reference_t<Val const &>,
0089 iter_rvalue_reference_t<I>>
0090 operator()(move_tag, I const & i)
0091 {
0092 auto && x = iter_move(i);
0093 if(invoke(first(), (decltype(x) &&)x))
0094 return unwrap_reference(second());
0095 return (decltype(x) &&)x;
0096 }
0097 template(typename I)(
0098 requires invocable<Pred const &, iter_rvalue_reference_t<I>>)
0099 common_reference_t<
0100 unwrap_reference_t<Val const &>,
0101 iter_rvalue_reference_t<I>>
0102 operator()(move_tag, I const & i) const
0103 {
0104 auto && x = iter_move(i);
0105 if(invoke(first(), (decltype(x) &&)x))
0106 return unwrap_reference(second());
0107 return (decltype(x) &&)x;
0108 }
0109 };
0110 }
0111
0112
0113
0114
0115 namespace views
0116 {
0117 struct replace_if_base_fn
0118 {
0119 template(typename Rng, typename Pred, typename Val)(
0120 requires viewable_range<Rng> AND input_range<Rng> AND
0121 indirect_unary_predicate<Pred, iterator_t<Rng>> AND
0122 common_with<detail::decay_t<unwrap_reference_t<Val const &>>,
0123 range_value_t<Rng>> AND
0124 common_reference_with<unwrap_reference_t<Val const &>,
0125 range_reference_t<Rng>> AND
0126 common_reference_with<unwrap_reference_t<Val const &>,
0127 range_rvalue_reference_t<Rng>>)
0128 constexpr replace_if_view<all_t<Rng>, Pred, Val>
0129 operator()(Rng && rng, Pred pred, Val new_value) const
0130 {
0131 return {all(static_cast<Rng &&>(rng)),
0132 {std::move(pred), std::move(new_value)}};
0133 }
0134 };
0135
0136 struct replace_if_fn : replace_if_base_fn
0137 {
0138 using replace_if_base_fn::operator();
0139
0140 template<typename Pred, typename Val>
0141 constexpr auto operator()(Pred pred, Val new_value) const
0142 {
0143 return make_view_closure(bind_back(
0144 replace_if_base_fn{}, std::move(pred), std::move(new_value)));
0145 }
0146 };
0147
0148
0149
0150 RANGES_INLINE_VARIABLE(replace_if_fn, replace_if)
0151 }
0152
0153 }
0154
0155 #include <range/v3/detail/epilogue.hpp>
0156
0157 #endif