VCCC  2024.05
VisualCamp Common C++ library
incrementable_traits.hpp
Go to the documentation of this file.
1 //
2 // Created by cosge on 2023-12-03.
3 //
4 
5 #ifndef VCCC_ITERATOR_INCREMENTABLE_TRAITS_HPP_
6 #define VCCC_ITERATOR_INCREMENTABLE_TRAITS_HPP_
7 
8 #include <cstddef>
9 #include <iterator>
10 #include <type_traits>
11 
15 
16 namespace vccc {
17 namespace detail {
18 
20 struct substract_check : std::false_type {};
21 
22 template<typename T>
23 struct substract_check<T, true> : std::is_integral<decltype(std::declval<const T&>() - std::declval<const T&>())> {};
24 
25 
26 template<typename T>
27 struct incrementable_traits_subtractable {
28  using difference_type = std::make_signed_t<decltype(std::declval<T>() - std::declval<T>())>;
29 };
30 
31 template<typename T>
32 struct incrementable_traits_no_difference_type
33  : std::conditional_t<
34  substract_check<T>::value,
35  incrementable_traits_subtractable<T>,
36  empty
37  > {};
38 
39 template<typename T>
40 struct incrementable_traits_yes_difference_type {
41  using difference_type = typename T::difference_type;
42 };
43 
44 template<typename T>
45 struct incrementable_traits_impl
46  : std::conditional_t<
47  has_typename_difference_type<T>::value,
48  incrementable_traits_yes_difference_type<T>,
49  incrementable_traits_no_difference_type<T>
50  > {};
51 
52 template<typename T>
53 struct incrementable_traits_object_pointer {
54  using difference_type = std::ptrdiff_t;
55 };
56 
57 template<typename T>
58 struct incrementable_traits_impl<T*>
59  : std::conditional_t<
61  incrementable_traits_object_pointer<T>,
62  empty
63  > {};
64 
65 #if __cplusplus < 202002L
66 template<typename T>
67 struct incrementable_traits_impl<std::back_insert_iterator<T>> {
68  using difference_type = std::ptrdiff_t;
69 };
70 
71 template<typename T>
72 struct incrementable_traits_impl<std::front_insert_iterator<T>> {
73  using difference_type = std::ptrdiff_t;
74 };
75 
76 template<typename T>
77 struct incrementable_traits_impl<std::insert_iterator<T>> {
78  using difference_type = std::ptrdiff_t;
79 };
80 
81 template<typename T>
82 struct incrementable_traits_impl<std::ostream_iterator<T>> {
83  using difference_type = std::ptrdiff_t;
84 };
85 
86 template<typename T>
87 struct incrementable_traits_impl<std::ostreambuf_iterator<T>> {
88  using difference_type = std::ptrdiff_t;
89 };
90 #endif
91 
92 } // namespace detail
93 
94 
97 
117 template<typename I>
118 struct incrementable_traits;
119 
121 
122 template<typename I>
123 struct incrementable_traits : detail::incrementable_traits_impl<I> {};
124 
125 template<typename T>
127 
128 } // namespace vccc
129 
130 #endif // VCCC_ITERATOR_INCREMENTABLE_TRAITS_HPP_
constexpr VCCC_INLINE_OR_STATIC detail::empty_niebloid empty
checks whether a range is empty
Definition: empty.hpp:116
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
computes the difference type of a weakly_incrementable type
Definition: incrementable_traits.hpp:123