You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

replace.hpp 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /// \file
  2. // 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. #ifndef RANGES_V3_VIEW_REPLACE_HPP
  14. #define RANGES_V3_VIEW_REPLACE_HPP
  15. #include <type_traits>
  16. #include <utility>
  17. #include <meta/meta.hpp>
  18. #include <concepts/concepts.hpp>
  19. #include <range/v3/range_fwd.hpp>
  20. #include <range/v3/functional/bind_back.hpp>
  21. #include <range/v3/utility/static_const.hpp>
  22. #include <range/v3/view/all.hpp>
  23. #include <range/v3/view/transform.hpp>
  24. #include <range/v3/view/view.hpp>
  25. RANGES_DISABLE_WARNINGS
  26. namespace ranges
  27. {
  28. /// \cond
  29. namespace detail
  30. {
  31. template<typename Val1, typename Val2>
  32. struct replacer_fn
  33. {
  34. private:
  35. Val1 old_value_;
  36. Val2 new_value_;
  37. public:
  38. replacer_fn() = default;
  39. constexpr replacer_fn(Val1 old_value, Val2 new_value)
  40. : old_value_(std::move(old_value))
  41. , new_value_(std::move(new_value))
  42. {}
  43. template<typename I>
  44. [[noreturn]] common_type_t<decay_t<unwrap_reference_t<Val2 const &>>,
  45. iter_value_t<I>> &
  46. operator()(copy_tag, I const &) const
  47. {
  48. RANGES_EXPECT(false);
  49. }
  50. template<typename I>
  51. common_reference_t<unwrap_reference_t<Val2 const &>, iter_reference_t<I>>
  52. operator()(I const & i) const
  53. {
  54. auto && x = *i;
  55. if(x == unwrap_reference(old_value_))
  56. return unwrap_reference(new_value_);
  57. return ((decltype(x) &&)x);
  58. }
  59. template<typename I>
  60. common_reference_t<unwrap_reference_t<Val2 const &>,
  61. iter_rvalue_reference_t<I>>
  62. operator()(move_tag, I const & i) const
  63. {
  64. auto && x = iter_move(i);
  65. if(x == unwrap_reference(old_value_))
  66. return unwrap_reference(new_value_);
  67. return ((decltype(x) &&)x);
  68. }
  69. };
  70. } // namespace detail
  71. /// \endcond
  72. /// \addtogroup group-views
  73. /// @{
  74. namespace views
  75. {
  76. struct replace_fn
  77. {
  78. private:
  79. friend view_access;
  80. template<typename Val1, typename Val2>
  81. static constexpr auto CPP_fun(bind)(replace_fn replace, Val1 old_value,
  82. Val2 new_value)( //
  83. requires same_as<detail::decay_t<unwrap_reference_t<Val1>>,
  84. detail::decay_t<unwrap_reference_t<Val2>>>)
  85. {
  86. return make_pipeable(
  87. bind_back(replace, std::move(old_value), std::move(new_value)));
  88. }
  89. public:
  90. template<typename Rng, typename Val1, typename Val2>
  91. constexpr auto operator()(
  92. Rng && rng, Val1 && old_value,
  93. Val2 &&
  94. new_value) const -> CPP_ret(replace_view<all_t<Rng>,
  95. detail::decay_t<Val1>,
  96. detail::decay_t<Val2>>)( //
  97. requires viewable_range<Rng> && input_range<Rng> && same_as<
  98. detail::decay_t<unwrap_reference_t<Val1>>,
  99. detail::decay_t<unwrap_reference_t<Val2>>> &&
  100. equality_comparable_with<detail::decay_t<unwrap_reference_t<Val1>>,
  101. range_value_t<Rng>> &&
  102. common_with<detail::decay_t<unwrap_reference_t<Val2 const &>>,
  103. range_value_t<Rng>> &&
  104. common_reference_with<unwrap_reference_t<Val2 const &>,
  105. range_reference_t<Rng>> &&
  106. common_reference_with<unwrap_reference_t<Val2 const &>,
  107. range_rvalue_reference_t<Rng>>)
  108. {
  109. return {
  110. all(static_cast<Rng &&>(rng)),
  111. {static_cast<Val1 &&>(old_value), static_cast<Val2 &&>(new_value)}};
  112. }
  113. };
  114. /// \relates replace_fn
  115. /// \ingroup group-views
  116. RANGES_INLINE_VARIABLE(view<replace_fn>, replace)
  117. } // namespace views
  118. /// @}
  119. } // namespace ranges
  120. RANGES_RE_ENABLE_WARNINGS
  121. #endif