VCCC  2024.05
VisualCamp Common C++ library
cxx20_iterator_traits.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2023/12/25.
3 //
4 
5 #ifndef VCCC_ITERATOR_ITERATOR_TRAITS_CXX20_ITERATOR_TRAITS_HPP_
6 #define VCCC_ITERATOR_ITERATOR_TRAITS_CXX20_ITERATOR_TRAITS_HPP_
7 
8 #include <cstddef>
9 #include <type_traits>
10 
21 
22 namespace vccc {
23 namespace detail {
24 
25 template<typename T, typename = void>
26 struct has_typename_pointer : std::false_type {};
27 template<typename T>
28 struct has_typename_pointer<T, void_t<typename T::pointer>> : std::true_type {};
29 
30 template<typename T, typename = void>
31 struct has_typename_reference : std::false_type {};
32 template<typename T>
33 struct has_typename_reference<T, void_t<typename T::reference>> : std::true_type {};
34 
35 template<typename T, typename = void>
36 struct has_typename_iterator_category : std::false_type {};
37 template<typename T>
38 struct has_typename_iterator_category<T, void_t<typename T::iterator_category>>
39  : negation< std::is_same<iterator_ignore, typename T::iterator_category> > {};
40 
41 template<typename T, typename = void>
42 struct has_typename_iterator_concept : std::false_type {};
43 template<typename T>
44 struct has_typename_iterator_concept<T, void_t<typename T::iterator_concept>> : std::true_type {};
45 
47 struct cxx20_iterator_category_check_forward {
48  using type = input_iterator_tag;
49 };
50 
51 template<typename Iter>
52 struct cxx20_iterator_category_check_forward<Iter, true> {
53  using type = forward_iterator_tag;
54 };
55 
57 struct cxx20_iterator_category_check_bidirectional
58  : cxx20_iterator_category_check_forward<Iter> {};
59 
60 template<typename Iter>
61 struct cxx20_iterator_category_check_bidirectional<Iter, true> {
62  using type = bidirectional_iterator_tag;
63 };
64 
66 struct cxx20_iterator_category_check_random_access
67  : cxx20_iterator_category_check_bidirectional<Iter> {};
68 
69 template<typename Iter>
70 struct cxx20_iterator_category_check_random_access<Iter, true> {
71  using type = random_access_iterator_tag;
72 };
73 
75 struct cxx20_iterator_category : cxx20_iterator_category_check_random_access<Iter> {};
76 
77 template<typename Iter>
78 struct cxx20_iterator_category<Iter, true> {
79  using type = typename Iter::iterator_category;
80 };
81 
83 struct cxx20_iterator_traits_reference {
84  using type = iter_reference_t<Iter>;
85 };
86 template<typename Iter>
87 struct cxx20_iterator_traits_reference<Iter, true> {
88  using type = typename Iter::reference;
89 };
90 
91 template<typename Iter, typename = void>
92 struct cxx20_iterator_traits_pointer_sfinae {
93  using type = void;
94 };
95 template<typename Iter>
96 struct cxx20_iterator_traits_pointer_sfinae<Iter, void_t<decltype( std::declval<Iter&>().operator->() )>> {
97  using type = decltype( std::declval<Iter&>().operator->() );
98 };
100 struct cxx20_iterator_traits_pointer : cxx20_iterator_traits_pointer_sfinae<Iter> {};
101 template<typename Iter>
102 struct cxx20_iterator_traits_pointer<Iter, true> {
103  using type = typename Iter::pointer;
104 };
105 
106 template<
107  typename Iter,
108  bool = has_typename_difference_type<incrementable_traits<Iter>>::value /* false */
109 >
110 struct cxx20_iterator_traits_sfinae_legacy_iterator_difference_type {
111  using type = void;
112 };
113 template<typename Iter>
114 struct cxx20_iterator_traits_sfinae_legacy_iterator_difference_type<Iter, true> {
115  using type = typename incrementable_traits<Iter>::difference_type;
116 };
117 
118 template<
119  typename Iter,
120  bool = LegacyIterator<Iter>::value /* false */
121 >
122 struct cxx20_iterator_traits_sfinae_legacy_iterator {};
123 
124 template<typename Iter>
125 struct cxx20_iterator_traits_sfinae_legacy_iterator<Iter, true> {
126  using difference_type = typename cxx20_iterator_traits_sfinae_legacy_iterator_difference_type<Iter>::difference_type;
127  using value_type = void;
128  using pointer = void;
129  using reference = void;
130  using iterator_category = output_iterator_tag;
131 };
132 
134 struct cxx20_iterator_traits_sfinae_legacy_input_iterator : cxx20_iterator_traits_sfinae_legacy_iterator<Iter> {};
135 
136 template<typename Iter>
137 struct cxx20_iterator_traits_sfinae_legacy_input_iterator<Iter, true> {
138  using difference_type = typename incrementable_traits<Iter>::difference_type;
139  using value_type = typename indirectly_readable_traits<Iter>::value_type;
140  using pointer = typename cxx20_iterator_traits_pointer<Iter>::type;
141  using reference = typename cxx20_iterator_traits_reference<Iter>::type;
142  using iterator_category = typename cxx20_iterator_category<Iter>::type;;
143 };
144 
145 template<
146  typename Iter,
152 >
153 struct cxx20_iterator_traits_sfinae : cxx20_iterator_traits_sfinae_legacy_input_iterator<Iter> {};
154 
155 template<typename Iter>
156 struct cxx20_iterator_traits_sfinae<Iter, true, true, true, true, true> {
157  using difference_type = typename Iter::difference_type;
158  using value_type = typename Iter::value_type;
159  using pointer = typename Iter::pointer;
160  using reference = typename Iter::reference;
161  using iterator_category = typename Iter::iterator_category;
162 };
163 
164 template<typename Iter>
165 struct cxx20_iterator_traits_sfinae<Iter, true, true, false, true, true> {
166  using difference_type = typename Iter::difference_type;
167  using value_type = typename Iter::value_type;
168  using pointer = void;
169  using reference = typename Iter::reference;
170  using iterator_category = typename Iter::iterator_category;
171 };
172 
174 struct cxx20_iterator_traits_object_pointer {};
175 template<typename T>
176 struct cxx20_iterator_traits_object_pointer<T, true> {
177  using difference_type = std::ptrdiff_t;
178  using value_type = std::remove_cv_t<T>;
179  using pointer = T*;
180  using reference = T&;
181  using iterator_category = random_access_iterator_tag;
182  using iterator_concept = contiguous_iterator_tag;
183 };
184 
185 } // namespace detail
186 
187 template<typename Iter>
188 struct cxx20_iterator_traits : detail::cxx20_iterator_traits_sfinae<Iter> {};
189 
190 template<typename T>
191 struct cxx20_iterator_traits<T*> : detail::cxx20_iterator_traits_object_pointer<T> {};
192 
193 } // namespace vccc
194 
195 #endif // VCCC_ITERATOR_ITERATOR_TRAITS_CXX20_ITERATOR_TRAITS_HPP_
std::forward_iterator_tag forward_iterator_tag
Definition: iterator_tag.hpp:17
std::random_access_iterator_tag random_access_iterator_tag
Definition: iterator_tag.hpp:19
std::output_iterator_tag output_iterator_tag
Definition: iterator_tag.hpp:16
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
std::bidirectional_iterator_tag bidirectional_iterator_tag
Definition: iterator_tag.hpp:18
void void_t
Definition: void_t.hpp:19
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: cxx20_iterator_traits.hpp:188