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 Hui Xie 2021
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_CHUNK_BY_HPP
0015 #define RANGES_V3_VIEW_CHUNK_BY_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/algorithm/adjacent_find.hpp>
0025 #include <range/v3/functional/bind_back.hpp>
0026 #include <range/v3/functional/not_fn.hpp>
0027 #include <range/v3/iterator/default_sentinel.hpp>
0028 #include <range/v3/range/access.hpp>
0029 #include <range/v3/range/concepts.hpp>
0030 #include <range/v3/range/traits.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/all.hpp>
0035 #include <range/v3/view/facade.hpp>
0036 #include <range/v3/view/subrange.hpp>
0037 #include <range/v3/view/view.hpp>
0038 
0039 #include <range/v3/detail/prologue.hpp>
0040 
0041 namespace ranges
0042 {
0043 
0044     /// \addtogroup group-views
0045     /// @{
0046     template<typename Rng, typename Fun>
0047     struct chunk_by_view
0048       : view_facade<chunk_by_view<Rng, Fun>,
0049                     is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
0050     {
0051     private:
0052         friend range_access;
0053         Rng rng_;
0054         // cached version of the end of the first subrange / start of the second subrange
0055         detail::non_propagating_cache<iterator_t<Rng>> second_;
0056         semiregular_box_t<Fun> fun_;
0057 
0058         struct cursor
0059         {
0060         private:
0061             friend range_access;
0062             friend chunk_by_view;
0063             iterator_t<Rng> cur_;
0064             iterator_t<Rng> next_cur_;
0065             sentinel_t<Rng> last_;
0066             semiregular_box_ref_or_val_t<Fun, false> fun_;
0067 
0068 #ifdef _MSC_VER
0069             template<typename I = iterator_t<Rng>>
0070             subrange<I> read() const
0071             {
0072                 return {cur_, next_cur_};
0073             }
0074 #else
0075             subrange<iterator_t<Rng>> read() const
0076             {
0077                 return {cur_, next_cur_};
0078             }
0079 #endif
0080             void next()
0081             {
0082                 cur_ = next_cur_;
0083                 auto partition_cur = adjacent_find(cur_, last_, not_fn(fun_));
0084                 next_cur_ =
0085                     partition_cur != last_ ? ranges::next(partition_cur) : partition_cur;
0086             }
0087 
0088             bool equal(default_sentinel_t) const
0089             {
0090                 return cur_ == last_;
0091             }
0092             bool equal(cursor const & that) const
0093             {
0094                 return cur_ == that.cur_;
0095             }
0096             cursor(semiregular_box_ref_or_val_t<Fun, false> fun, iterator_t<Rng> first,
0097                    iterator_t<Rng> next_cur, sentinel_t<Rng> last)
0098               : cur_(first)
0099               , next_cur_(next_cur)
0100               , last_(last)
0101               , fun_(fun)
0102             {}
0103 
0104         public:
0105             cursor() = default;
0106         };
0107         cursor begin_cursor()
0108         {
0109             auto first = ranges::begin(rng_);
0110             auto last = ranges::end(rng_);
0111             if(!second_)
0112             {
0113                 auto partition_cur = adjacent_find(first, last, not_fn(fun_));
0114                 second_ =
0115                     partition_cur != last ? ranges::next(partition_cur) : partition_cur;
0116             }
0117             return {fun_, first, *second_, last};
0118         }
0119 
0120     public:
0121         chunk_by_view() = default;
0122         constexpr chunk_by_view(Rng rng, Fun fun)
0123           : rng_(std::move(rng))
0124           , fun_(std::move(fun))
0125         {}
0126     };
0127 
0128 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0129     template(typename Rng, typename Fun)(
0130         requires copy_constructible<Fun>) chunk_by_view(Rng &&, Fun)
0131         ->chunk_by_view<views::all_t<Rng>, Fun>;
0132 #endif
0133 
0134     namespace views
0135     {
0136         struct chunk_by_base_fn
0137         {
0138             template(typename Rng, typename Fun)(
0139                 requires viewable_range<Rng> AND forward_range<Rng> AND //
0140                     indirect_relation<Fun, iterator_t<Rng>>)            //
0141             constexpr chunk_by_view<all_t<Rng>, Fun>
0142             operator()(Rng && rng, Fun fun) const
0143             {
0144                 return {all(static_cast<Rng &&>(rng)), std::move(fun)};
0145             }
0146         };
0147 
0148         struct chunk_by_fn : chunk_by_base_fn
0149         {
0150             using chunk_by_base_fn::operator();
0151 
0152             template<typename Fun>
0153             constexpr auto operator()(Fun fun) const
0154             {
0155                 return make_view_closure(bind_back(chunk_by_base_fn{}, std::move(fun)));
0156             }
0157         };
0158 
0159         /// \relates chunk_by_fn
0160         /// \ingroup group-views
0161         RANGES_INLINE_VARIABLE(chunk_by_fn, chunk_by)
0162     } // namespace views
0163     /// @}
0164 } // namespace ranges
0165 
0166 #include <range/v3/detail/epilogue.hpp>
0167 #include <range/v3/detail/satisfy_boost_range.hpp>
0168 RANGES_SATISFY_BOOST_RANGE(::ranges::chunk_by_view)
0169 
0170 #endif