Horizon
take_exactly.hpp
Go to the documentation of this file.
1 // 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 
19 #include <range/v3/range_fwd.hpp>
20 
28 #include <range/v3/utility/static_const.hpp>
29 #include <range/v3/view/all.hpp>
33 #include <range/v3/view/view.hpp>
34 
35 #include <range/v3/detail/prologue.hpp>
36 
37 namespace 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)(
172  requires viewable_range<Rng> AND input_range<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 
195  } // namespace views
197 } // namespace ranges
198 
199 #include <range/v3/detail/epilogue.hpp>
200 #include <range/v3/detail/satisfy_boost_range.hpp>
201 RANGES_SATISFY_BOOST_RANGE(::ranges::detail::take_exactly_view_)
202 
203 #endif
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition: meta.hpp:168
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:994
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