Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:57

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
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     /// \cond
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     } // namespace detail
0083     /// \endcond
0084 
0085     /// \addtogroup group-views
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         /// \relates replace_fn
0134         /// \ingroup group-views
0135         RANGES_INLINE_VARIABLE(replace_fn, replace)
0136     } // namespace views
0137     /// @}
0138 } // namespace ranges
0139 
0140 #include <range/v3/detail/epilogue.hpp>
0141 
0142 #endif