Horizon
Loading...
Searching...
No Matches
take_exactly.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_TAKE_EXACTLY_HPP
15#define RANGES_V3_VIEW_TAKE_EXACTLY_HPP
16
17#include <type_traits>
18
20
28#include <range/v3/utility/static_const.hpp>
29#include <range/v3/view/all.hpp>
34
35#include <range/v3/detail/prologue.hpp>
36
37namespace ranges
38{
40 namespace detail
41 {
42 template<typename Rng>
43 struct is_random_access_common_
44 : meta::bool_<(bool)random_access_range<Rng> && (bool)common_range<Rng>>
45 {};
46
47 // BUGBUG Per the discussion in https://github.com/ericniebler/stl2/issues/63,
48 // it's unclear if we can infer anything from random_access_range<Rng> &&
49 // common_range<Rng>
50 template<typename Rng,
51 bool IsRandomAccessCommon /*= is_random_access_common_<Rng>::value*/>
52 struct take_exactly_view_
53 : view_interface<take_exactly_view_<Rng, IsRandomAccessCommon>, finite>
54 {
55 private:
56 Rng rng_;
57 range_difference_t<Rng> n_;
58
59 public:
60 take_exactly_view_() = default;
61 take_exactly_view_(Rng rng, range_difference_t<Rng> n)
62 : rng_(std::move(rng))
63 , n_(n)
64 {
65 RANGES_EXPECT(n >= 0);
66 }
67 counted_iterator<iterator_t<Rng>> begin()
68 {
69 return {ranges::begin(rng_), n_};
70 }
71 template(typename BaseRng = Rng)(
72 requires range<BaseRng const>)
73 counted_iterator<iterator_t<BaseRng const>> begin() const
74 {
75 return {ranges::begin(rng_), n_};
76 }
77 default_sentinel_t end() const
78 {
79 return {};
80 }
81 auto size() const
82 {
83 return static_cast<detail::iter_size_t<iterator_t<Rng>>>(n_);
84 }
85 Rng base() const
86 {
87 return rng_;
88 }
89 };
90
91 template<typename Rng>
92 struct take_exactly_view_<Rng, true>
93 : view_interface<take_exactly_view_<Rng, true>, finite>
94 {
95 private:
96 Rng rng_;
97 range_difference_t<Rng> n_;
98
99 public:
100 take_exactly_view_() = default;
101 take_exactly_view_(Rng rng, range_difference_t<Rng> n)
102 : rng_(std::move(rng))
103 , n_(n)
104 {
105 RANGES_EXPECT(n >= 0);
106 RANGES_EXPECT(!(bool)sized_range<Rng> || n <= ranges::distance(rng_));
107 }
108 iterator_t<Rng> begin()
109 {
110 return ranges::begin(rng_);
111 }
112 iterator_t<Rng> end()
113 {
114 return ranges::begin(rng_) + n_;
115 }
116 CPP_auto_member
117 auto CPP_fun(begin)()(const //
118 requires range<Rng const>)
119 {
120 return ranges::begin(rng_);
121 }
122 CPP_auto_member
123 auto CPP_fun(end)()(const //
124 requires range<Rng const>)
125 {
126 return ranges::begin(rng_) + n_;
127 }
128 detail::iter_size_t<iterator_t<Rng>> size() const
129 {
130 return static_cast<detail::iter_size_t<iterator_t<Rng>>>(n_);
131 }
132 Rng base() const
133 {
134 return rng_;
135 }
136 };
137 } // namespace detail
139
142 template<typename Rng>
143 using take_exactly_view = detail::take_exactly_view_<Rng>;
144
145 template<typename Rng, bool B>
146 RANGES_INLINE_VAR constexpr bool //
147 enable_borrowed_range<detail::take_exactly_view_<Rng, B>> = //
148 enable_borrowed_range<Rng>;
149
150 namespace views
151 {
153 {
154 private:
155 template<typename Rng>
156 static constexpr take_exactly_view<all_t<Rng>> impl_(
157 Rng && rng, range_difference_t<Rng> n, input_range_tag)
158 {
159 return {all(static_cast<Rng &&>(rng)), n};
160 }
161 template(typename Rng)(
162 requires borrowed_range<Rng>)
163 static constexpr subrange<iterator_t<Rng>> impl_(Rng && rng,
164 range_difference_t<Rng> n,
166 {
167 return {begin(rng), next(begin(rng), n)};
168 }
169
170 public:
171 template(typename Rng)(
173 constexpr auto operator()(Rng && rng, range_difference_t<Rng> n) const
174 {
175 return take_exactly_base_fn::impl_(
176 static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
177 }
178 };
179
181 {
182 using take_exactly_base_fn::operator();
183
184 template(typename Int)(
185 requires detail::integer_like_<Int>)
186 constexpr auto operator()(Int n) const
187 {
188 return make_view_closure(bind_back(take_exactly_base_fn{}, n));
189 }
190 };
191
194 RANGES_INLINE_VARIABLE(take_exactly_fn, take_exactly)
195 } // namespace views
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::detail::take_exactly_view_)
202
203#endif
The borrowed_range concept.
The input_range concept.
The viewable_range concept.
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
meta::size_t< L::size()> size
An integral constant wrapper that is the size of the meta::list L.
Definition meta.hpp:1696
Definition concepts.hpp:271
Definition concepts.hpp:277
Definition subrange.hpp:196
Definition take_exactly.hpp:153
Definition take_exactly.hpp:181