Back to home page

EIC code displayed by LXR

 
 

    


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

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_FILTER_HPP
0015 #define RANGES_V3_VIEW_ADJACENT_FILTER_HPP
0016 
0017 #include <utility>
0018 
0019 #include <meta/meta.hpp>
0020 
0021 #include <range/v3/range_fwd.hpp>
0022 
0023 #include <range/v3/algorithm/adjacent_find.hpp>
0024 #include <range/v3/functional/bind_back.hpp>
0025 #include <range/v3/functional/invoke.hpp>
0026 #include <range/v3/range/access.hpp>
0027 #include <range/v3/utility/semiregular_box.hpp>
0028 #include <range/v3/utility/static_const.hpp>
0029 #include <range/v3/view/adaptor.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         // clang-format off
0040         /// \concept adjacent_filter_constraints_
0041         /// \brief The \c adjacent_filter_constraints_ concept
0042         template(typename Rng, typename Pred)(
0043         concept (adjacent_filter_constraints_)(Rng, Pred),
0044             indirect_binary_predicate_<Pred, iterator_t<Rng>, iterator_t<Rng>>
0045         );
0046         /// \concept adjacent_filter_constraints
0047         /// \brief The \c adjacent_filter_constraints concept
0048         template<typename Rng, typename Pred>
0049         CPP_concept adjacent_filter_constraints =
0050             viewable_range<Rng> && forward_range<Rng> &&
0051             CPP_concept_ref(detail::adjacent_filter_constraints_, Rng, Pred);
0052         // clang-format on
0053     } // namespace detail
0054     /// \endcond
0055 
0056     /// \addtogroup group-views
0057     /// @{
0058     template<typename Rng, typename Pred>
0059     struct RANGES_EMPTY_BASES adjacent_filter_view
0060       : view_adaptor<adjacent_filter_view<Rng, Pred>, Rng,
0061                      is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
0062       , private box<semiregular_box_t<Pred>, adjacent_filter_view<Rng, Pred>>
0063     {
0064     private:
0065         friend range_access;
0066 
0067         template<bool Const>
0068         struct adaptor : adaptor_base
0069         {
0070         private:
0071             friend struct adaptor<!Const>;
0072             using CRng = meta::const_if_c<Const, Rng>;
0073             using Parent = meta::const_if_c<Const, adjacent_filter_view>;
0074             Parent * rng_;
0075 
0076         public:
0077             adaptor() = default;
0078             constexpr adaptor(Parent * rng) noexcept
0079               : rng_(rng)
0080             {}
0081             template(bool Other)(
0082                 requires Const && CPP_NOT(Other)) //
0083                 constexpr adaptor(adaptor<Other> that)
0084               : rng_(that.rng_)
0085             {}
0086             constexpr void next(iterator_t<CRng> & it) const
0087             {
0088                 auto const last = ranges::end(rng_->base());
0089                 auto & pred = rng_->adjacent_filter_view::box::get();
0090                 RANGES_EXPECT(it != last);
0091                 for(auto tmp = it; ++it != last; tmp = it)
0092                     if(invoke(pred, *tmp, *it))
0093                         break;
0094             }
0095             CPP_member
0096             constexpr auto prev(iterator_t<CRng> & it) const //
0097                 -> CPP_ret(void)(
0098                     requires bidirectional_range<CRng>)
0099             {
0100                 auto const first = ranges::begin(rng_->base());
0101                 auto & pred = rng_->adjacent_filter_view::box::get();
0102                 RANGES_EXPECT(it != first);
0103                 --it;
0104                 while(it != first)
0105                 {
0106                     auto tmp = it;
0107                     if(invoke(pred, *--tmp, *it))
0108                         break;
0109                     it = tmp;
0110                 }
0111             }
0112             void distance_to() = delete;
0113         };
0114         constexpr adaptor<false> begin_adaptor() noexcept
0115         {
0116             return {this};
0117         }
0118         CPP_member
0119         constexpr auto begin_adaptor() const noexcept //
0120             -> CPP_ret(adaptor<true>)(
0121                 requires detail::adjacent_filter_constraints<Rng const, Pred const>)
0122         {
0123             return {this};
0124         }
0125         constexpr adaptor<false> end_adaptor() noexcept
0126         {
0127             return {this};
0128         }
0129         CPP_member
0130         constexpr auto end_adaptor() const noexcept //
0131             -> CPP_ret(adaptor<true>)(
0132                 requires detail::adjacent_filter_constraints<Rng const, Pred const>)
0133         {
0134             return {this};
0135         }
0136 
0137     public:
0138         adjacent_filter_view() = default;
0139         constexpr adjacent_filter_view(Rng rng, Pred pred)
0140           : adjacent_filter_view::view_adaptor{detail::move(rng)}
0141           , adjacent_filter_view::box(detail::move(pred))
0142         {}
0143     };
0144 
0145 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0146     template(typename Rng, typename Fun)(
0147         requires copy_constructible<Rng>)
0148         adjacent_filter_view(Rng &&, Fun)
0149             ->adjacent_filter_view<views::all_t<Rng>, Fun>;
0150 #endif
0151 
0152     namespace views
0153     {
0154         struct adjacent_filter_base_fn
0155         {
0156             template(typename Rng, typename Pred)(
0157                 requires detail::adjacent_filter_constraints<Rng, Pred>)
0158             constexpr adjacent_filter_view<all_t<Rng>, Pred> //
0159             operator()(Rng && rng, Pred pred) const
0160             {
0161                 return {all(static_cast<Rng &&>(rng)), std::move(pred)};
0162             }
0163         };
0164 
0165         struct adjacent_filter_fn : adjacent_filter_base_fn
0166         {
0167             using adjacent_filter_base_fn::operator();
0168 
0169             template<typename Pred>
0170             constexpr auto operator()(Pred pred) const
0171             {
0172                 return make_view_closure(
0173                     bind_back(adjacent_filter_base_fn{}, std::move(pred)));
0174             }
0175         };
0176 
0177         /// \relates adjacent_filter_fn
0178         /// \ingroup group-views
0179         RANGES_INLINE_VARIABLE(adjacent_filter_fn, adjacent_filter)
0180     } // namespace views
0181     /// @}
0182 } // namespace ranges
0183 
0184 #include <range/v3/detail/epilogue.hpp>
0185 
0186 #include <range/v3/detail/satisfy_boost_range.hpp>
0187 RANGES_SATISFY_BOOST_RANGE(::ranges::adjacent_filter_view)
0188 
0189 #endif