Back to home page

EIC code displayed by LXR

 
 

    


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

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_ACTION_STRIDE_HPP
0015 #define RANGES_V3_ACTION_STRIDE_HPP
0016 
0017 #include <range/v3/range_fwd.hpp>
0018 
0019 #include <range/v3/action/action.hpp>
0020 #include <range/v3/action/erase.hpp>
0021 #include <range/v3/functional/bind_back.hpp>
0022 #include <range/v3/iterator/concepts.hpp>
0023 #include <range/v3/iterator/operations.hpp>
0024 #include <range/v3/iterator/traits.hpp>
0025 #include <range/v3/utility/static_const.hpp>
0026 
0027 #include <range/v3/detail/prologue.hpp>
0028 
0029 namespace ranges
0030 {
0031     /// \addtogroup group-actions
0032     /// @{
0033     namespace actions
0034     {
0035         struct stride_fn
0036         {
0037             template(typename D)(
0038                 requires detail::integer_like_<D>)
0039             constexpr auto operator()(D step) const
0040             {
0041                 return make_action_closure(bind_back(stride_fn{}, step));
0042             }
0043 
0044             template(typename Rng, typename D = range_difference_t<Rng>)(
0045                 requires forward_range<Rng> AND
0046                     erasable_range<Rng &, iterator_t<Rng>, sentinel_t<Rng>> AND
0047                     permutable<iterator_t<Rng>>)
0048             Rng operator()(Rng && rng, range_difference_t<Rng> const step) const
0049             {
0050                 using I = iterator_t<Rng>;
0051                 using S = sentinel_t<Rng>;
0052                 RANGES_EXPECT(0 < step);
0053                 if(1 < step)
0054                 {
0055                     I first = ranges::begin(rng);
0056                     S const last = ranges::end(rng);
0057                     if(first != last)
0058                     {
0059                         for(I i = ranges::next(++first, step - 1, last); i != last;
0060                             advance(i, step, last), ++first)
0061                         {
0062                             *first = iter_move(i);
0063                         }
0064                     }
0065                     ranges::actions::erase(rng, first, last);
0066                 }
0067                 return static_cast<Rng &&>(rng);
0068             }
0069         };
0070 
0071         /// \relates actions::stride_fn
0072         RANGES_INLINE_VARIABLE(stride_fn, stride)
0073     } // namespace actions
0074     /// @}
0075 } // namespace ranges
0076 
0077 #include <range/v3/detail/epilogue.hpp>
0078 
0079 #endif