VCCC  2024.05
VisualCamp Common C++ library
take.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2024/01/03.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_TAKE_HPP
6 #define VCCC_RANGES_VIEWS_TAKE_HPP
7 
8 #include <algorithm>
9 #include <cstddef>
10 #include <type_traits>
11 
14 #include "vccc/__ranges/begin.hpp"
15 #include "vccc/__ranges/end.hpp"
17 #include "vccc/__ranges/range.hpp"
27 #include "vccc/span.hpp"
28 #include "vccc/string_view.hpp"
34 
35 namespace vccc {
36 namespace ranges {
37 namespace views {
38 namespace detail {
39 
40 using vccc::detail::return_category;
41 
42 struct take_niebloid {
43  private:
45  struct return_category_empty_view : std::true_type {
46  using category = return_category<1, decltype(vccc_decay_copy(std::declval<R>()))>;
47  };
48  template<typename R, typename T, typename D>
49  struct return_category_empty_view<R, T, D, false> : std::false_type {
50  using category = return_category<0>;
51  };
52  template<typename R, typename RT>
53  constexpr RT operator()(R&& r, range_difference_t<R> count, return_category<1, RT>) const {
54  return ((void)count, vccc_decay_copy(std::forward<R>(r)));
55  }
56 
57  template<typename T>
58  struct is_span : std::false_type {};
59  template<typename T, std::size_t Extent>
60  struct is_span<span<T, Extent>> : std::true_type {};
61 
63  struct return_category_span : std::true_type {
64  using category = return_category<2, span<typename T::element_type>>;
65  };
66  template<typename T, typename D>
67  struct return_category_span<T, D, false> : std::false_type {
68  using category = return_category<0>;
69  };
70 
72  struct return_category_string_view : std::true_type {
73  using category = return_category<2, T>;
74  };
75  template<typename T>
76  struct return_category_string_view<T, false> : std::false_type {
77  using category = return_category<0>;
78  };
79 
81  struct return_category_subrange : std::true_type {
82  using category = return_category<2, subrange<iterator_t<T>>>;
83  };
84  template<typename T>
85  struct return_category_subrange<T, false> : std::false_type {
86  using category = return_category<0>;
87  };
88 
89  template<typename R, typename U>
90  constexpr U operator()(R&& e, range_difference_t<R> f, return_category<2, U>) const {
91  using D = range_difference_t<decltype((e))>;
92  return U(
94  ranges::begin(e) + (std::min<D>)(ranges::distance(e), f)
95  );
96  }
97 
98  template<typename T, bool = conjunction<is_specialization<T, iota_view>, random_access_range<T>, sized_range<T>>::value /* true */>
99  struct return_category_iota_view : std::true_type {
100  using category = return_category<3, T>;
101  };
102  template<typename T>
103  struct return_category_iota_view<T, false> : std::false_type {
104  using category = return_category<0>;
105  };
106  template<typename R, typename IV>
107  constexpr IV operator()(R&& e, ranges::range_difference_t<R> f, return_category<3, IV>) const {
108  using D = ranges::range_difference_t<decltype((e))>;
109  return views::iota(
110  *ranges::begin(e),
111  *(ranges::begin(e) + (std::min<D>)(ranges::distance(e), f))
112  );
113  }
114 
116  struct return_category_repeat_view : std::true_type {
118  };
119  template<typename T>
120  struct return_category_repeat_view<T, false> : std::false_type {
121  using category = return_category<0>;
122  };
123  template<typename R>
124  constexpr auto operator()(R&& e, ranges::range_difference_t<R> f, return_category<4, std::true_type /* sized_range */>) const {
125  using D = ranges::range_difference_t<decltype((e))>;
126  return views::repeat(*(e.begin()), (std::min<D>)(ranges::distance(e), f));
127  }
128  template<typename R>
129  constexpr auto operator()(R&& e, ranges::range_difference_t<R> f, return_category<4, std::false_type /* sized_range */>) const {
130  using D = ranges::range_difference_t<decltype((e))>;
131  return views::repeat(*(e.begin()), static_cast<D>(f));
132  }
133 
134  template<typename R, typename TakeView>
135  constexpr TakeView operator()(R&& r, ranges::range_difference_t<R> f, return_category<5, TakeView>) const {
136  return TakeView(std::forward<R>(r), f);
137  }
138 
139  template<typename R, typename T, typename D>
140  using category =
141  std::conditional_t<
142  return_category_empty_view<R, T, D>::value, typename return_category_empty_view<R, T, D>::category, // 1
143  std::conditional_t<
144  return_category_span<T, D>::value, typename return_category_span<T, D>::category, // 2
145  std::conditional_t<
146  return_category_string_view<T>::value, typename return_category_string_view<T>::category, // 2
147  std::conditional_t<
148  return_category_subrange<T>::value, typename return_category_subrange<T>::category, // 2
149  std::conditional_t<
150  return_category_iota_view<T>::value, typename return_category_iota_view<T>::category, // 3
151  std::conditional_t<
152  return_category_repeat_view<T>::value, typename return_category_repeat_view<T>::category, // 4
153  return_category<5, take_view<views::all_t<R>>>> // 5
154  >>>>>;
155 
156 
157  public:
159  constexpr auto
161  using T = remove_cvref_t<decltype((r))>;
162  using D = ranges::range_difference_t<decltype((r))>;
163  static_assert(convertible_to<decltype((count)), D>::value, "Constraints not satisfied");
164  return (*this)(std::forward<R>(r), count, category<R&&, T, D>{});
165  }
166 
167  template<typename DifferenceType>
168  constexpr auto operator()(DifferenceType&& count) const {
170  }
171 };
172 } // namespace detail
173 
176 
178 
180 
181 } // namespace views
182 } // namespace ranges
183 } // namespace vccc
184 
185 #endif // VCCC_RANGES_VIEWS_TAKE_HPP
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
constexpr VCCC_INLINE_OR_STATIC detail::iota_niebloid iota
Definition: iota_view.hpp:539
constexpr VCCC_INLINE_OR_STATIC detail::take_niebloid take
Definition: take.hpp:177
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
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
Models std::convertible_to
Definition: convertible_to.hpp:38
constexpr auto operator()(DifferenceType &&count) const
Definition: take.hpp:168
constexpr auto operator()(R &&r, ranges::range_difference_t< R > count) const
Definition: take.hpp:160