VCCC  2024.05
VisualCamp Common C++ library
drop.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2024/01/29.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_DROP_HPP
6 #define VCCC_RANGES_VIEWS_DROP_HPP
7 
8 #include <algorithm>
9 #include <cstddef>
10 #include <type_traits>
11 
14 #include "vccc/__ranges/range.hpp"
24 #include "vccc/span.hpp"
25 #include "vccc/string_view.hpp"
29 
30 namespace vccc {
31 namespace ranges {
32 namespace views {
33 namespace detail {
34 
35 using vccc::detail::return_category;
36 
37 struct drop_niebloid {
38  private:
39  // empty_view - 1
41  struct return_category_empty_view : std::true_type {
42  using category = return_category<1, decltype(vccc_decay_copy(std::declval<R>()))>;
43  };
44  template<typename R, typename T, typename D>
45  struct return_category_empty_view<R, T, D, false> : std::false_type {
46  using category = return_category<0>;
47  };
48  template<typename R, typename D, typename RT>
49  constexpr RT operator()(R&& r, D, return_category<1, RT>) const {
50  return std::forward<R>(r);
51  }
52 
53  // subrange - 2 / 3
54  template<typename T, bool = conjunction<ranges::detail::is_subrange<T>, random_access_range<T>, sized_range<T>>::value /* true */>
55  struct return_category_subrange : std::true_type {
57  return_category<2, subrange<iterator_t<T>, sentinel_t<T>, subrange_kind::sized> >,
58  return_category<3, subrange<iterator_t<T>, sentinel_t<T>> >
59  >;
60  };
61  template<typename T>
62  struct return_category_subrange<T, false> : std::false_type {
63  using category = return_category<0>;
64  };
65 
66  template<typename R, typename D, typename U>
67  constexpr U operator()(R&& e, D f, return_category<2, U>) const {
68  auto inc = (std::min<D>)(ranges::distance(e), f);
69  return U(
70  ranges::begin(e) + inc,
71  ranges::end(e),
72  static_cast<std::make_unsigned_t<decltype(inc)>>(ranges::distance(e) - inc)
73  );
74  }
75 
76  // span - 3
77  template<typename T>
78  struct is_span : std::false_type {};
79  template<typename T, std::size_t Extent>
80  struct is_span<span<T, Extent>> : std::true_type {};
81 
83  struct return_category_span : std::true_type {
84  using category = return_category<3, span<typename T::element_type>>;
85  };
86  template<typename T, typename D>
87  struct return_category_span<T, D, false> : std::false_type {
88  using category = return_category<0>;
89  };
90 
91  // basic_string_view - 3
93  struct return_category_string_view : std::true_type {
94  using category = return_category<3, T>;
95  };
96  template<typename T>
97  struct return_category_string_view<T, false> : std::false_type {
98  using category = return_category<0>;
99  };
100 
101  // iota_view - 3
103  struct return_category_iota_view : std::true_type {
104  using category = return_category<3, T>;
105  };
106  template<typename T>
107  struct return_category_iota_view<T, false> : std::false_type {
108  using category = return_category<0>;
109  };
110 
111  template<typename R, typename D, typename U>
112  constexpr U operator()(R&& e, D f, return_category<3, U>) const {
113  return U(
114  ranges::begin(e) + (std::min<D>)(ranges::distance(e), f),
115  ranges::end(e)
116  );
117  }
118 
119  // repeat_view - 4
120  template<typename T>
121  struct return_category_repeat_view : is_specialization<T, repeat_view> {
122  using category = return_category<(is_specialization<T, repeat_view>::value ? 4 : 0)>;
123  };
124  template<typename R, typename D>
125  constexpr auto operator()(R&& e, D f, return_category<4>, std::true_type /* sized_range */) const {
126  return views::repeat(*e, ranges::distance(e) - (std::min<D>)(ranges::distance(e), f));
127  }
128  template<typename R, typename D>
129  constexpr auto operator()(R&& e, D, return_category<4>, std::false_type /* sized_range */) const {
130  return vccc_decay_copy(e);
131  }
132  template<typename R, typename D>
133  constexpr auto operator()(R&& e, D f, return_category<4>) const {
134  return (*this)(std::forward<R>(e), f, sized_range<remove_cvref_t<R>>{});
135  }
136 
137  template<typename R, typename D>
138  constexpr drop_view<all_t<R>> operator()(R&& r, D f, return_category<0>) const {
139  return drop_view<all_t<R>>(std::forward<R>(r), f);
140  }
141 
142  template<typename R, typename T, typename D>
143  using category =
144  std::conditional_t<
145  return_category_empty_view<R, T, D>::value, typename return_category_empty_view<R, T, D>::category, // 1
146  std::conditional_t<
147  return_category_span<T, D>::value, typename return_category_span<T, D>::category, // 3
148  std::conditional_t<
149  return_category_string_view<T>::value, typename return_category_string_view<T>::category, // 3
150  std::conditional_t<
151  return_category_subrange<T>::value, typename return_category_subrange<T>::category, // 2 or 3
152  std::conditional_t<
153  return_category_iota_view<T>::value, typename return_category_iota_view<T>::category, // 3
154  std::conditional_t<
155  return_category_repeat_view<T>::value, typename return_category_iota_view<T>::category, // 4
156  return_category<0>
157  >>>>>>;
158 
159  public:
161  constexpr auto
163  using T = remove_cvref_t<decltype((r))>;
164  using D = range_difference_t<decltype((r))>;
165  return (*this)(std::forward<R>(r), count, category<R&&, T, D>{});
166  }
167 
168  template<typename DifferenceType>
169  constexpr auto operator()(DifferenceType&& count) const {
171  }
172 };
173 
174 } // namespace detail
175 
178 
180 
182 
183 } // namespace views
184 } // namespace ranges
185 } // namespace vccc
186 
187 #endif // VCCC_RANGES_VIEWS_DROP_HPP
Definition: drop_view.hpp:66
Definition: range_adaptor.hpp:25
a non-owning view over a contiguous sequence of objects
Definition: span.hpp:118
#define vccc_decay_copy(x)
Definition: decay_copy.hpp:12
constexpr VCCC_INLINE_OR_STATIC detail::count_niebloid count
Definition: count.hpp:58
constexpr T e
the mathematical constant
Definition: constants.hpp:37
typename sentinel< R >::type sentinel_t
Definition: sentinel_t.hpp:29
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
constexpr VCCC_INLINE_OR_STATIC detail::repeat_niebloid repeat
Definition: repeat.hpp:56
constexpr VCCC_INLINE_OR_STATIC detail::distance_niebloid distance
Definition: distance.hpp:72
constexpr VCCC_INLINE_OR_STATIC detail::drop_niebloid drop
Definition: drop.hpp:179
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
typename range_difference< R >::type range_difference_t
Used to obtain the difference type of the iterator type of range type R.
Definition: range_difference_t.hpp:41
typename remove_cvref< T >::type remove_cvref_t
Definition: remove_cvref.hpp:24
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: is_specialization.hpp:30
specifies that a range knows its size in constant time
Definition: sized_range.hpp:38
constexpr auto operator()(DifferenceType &&count) const
Definition: drop.hpp:169
constexpr auto operator()(R &&r, range_difference_t< R > count) const
Definition: drop.hpp:162