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_REMOVE_IF_HPP
0015 #define RANGES_V3_VIEW_REMOVE_IF_HPP
0016 
0017 #include <type_traits>
0018 #include <utility>
0019 
0020 #include <meta/meta.hpp>
0021 
0022 #include <range/v3/range_fwd.hpp>
0023 
0024 #include <range/v3/functional/bind_back.hpp>
0025 #include <range/v3/functional/compose.hpp>
0026 #include <range/v3/functional/invoke.hpp>
0027 #include <range/v3/range/access.hpp>
0028 #include <range/v3/range/concepts.hpp>
0029 #include <range/v3/range/traits.hpp>
0030 #include <range/v3/utility/box.hpp>
0031 #include <range/v3/utility/optional.hpp>
0032 #include <range/v3/utility/semiregular_box.hpp>
0033 #include <range/v3/utility/static_const.hpp>
0034 #include <range/v3/view/adaptor.hpp>
0035 #include <range/v3/view/view.hpp>
0036 
0037 #include <range/v3/detail/prologue.hpp>
0038 
0039 namespace ranges
0040 {
0041     /// \addtogroup group-views
0042     /// @{
0043     template<typename Rng, typename Pred>
0044     struct RANGES_EMPTY_BASES remove_if_view
0045       : view_adaptor<remove_if_view<Rng, Pred>, Rng,
0046                      is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
0047       , private box<semiregular_box_t<Pred>>
0048     {
0049         remove_if_view() = default;
0050         constexpr remove_if_view(Rng rng, Pred pred)
0051           : remove_if_view::view_adaptor{detail::move(rng)}
0052           , remove_if_view::box(detail::move(pred))
0053         {}
0054 
0055     private:
0056         friend range_access;
0057 
0058         struct adaptor : adaptor_base
0059         {
0060             adaptor() = default;
0061             constexpr adaptor(remove_if_view * rng) noexcept
0062               : rng_(rng)
0063             {}
0064             static constexpr iterator_t<Rng> begin(remove_if_view & rng)
0065             {
0066                 return *rng.begin_;
0067             }
0068             constexpr void next(iterator_t<Rng> & it) const
0069             {
0070                 RANGES_ASSERT(it != ranges::end(rng_->base()));
0071                 rng_->satisfy_forward(++it);
0072             }
0073             CPP_member
0074             constexpr auto prev(iterator_t<Rng> & it) const //
0075                 -> CPP_ret(void)(
0076                     requires bidirectional_range<Rng>)
0077             {
0078                 rng_->satisfy_reverse(it);
0079             }
0080             void advance() = delete;
0081             void distance_to() = delete;
0082 
0083         private:
0084             remove_if_view * rng_;
0085         };
0086         constexpr adaptor begin_adaptor()
0087         {
0088             cache_begin();
0089             return {this};
0090         }
0091         CPP_member
0092         constexpr auto end_adaptor() const noexcept //
0093             -> CPP_ret(adaptor_base)(
0094                 requires (!common_range<Rng>))
0095         {
0096             return {};
0097         }
0098         CPP_member
0099         constexpr auto end_adaptor() //
0100             -> CPP_ret(adaptor)(
0101                 requires common_range<Rng>)
0102         {
0103             if(bidirectional_range<Rng>)
0104                 cache_begin();
0105             return {this};
0106         }
0107 
0108         constexpr void satisfy_forward(iterator_t<Rng> & it)
0109         {
0110             auto const last = ranges::end(this->base());
0111             auto & pred = this->remove_if_view::box::get();
0112             while(it != last && invoke(pred, *it))
0113                 ++it;
0114         }
0115         constexpr void satisfy_reverse(iterator_t<Rng> & it)
0116         {
0117             RANGES_ASSERT(begin_);
0118             auto const & first = *begin_;
0119             auto & pred = this->remove_if_view::box::get();
0120             do
0121             {
0122                 RANGES_ASSERT(it != first);
0123                 (void)first;
0124                 --it;
0125             } while(invoke(pred, *it));
0126         }
0127 
0128         constexpr void cache_begin()
0129         {
0130             if(begin_)
0131                 return;
0132             auto it = ranges::begin(this->base());
0133             satisfy_forward(it);
0134             begin_.emplace(std::move(it));
0135         }
0136 
0137         detail::non_propagating_cache<iterator_t<Rng>> begin_;
0138     };
0139 
0140 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0141     template(typename Rng, typename Pred)(
0142         requires copy_constructible<Pred>)
0143     remove_if_view(Rng &&, Pred)
0144         -> remove_if_view<views::all_t<Rng>, Pred>;
0145 #endif
0146 
0147     namespace views
0148     {
0149         /// Given a source range, unary predicate, and optional projection,
0150         /// present a view of the elements that do not satisfy the predicate.
0151         struct remove_if_base_fn
0152         {
0153             template(typename Rng, typename Pred)(
0154                 requires viewable_range<Rng> AND input_range<Rng> AND
0155                     indirect_unary_predicate<Pred, iterator_t<Rng>>)
0156             constexpr remove_if_view<all_t<Rng>, Pred> operator()(Rng && rng, Pred pred)
0157                 const
0158             {
0159                 return remove_if_view<all_t<Rng>, Pred>{all(static_cast<Rng &&>(rng)),
0160                                                         std::move(pred)};
0161             }
0162             template(typename Rng, typename Pred, typename Proj)(
0163                 requires viewable_range<Rng> AND input_range<Rng> AND
0164                     indirect_unary_predicate<Pred, projected<iterator_t<Rng>, Proj>>)
0165             constexpr remove_if_view<all_t<Rng>, composed<Pred, Proj>> //
0166             operator()(Rng && rng, Pred pred, Proj proj) const
0167             {
0168                 return remove_if_view<all_t<Rng>, composed<Pred, Proj>>{
0169                     all(static_cast<Rng &&>(rng)),
0170                     compose(std::move(pred), std::move(proj))};
0171             }
0172         };
0173 
0174         struct remove_if_bind_fn
0175         {
0176             template<typename Pred>
0177             constexpr auto operator()(Pred pred) const // TODO: underconstrained
0178             {
0179                 return make_view_closure(bind_back(remove_if_base_fn{}, std::move(pred)));
0180             }
0181             template(typename Pred, typename Proj)(
0182                 requires (!range<Pred>)) // TODO: underconstrained
0183             constexpr auto operator()(Pred && pred, Proj proj) const
0184             {
0185                 return make_view_closure(bind_back(
0186                     remove_if_base_fn{}, static_cast<Pred &&>(pred), std::move(proj)));
0187             }
0188         };
0189 
0190         struct RANGES_EMPTY_BASES remove_if_fn
0191           : remove_if_base_fn, remove_if_bind_fn
0192         {
0193             using remove_if_base_fn::operator();
0194             using remove_if_bind_fn::operator();
0195         };
0196 
0197         /// \relates remove_if_fn
0198         /// \ingroup group-views
0199         RANGES_INLINE_VARIABLE(remove_if_fn, remove_if)
0200     } // namespace views
0201     /// @}
0202 } // namespace ranges
0203 
0204 #include <range/v3/detail/satisfy_boost_range.hpp>
0205 RANGES_SATISFY_BOOST_RANGE(::ranges::remove_if_view)
0206 
0207 #include <range/v3/detail/epilogue.hpp>
0208 
0209 #endif