Horizon
Loading...
Searching...
No Matches
drop.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2013-present
5//
6// Use, modification and distribution is subject to the
7// Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11// Project home: https://github.com/ericniebler/range-v3
12//
13
14#ifndef RANGES_V3_VIEW_DROP_HPP
15#define RANGES_V3_VIEW_DROP_HPP
16
17#include <type_traits>
18
19#include <meta/meta.hpp>
20
22
31#include <range/v3/utility/static_const.hpp>
32#include <range/v3/view/all.hpp>
36
37#include <range/v3/detail/prologue.hpp>
38
39namespace ranges
40{
43 template<typename Rng>
44 struct RANGES_EMPTY_BASES drop_view
45 : view_interface<drop_view<Rng>,
46 is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
47 , private detail::non_propagating_cache<iterator_t<Rng>, drop_view<Rng>,
48 !random_access_range<Rng>>
49 {
50 private:
51 using difference_type_ = range_difference_t<Rng>;
52 Rng rng_;
53 difference_type_ n_;
54
55 template(bool Const = true)(
56 requires Const AND range<meta::const_if_c<Const, Rng>>)
58 get_begin_(std::true_type, std::true_type) const
59 {
60 CPP_assert(random_access_range<meta::const_if_c<Const, Rng>>);
61 return next(ranges::begin(rng_), n_, ranges::end(rng_));
62 }
63 iterator_t<Rng> get_begin_(std::true_type, std::false_type)
64 {
65 CPP_assert(random_access_range<Rng>);
66 return next(ranges::begin(rng_), n_, ranges::end(rng_));
67 }
68 iterator_t<Rng> get_begin_(std::false_type, detail::ignore_t)
69 {
70 CPP_assert(!random_access_range<Rng>);
71 using cache_t =
72 detail::non_propagating_cache<iterator_t<Rng>, drop_view<Rng>>;
73 auto & begin_ = static_cast<cache_t &>(*this);
74 if(!begin_)
75 begin_ = next(ranges::begin(rng_), n_, ranges::end(rng_));
76 return *begin_;
77 }
78
79 public:
80 drop_view() = default;
81 drop_view(Rng rng, difference_type_ n)
82 : rng_(std::move(rng))
83 , n_(n)
84 {
85 RANGES_EXPECT(n >= 0);
86 }
87 iterator_t<Rng> begin()
88 {
89 return this->get_begin_(meta::bool_<random_access_range<Rng>>{},
90 std::false_type{});
91 }
92 sentinel_t<Rng> end()
93 {
94 return ranges::end(rng_);
95 }
96 template(bool Const = true)(
97 requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
99 {
100 return this->get_begin_(std::true_type{}, std::true_type{});
101 }
102 template(bool Const = true)(
103 requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
104 sentinel_t<meta::const_if_c<Const, Rng>> end() const
105 {
106 return ranges::end(rng_);
107 }
108 CPP_auto_member
109 auto CPP_fun(size)()(const //
110 requires sized_range<Rng const>)
111 {
112 auto const s = ranges::size(rng_);
113 auto const n = static_cast<range_size_t<Rng const>>(n_);
114 return s < n ? 0 : s - n;
115 }
116 CPP_auto_member
117 auto CPP_fun(size)()(
118 requires sized_range<Rng>)
119 {
120 auto const s = ranges::size(rng_);
121 auto const n = static_cast<range_size_t<Rng>>(n_);
122 return s < n ? 0 : s - n;
123 }
124 Rng base() const
125 {
126 return rng_;
127 }
128 };
129
130 template<typename Rng>
131 RANGES_INLINE_VAR constexpr bool enable_borrowed_range<drop_view<Rng>> = //
132 enable_borrowed_range<Rng>;
133
134#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
135 template<typename Rng>
136 drop_view(Rng &&, range_difference_t<Rng>)
138#endif
139
140 namespace views
141 {
143 {
144 private:
145 template<typename Rng>
146 static auto impl_(Rng && rng, range_difference_t<Rng> n, input_range_tag)
148 {
149 return {all(static_cast<Rng &&>(rng)), n};
150 }
151 template(typename Rng)(
153 static subrange<iterator_t<Rng>, sentinel_t<Rng>> //
154 impl_(Rng && rng, range_difference_t<Rng> n, random_access_range_tag)
155 {
156 return {begin(rng) + ranges::min(n, distance(rng)), end(rng)};
157 }
158
159 public:
160 template(typename Rng)(
162 auto operator()(Rng && rng, range_difference_t<Rng> n) const
163 {
164 return drop_base_fn::impl_(
165 static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
166 }
167 };
168
170 {
171 using drop_base_fn::operator();
172
173 template(typename Int)(
174 requires detail::integer_like_<Int>)
175 constexpr auto operator()(Int n) const
176 {
177 return make_view_closure(bind_back(drop_base_fn{}, n));
178 }
179 };
180
183 RANGES_INLINE_VARIABLE(drop_fn, drop)
184 } // namespace views
185
186 namespace cpp20
187 {
188 namespace views
189 {
190 using ranges::views::drop;
191 }
192 template(typename Rng)(
193 requires view_<Rng>)
194 using drop_view = ranges::drop_view<Rng>;
195 } // namespace cpp20
197} // namespace ranges
198
199#include <range/v3/detail/epilogue.hpp>
200#include <range/v3/detail/satisfy_boost_range.hpp>
201RANGES_SATISFY_BOOST_RANGE(::ranges::drop_view)
202
203#endif
The borrowed_range concept.
The input_range concept.
The random_access_range concept.
The range concept.
The sized_range concept.
The viewable_range concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
Tiny meta-programming library.
Definition drop.hpp:49
Definition concepts.hpp:271
Definition concepts.hpp:277
Definition subrange.hpp:196
Definition interface.hpp:129
Definition drop.hpp:143
Definition drop.hpp:170