VCCC  2024.05
VisualCamp Common C++ library
begin.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2023/12/24.
3 //
4 
5 #ifndef VCCC_RANGES_BEGIN_HPP_
6 #define VCCC_RANGES_BEGIN_HPP_
7 
8 #include <cstddef>
9 #include <type_traits>
10 
20 
21 namespace vccc {
22 namespace ranges {
23 namespace detail {
24 
25 using vccc::detail::return_category;
26 
27 template<typename T, bool = std::is_array<remove_cvref_t<T>>::value>
28 struct begin_array_check : std::false_type {
29  using category = return_category<0>;
30 };
31 template<typename T>
32 struct begin_array_check<T, true> : std::true_type {
33  using category = return_category<1, decltype(std::declval<T>() + 0)>;
34 };
35 
36 template<typename T, typename = void>
37 struct begin_member_check : std::false_type {
38  using category = return_category<0>;
39 };
40 template<typename T>
41 struct begin_member_check<T, void_t<decltype(vccc_decay_copy(std::declval<T>().begin()))>>
42  : input_or_output_iterator<decltype(vccc_decay_copy(std::declval<T>().begin()))> {
43  using category = return_category<2, decltype(vccc_decay_copy(std::declval<T>().begin()))>;
44 };
45 
46 template<typename T, typename = void>
47 struct begin_global_check : std::false_type {
48  using category = return_category<0>;
49 };
50 template<typename T>
51 struct begin_global_check<T, void_t<decltype(vccc_decay_copy(begin(std::declval<T>())))>>
52  : input_or_output_iterator<decltype(vccc_decay_copy(begin(std::declval<T>())))> {
53  using category = return_category<3, decltype(vccc_decay_copy(begin(std::declval<T>())))>;
54 };
55 
57 struct begin_category_impl_2 : begin_global_check<T> {};
58 template<typename T>
59 struct begin_category_impl_2<T, true> : begin_member_check<T> {};
60 
62 struct begin_category_impl : begin_category_impl_2<T> {};
63 template<typename T>
64 struct begin_category_impl<T, true> : begin_array_check<T> {};
65 
66 template<typename T>
67 struct begin_category
68  : std::conditional_t<
69  disjunction<
70  std::is_lvalue_reference<T>,
71  enable_borrowed_range<remove_cvref_t<T>>
72  >::value,
73  typename begin_category_impl<T>::category,
74  return_category<0>
75  > {};
76 
77 template<typename T, typename R>
78 constexpr R ranges_begin(T&& t, return_category<1, R>) {
79  static_assert(is_complete<std::remove_all_extents_t<std::remove_reference_t<T>>>::value, "Array element must be complete type");
80  return t + 0;
81 }
82 
83 template<typename T, typename R>
84 constexpr R ranges_begin(T&& t, return_category<2, R>) {
85  return vccc_decay_copy(t.begin());
86 }
87 
88 template<typename T, typename R>
89 constexpr R ranges_begin(T&& t, return_category<3, R>) {
90  return vccc_decay_copy(begin(t));
91 }
92 
93 struct begin_niebloid {
94  template<typename T>
95  constexpr typename begin_category<T&&>::return_type
96  operator()(T&& t) const {
97  return ranges_begin(std::forward<T>(t), detail::begin_category<T&&>{});
98  }
99 };
100 
101 } // namespace detail
102 
103 namespace niebloid {
104 
107 
116 VCCC_INLINE_OR_STATIC constexpr detail::begin_niebloid begin{};
118 
119 } // namespace niebloid
120 using namespace niebloid;
121 
122 } // namespace ranges
123 } // namespace vccc
124 
125 #endif // VCCC_RANGES_BEGIN_HPP_
#define vccc_decay_copy(x)
Definition: decay_copy.hpp:12
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
void void_t
Definition: void_t.hpp:19
decltype(detail::is_complete_impl(std::declval< T * >())) is_complete
Definition: is_complete.hpp:23
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35