Back to home page

EIC code displayed by LXR

 
 

    


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

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_ADJACENT_REMOVE_IF_HPP
0015 #define RANGES_V3_VIEW_ADJACENT_REMOVE_IF_HPP
0016 
0017 #include <utility>
0018 
0019 #include <meta/meta.hpp>
0020 
0021 #include <range/v3/range_fwd.hpp>
0022 
0023 #include <range/v3/functional/bind_back.hpp>
0024 #include <range/v3/functional/invoke.hpp>
0025 #include <range/v3/range/access.hpp>
0026 #include <range/v3/utility/box.hpp>
0027 #include <range/v3/utility/optional.hpp>
0028 #include <range/v3/utility/semiregular_box.hpp>
0029 #include <range/v3/utility/static_const.hpp>
0030 #include <range/v3/view/adaptor.hpp>
0031 #include <range/v3/view/view.hpp>
0032 
0033 #include <range/v3/detail/prologue.hpp>
0034 
0035 namespace ranges
0036 {
0037     /// \addtogroup group-views
0038     /// @{
0039     template<typename Rng, typename Pred>
0040     struct RANGES_EMPTY_BASES adjacent_remove_if_view
0041       : view_adaptor<adjacent_remove_if_view<Rng, Pred>, Rng,
0042                      is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
0043       , private box<semiregular_box_t<Pred>, adjacent_remove_if_view<Rng, Pred>>
0044     {
0045         adjacent_remove_if_view() = default;
0046         constexpr adjacent_remove_if_view(Rng rng, Pred pred)
0047           : adjacent_remove_if_view::view_adaptor{detail::move(rng)}
0048           , adjacent_remove_if_view::box(detail::move(pred))
0049         {}
0050 
0051     private:
0052         friend range_access;
0053 
0054         struct adaptor : adaptor_base
0055         {
0056         private:
0057             adjacent_remove_if_view * rng_;
0058 
0059         public:
0060             adaptor() = default;
0061             constexpr adaptor(adjacent_remove_if_view * rng) noexcept
0062               : rng_(rng)
0063             {}
0064             static constexpr iterator_t<Rng> begin(adjacent_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         constexpr adaptor begin_adaptor()
0084         {
0085             cache_begin();
0086             return {this};
0087         }
0088         CPP_member
0089         constexpr auto end_adaptor() //
0090             -> CPP_ret(adaptor)(
0091                 requires common_range<Rng>)
0092         {
0093             if(bidirectional_range<Rng>)
0094                 cache_begin();
0095             return {this};
0096         }
0097         CPP_member
0098         constexpr auto end_adaptor() noexcept //
0099             -> CPP_ret(adaptor_base)(
0100                 requires (!common_range<Rng>))
0101         {
0102             return {};
0103         }
0104 
0105         constexpr void satisfy_forward(iterator_t<Rng> & it)
0106         {
0107             auto const last = ranges::end(this->base());
0108             if(it == last)
0109                 return;
0110             auto & pred = this->adjacent_remove_if_view::box::get();
0111             for(auto nxt = it; ++nxt != last && invoke(pred, *it, *nxt); it = nxt)
0112                 ;
0113         }
0114         constexpr void satisfy_reverse(iterator_t<Rng> & it)
0115         {
0116             auto const & first = *begin_;
0117             RANGES_ASSERT(it != first);
0118             (void)first;
0119             auto prv = it;
0120             --it;
0121             if(prv == ranges::end(this->base()))
0122             {
0123                 return;
0124             }
0125             auto & pred = this->adjacent_remove_if_view::box::get();
0126             for(; invoke(pred, *it, *prv); prv = it, --it)
0127                 RANGES_ASSERT(it != first);
0128         }
0129 
0130         void cache_begin()
0131         {
0132             if(begin_)
0133                 return;
0134             auto it = ranges::begin(this->base());
0135             satisfy_forward(it);
0136             begin_.emplace(std::move(it));
0137         }
0138 
0139         detail::non_propagating_cache<iterator_t<Rng>> begin_;
0140     };
0141 
0142 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0143     template(typename Rng, typename Fun)(
0144         requires copy_constructible<Rng>)
0145     adjacent_remove_if_view(Rng &&, Fun)
0146         -> adjacent_remove_if_view<views::all_t<Rng>, Fun>;
0147 #endif
0148 
0149     namespace views
0150     {
0151         struct adjacent_remove_if_base_fn
0152         {
0153             template(typename Rng, typename Pred)(
0154                 requires viewable_range<Rng> AND forward_range<Rng> AND
0155                     indirect_binary_predicate_<Pred, iterator_t<Rng>, iterator_t<Rng>>)
0156             constexpr adjacent_remove_if_view<all_t<Rng>, Pred> //
0157             operator()(Rng && rng, Pred pred) const
0158             {
0159                 return {all(static_cast<Rng &&>(rng)), std::move(pred)};
0160             }
0161         };
0162 
0163         struct adjacent_remove_if_fn : adjacent_remove_if_base_fn
0164         {
0165             using adjacent_remove_if_base_fn::operator();
0166 
0167             template<typename Pred>
0168             constexpr auto operator()(Pred pred) const
0169             {
0170                 return make_view_closure(
0171                     bind_back(adjacent_remove_if_base_fn{}, std::move(pred)));
0172             }
0173         };
0174 
0175         /// \relates adjacent_remove_if_fn
0176         /// \ingroup group-views
0177         RANGES_INLINE_VARIABLE(adjacent_remove_if_fn, adjacent_remove_if)
0178     } // namespace views
0179     /// @}
0180 } // namespace ranges
0181 
0182 #include <range/v3/detail/epilogue.hpp>
0183 #include <range/v3/detail/satisfy_boost_range.hpp>
0184 RANGES_SATISFY_BOOST_RANGE(::ranges::adjacent_remove_if_view)
0185 
0186 #endif