17 #ifndef OPENKALMAN_COMPATIBILITY_ITERATOR_HPP 18 #define OPENKALMAN_COMPATIBILITY_ITERATOR_HPP 29 #ifdef __cpp_lib_ranges 30 using std::indirectly_readable_traits;
31 using std::incrementable_traits;
32 using std::contiguous_iterator_tag;
33 using std::iterator_traits;
34 using std::iter_value_t;
35 using std::iter_reference_t;
36 using std::iter_difference_t;
37 using std::iter_rvalue_reference_t;
38 using std::indirectly_readable;
39 using std::iter_common_reference_t;
40 #if __cplusplus >= 202302L 41 using std::iter_const_reference_t;
43 using std::indirectly_writable;
44 using std::weakly_incrementable;
45 using std::input_or_output_iterator;
46 using std::input_iterator;
47 using std::output_iterator;
48 using std::incrementable;
49 using std::forward_iterator;
50 using std::bidirectional_iterator;
51 using std::random_access_iterator;
52 using std::sentinel_for;
53 using std::sized_sentinel_for;
54 using std::unreachable_sentinel_t;
55 using std::unreachable_sentinel;
57 using std::indirectly_copyable;
64 namespace detail_indirectly_readable
68 template<
typename,
typename =
void>
72 struct cond_value_type<T,
std::enable_if_t<std::is_object_v<T>>> {
using value_type = std::remove_cv_t<T>; };
74 template<
typename,
typename =
void>
83 template<
typename,
typename =
void>
94 template<
typename I,
typename =
void>
102 {
using value_type = std::remove_cv_t<std::remove_extent_t<I>>; };
109 detail_indirectly_readable::has_member_value_type<T> and
110 not detail_indirectly_readable::has_member_element_type<T>>>
115 not detail_indirectly_readable::has_member_value_type<T> and
116 detail_indirectly_readable::has_member_element_type<T>>>
121 detail_indirectly_readable::has_member_value_type<T> and
122 detail_indirectly_readable::has_member_element_type<T>>>
123 : std::conditional_t<
124 std::is_same_v<std::remove_cv_t<typename T::element_type>, std::remove_cv_t<typename T::value_type>>,
125 detail_indirectly_readable::cond_value_type<typename T::value_type>,
126 detail_indirectly_readable::no_value_type> {};
135 template<
typename,
typename =
void>
143 template<
typename I,
typename =
void>
147 struct incrementable_traits<T, std::enable_if_t<std::is_pointer_v<T> and std::is_object_v<std::remove_pointer_t<T>>>>
149 using difference_type = std::ptrdiff_t;
156 struct incrementable_traits<T, std::enable_if_t<not std::is_pointer_v<T> and detail::has_member_difference_type<T>::value>>
158 using difference_type =
typename T::difference_type;
162 struct incrementable_traits<T, std::enable_if_t<not std::is_pointer_v<T> and not detail::has_member_difference_type<T>::value and
163 std::is_integral_v<decltype(std::declval<const T&>() - std::declval<const T&>())>>>
165 using difference_type = std::make_signed_t<decltype(std::declval<T>() - std::declval<T>())>;
169 struct contiguous_iterator_tag;
177 template<
typename T,
typename =
void>
180 template<
typename It>
182 typename It::iterator_category,
183 typename It::value_type,
184 typename It::difference_type,
185 typename It::reference>>
189 template<
typename T,
typename =
void>
192 template<
typename It>
197 template<
typename T,
typename =
void>
200 template<
typename It>
205 template<
typename T,
typename =
void>
208 template<
typename It>
213 template<
typename T,
typename =
void,
typename =
void>
219 stdex::copyable<T> and
220 stdex::same_as<decltype(++std::declval<T>()), T&>>,
222 decltype(*std::declval<T>())&,
223 decltype(*std::declval<T>()++)&>>
227 template<
typename T,
typename =
void,
typename =
void>
232 std::enable_if_t<stdex::signed_integral<typename stdex::incrementable_traits<T>::difference_type>>,
234 typename stdex::incrementable_traits<T>::difference_type,
235 typename stdex::indirectly_readable_traits<T>::value_type,
236 typename stdex::common_reference<decltype(*std::declval<T&>())&&, typename stdex::indirectly_readable_traits<T>::value_type&>::type,
237 decltype(*std::declval<T>()++),
238 typename stdex::common_reference<decltype(*std::declval<T>()++)&&, typename stdex::indirectly_readable_traits<T>::value_type&>::type>>
242 template<
typename T,
typename =
void>
247 std::void_t<typename stdex::incrementable_traits<T>::difference_type>>
254 template<
typename Iter,
typename =
void>
257 template<
typename It>
258 struct iterator_traits<It, std::enable_if_t<detail::iterator_traits_defined<It>::value>>
260 using difference_type =
typename It::difference_type;
261 using value_type =
typename It::value_type;
263 using reference =
typename It::reference;
264 using iterator_category =
typename It::iterator_category;
267 template<
typename Iter>
269 not detail::iterator_traits_defined<Iter>::value and
270 not detail::legacy_iterator<Iter>::value and
271 detail::legacy_input_iterator<Iter>::value>>
276 using pointer = std::conditional_t<
278 typename Iter::pointer,
281 decltype(std::declval<Iter&>().operator->()),
283 using reference = std::conditional_t<
285 typename Iter::reference,
286 decltype(*std::declval<Iter&>())>;
287 using iterator_category = std::random_access_iterator_tag;
290 template<
typename Iter>
292 not detail::iterator_traits_defined<Iter>::value and
293 detail::legacy_iterator<Iter>::value and
294 not detail::legacy_input_iterator<Iter>::value>>
297 using value_type = void;
298 using pointer = void;
299 using reference = void;
300 using iterator_category = std::output_iterator_tag;
301 using iterator_concept = stdex::contiguous_iterator_tag;
307 using difference_type = std::ptrdiff_t;
308 using value_type = std::remove_cv_t<T>;
310 using reference = T&;
311 using iterator_category = std::random_access_iterator_tag;
312 using iterator_concept = stdex::contiguous_iterator_tag;
322 template<
typename T,
typename =
void>
329 template<
typename T,
typename =
void>
341 using iter_reference_t = decltype(*std::declval<I&>());
347 using iter_rvalue_reference_t = decltype(std::move(*std::declval<I&>()));
356 template<
typename I,
typename =
void,
typename =
void>
361 std::void_t<iter_value_t<I>, iter_reference_t<I>, iter_rvalue_reference_t<I>>,
362 std::enable_if_t<std::is_same<decltype(*std::declval<I>()), iter_reference_t<I>>::value>> : std::true_type {};
370 template<
typename T, std::enable_if_t<indirectly_readable<T>,
int > = 0>
371 using iter_common_reference_t = stdex::common_reference_t<iter_reference_t<T>, iter_value_t<T>&>;
376 #if __cplusplus < 202302L 377 template<
typename T, std::enable_if_t<indirectly_readable<T>,
int > = 0>
378 using iter_const_reference_t = stdex::common_reference_t<const iter_value_t<T>&&, iter_reference_t<T>>;
382 #ifndef __cpp_lib_ranges 389 template<
typename Out,
typename T,
typename =
void>
392 template<
typename Out,
typename T>
395 decltype(*std::declval<Out&>() = std::declval<T&&>()),
396 decltype(*std::declval<Out&&>() = std::declval<T&&>()),
397 decltype(const_cast<const iter_reference_t<Out>&&>(*std::declval<Out&>()) = std::declval<T&&>()),
398 decltype(const_cast<const iter_reference_t<Out>&&>(*std::declval<Out&&>()) = std::declval<T&&>())
399 >> : std::true_type {};
403 template<
typename Out,
typename T>
413 template<
typename I,
typename =
void,
typename =
void>
418 std::enable_if_t<std::is_same<decltype(++std::declval<I&>()), I&>::value>> : std::true_type {};
432 template<
typename I,
typename =
void,
typename =
void>
437 std::void_t<iter_value_t<I>, iter_reference_t<I>, iter_rvalue_reference_t<I>>,
438 std::enable_if_t<std::is_same<decltype(*std::declval<I>()), iter_reference_t<I>>::value>> : std::true_type {};
451 inline constexpr
bool input_iterator =
452 input_or_output_iterator<I> and
453 indirectly_readable<I>;
462 template<
typename I,
typename T,
typename =
void>
465 template<
typename I,
typename T>
466 struct output_iterator_impl<I, T, std::void_t<decltype(*std::declval<I&>()++ = std::declval<T&&>())>> : std::true_type {};
470 template<
typename I,
typename T>
471 inline constexpr
bool output_iterator =
472 input_or_output_iterator<I> and
473 indirectly_writable<I, T> and
483 template<
typename I,
typename =
void>
487 struct is_incrementable<I, std::enable_if_t<std::is_same<decltype(std::declval<I&>()++), I>::value>> : std::true_type {};
492 inline constexpr
bool incrementable =
493 stdex::copy_constructible<I> and
494 std::is_object_v<I> and
495 std::is_move_constructible_v<I> and
496 std::is_assignable_v<I&, I> and
497 std::is_assignable_v<I&, I&> and
498 std::is_assignable_v<I&, const I&> and
499 std::is_assignable_v<I&, const I> and
500 default_initializable<I> and
501 weakly_incrementable<I> and
510 inline constexpr
bool forward_iterator =
511 input_iterator<I> and
521 template<
typename I,
typename =
void>
526 stdex::same_as<decltype(--std::declval<I&>()), I&> and
527 stdex::same_as<decltype(std::declval<I&>()--), I>>> : std::true_type {};
532 inline constexpr
bool bidirectional_iterator =
533 forward_iterator<I> and
543 template<
typename T,
typename U,
typename =
void>
546 template<
typename I,
typename S>
548 stdex::same_as<decltype(std::declval<const S&>() - std::declval<const I&>()), iter_difference_t<I>> and
549 stdex::same_as<decltype(std::declval<const I&>() - std::declval<const S&>()), iter_difference_t<I>>
550 >> : std::true_type {};
555 template<
typename S,
typename I>
556 inline constexpr
bool sentinel_for =
557 stdex::semiregular<S> and input_or_output_iterator<I> and OpenKalman::internal::WeaklyEqualityComparableWith<S, I>;
560 template<
typename S,
typename I>
561 inline constexpr
bool sized_sentinel_for = sentinel_for<S, I> and
572 template<
typename I,
typename =
void>
577 stdex::same_as<decltype(std::declval<I&>() += std::declval<iter_difference_t<I>>()), I&> and
578 stdex::same_as<decltype(std::declval<const I&>() + std::declval<iter_difference_t<I>>()), I> and
579 stdex::same_as<decltype(std::declval<iter_difference_t<I>>() + std::declval<const I&>()), I> and
580 stdex::same_as<decltype(std::declval<I&>() -= std::declval<iter_difference_t<I>>()), I&> and
581 stdex::same_as<decltype(std::declval<const I&>() - std::declval<iter_difference_t<I>>()), I> and
582 stdex::same_as<decltype(std::declval<const I&>()[std::declval<iter_difference_t<I>>()]), iter_reference_t<I>>
583 >> : std::true_type {};
588 inline constexpr
bool random_access_iterator =
589 bidirectional_iterator<I> and
590 stdex::totally_ordered<I> and
591 stdex::sized_sentinel_for<I, I> and
601 template<
typename I, std::enable_if_t<weakly_incrementable<I>,
int> = 0>
602 friend constexpr
bool 605 template<
typename I, std::enable_if_t<weakly_incrementable<I>,
int> = 0>
606 friend constexpr
bool 609 template<
typename I, std::enable_if_t<weakly_incrementable<I>,
int> = 0>
610 friend constexpr
bool 613 template<
typename I, std::enable_if_t<weakly_incrementable<I>,
int> = 0>
614 friend constexpr
bool 617 template<
typename I, std::enable_if_t<weakly_incrementable<I>,
int> = 0>
618 friend constexpr
bool 621 template<
typename I, std::enable_if_t<weakly_incrementable<I>,
int> = 0>
622 friend constexpr
bool 635 template<
typename In,
typename Out>
636 inline constexpr
bool indirectly_copyable =
637 indirectly_readable<In> and
638 indirectly_writable<Out, iter_reference_t<In>>;
Definition: iterator.hpp:75
Definition: iterator.hpp:255
Definition: iterator.hpp:178
Definition: iterator.hpp:414
Definition: iterator.hpp:463
Definition: iterator.hpp:198
Definition: iterator.hpp:206
Definition: iterator.hpp:136
Definition: iterator.hpp:544
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
Definition: iterator.hpp:84
Definitions relating to standard c++ library concepts.
Definition: iterator.hpp:390
Definition: iterator.hpp:243
Definition: iterator.hpp:144
Exposition-only definitions from teh c++ language standard.
Definition: iterator.hpp:330
Definitions relating to the availability of c++ language features.
Definition: iterator.hpp:214
Definition: iterator.hpp:69
Definition: iterator.hpp:484
Definition: iterator.hpp:522
Definition: iterator.hpp:357
Definition: iterator.hpp:190
Definition: iterator.hpp:599
Definitions relating to standard c++ library concepts.
Definition: iterator.hpp:66
Definition: iterator.hpp:323
Definition: iterator.hpp:95
Definition: iterator.hpp:573
Definition: basics.hpp:55