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_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     /// \cond
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     } // namespace detail
0111     /// \endcond
0112 
0113     /// \addtogroup group-views
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         /// \relates replace_if_fn
0149         /// \ingroup group-views
0150         RANGES_INLINE_VARIABLE(replace_if_fn, replace_if)
0151     } // namespace views
0152     /// @}
0153 } // namespace ranges
0154 
0155 #include <range/v3/detail/epilogue.hpp>
0156 
0157 #endif