Horizon
drop_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_DROP_EXACTLY_HPP
15 #define RANGES_V3_VIEW_DROP_EXACTLY_HPP
16 
17 #include <type_traits>
18 
19 #include <meta/meta.hpp>
20 
21 #include <range/v3/range_fwd.hpp>
22 
28 #include <range/v3/utility/box.hpp>
30 #include <range/v3/utility/static_const.hpp>
31 #include <range/v3/view/all.hpp>
34 #include <range/v3/view/view.hpp>
35 
36 #include <range/v3/detail/prologue.hpp>
37 
38 namespace ranges
39 {
42  template<typename Rng>
43  struct RANGES_EMPTY_BASES drop_exactly_view
44  : view_interface<drop_exactly_view<Rng>,
45  is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
46  , private detail::non_propagating_cache<iterator_t<Rng>, drop_exactly_view<Rng>,
47  !random_access_range<Rng>>
48  {
49  private:
50  using difference_type_ = range_difference_t<Rng>;
51  Rng rng_;
52  difference_type_ n_;
53 
54  // random_access_range == true
55  template(bool Const = true)(
56  requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
57  iterator_t<meta::const_if_c<Const, Rng>> get_begin_(std::true_type) const
58  {
59  return next(ranges::begin(rng_), n_);
60  }
61  iterator_t<Rng> get_begin_(std::true_type)
62  {
63  return next(ranges::begin(rng_), n_);
64  }
65  // random_access_range == false
66  iterator_t<Rng> get_begin_(std::false_type)
67  {
68  using cache_t =
69  detail::non_propagating_cache<iterator_t<Rng>, drop_exactly_view<Rng>>;
70  auto & begin_ = static_cast<cache_t &>(*this);
71  if(!begin_)
72  begin_ = next(ranges::begin(rng_), n_);
73  return *begin_;
74  }
75 
76  public:
77  drop_exactly_view() = default;
78  drop_exactly_view(Rng rng, difference_type_ n)
79  : rng_(std::move(rng))
80  , n_(n)
81  {
82  RANGES_EXPECT(n >= 0);
83  }
84  iterator_t<Rng> begin()
85  {
86  return this->get_begin_(meta::bool_<random_access_range<Rng>>{});
87  }
88  sentinel_t<Rng> end()
89  {
90  return ranges::end(rng_);
91  }
92  template(bool Const = true)(
93  requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
95  {
96  return this->get_begin_(std::true_type{});
97  }
98  template(bool Const = true)(
99  requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
100  sentinel_t<meta::const_if_c<Const, Rng>> end() const
101  {
102  return ranges::end(rng_);
103  }
104  CPP_auto_member
105  auto CPP_fun(size)()(const
106  requires sized_range<Rng const>)
107  {
108  return ranges::size(rng_) - static_cast<range_size_t<Rng const>>(n_);
109  }
110  CPP_auto_member
111  auto CPP_fun(size)()(
112  requires sized_range<Rng>)
113  {
114  return ranges::size(rng_) - static_cast<range_size_t<Rng>>(n_);
115  }
116  Rng base() const
117  {
118  return rng_;
119  }
120  };
121 
122  template<typename Rng>
123  RANGES_INLINE_VAR constexpr bool enable_borrowed_range<drop_exactly_view<Rng>> = //
124  enable_borrowed_range<Rng>;
125 
126 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
127  template<typename Rng>
128  drop_exactly_view(Rng &&, range_difference_t<Rng>)
129  ->drop_exactly_view<views::all_t<Rng>>;
130 #endif
131 
132  namespace views
133  {
135  {
136  private:
137  template<typename Rng>
138  static auto impl_(Rng && rng, range_difference_t<Rng> n, input_range_tag)
140  {
141  return {all(static_cast<Rng &&>(rng)), n};
142  }
143  template(typename Rng)(
144  requires borrowed_range<Rng>)
145  static subrange<iterator_t<Rng>, sentinel_t<Rng>> //
146  impl_(Rng && rng, range_difference_t<Rng> n, random_access_range_tag)
147  {
148  return {begin(rng) + n, end(rng)};
149  }
150 
151  public:
152  template(typename Rng)(
153  requires viewable_range<Rng> AND input_range<Rng>)
154  auto operator()(Rng && rng, range_difference_t<Rng> n) const
155  {
156  return drop_exactly_base_fn::impl_(
157  static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
158  }
159  };
160 
162  {
163  using drop_exactly_base_fn::operator();
164 
165  template(typename Int)(
166  requires detail::integer_like_<Int>)
167  constexpr auto operator()(Int n) const
168  {
169  return make_view_closure(bind_back(drop_exactly_base_fn{}, n));
170  }
171  };
172 
176  } // namespace views
178 } // namespace ranges
179 
180 #include <range/v3/detail/epilogue.hpp>
181 #include <range/v3/detail/satisfy_boost_range.hpp>
182 RANGES_SATISFY_BOOST_RANGE(::ranges::drop_exactly_view)
183 
184 #endif
CPP_concept random_access_range
\concept random_access_range
Definition: concepts.hpp:140
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
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
Tiny meta-programming library.
Definition: drop_exactly.hpp:48
Definition: concepts.hpp:271
Definition: concepts.hpp:277
Definition: subrange.hpp:196
Definition: interface.hpp:129
Definition: drop_exactly.hpp:135
Definition: drop_exactly.hpp:162