-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathiterator_interface.hpp
More file actions
126 lines (106 loc) · 3.79 KB
/
Copy pathiterator_interface.hpp
File metadata and controls
126 lines (106 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#pragma once
#include <type_traits>
namespace stdx
{
template <typename Iterator, typename Category, typename ValueType, typename Reference = ValueType&,
typename Pointer = ValueType*>
class iterator_interface
{
template <typename It>
decltype(auto) access(It it)
{
if constexpr (std::is_pointer_v<pointer>)
return std::addressof(*it.iter());
else
return Pointer(*it.iter());
}
public:
using iterator_category [[maybe_unused]] = Category;
using value_type [[maybe_unused]] = std::remove_const_t<ValueType>;
using reference [[maybe_unused]] = Reference;
using pointer = Pointer;
using difference_type = std::ptrdiff_t;
constexpr decltype(auto) iter() { return static_cast<Iterator&>(*this); }
constexpr decltype(auto) iter() const { return static_cast<const Iterator&>(*this); }
constexpr auto operator->() requires requires { *iter(); }
{
return access(*this);
}
constexpr auto operator->() const requires requires { *iter(); }
{
return access(*this);
}
constexpr decltype(auto) operator[](difference_type n) const
requires std::derived_from<Category, std::random_access_iterator_tag>
{
auto it = iter();
it += n;
return *it;
}
constexpr decltype(auto) operator++() requires(!std::derived_from<Category, std::random_access_iterator_tag>)
{
++iter();
return iter();
}
constexpr decltype(auto) operator++() requires std::derived_from<Category, std::random_access_iterator_tag>
{
return iter() += 1;
}
constexpr auto operator++(int)
{
const auto it = iter();
++iter();
return it;
}
constexpr decltype(auto)
operator+=(difference_type n) requires(!std::derived_from<Category, std::random_access_iterator_tag>)
{
iter() += n;
return iter();
}
friend constexpr auto
operator+(Iterator it, difference_type n) requires std::derived_from<Category, std::random_access_iterator_tag>
{
it += n;
return it;
}
friend constexpr auto
operator+(difference_type n, Iterator it) requires std::derived_from<Category, std::random_access_iterator_tag>
{
it += n;
return it;
}
constexpr decltype(auto) operator--() requires std::same_as<Category, std::bidirectional_iterator_tag>
{
--iter();
return iter();
}
constexpr decltype(auto) operator--() requires std::derived_from<Category, std::random_access_iterator_tag>
{
return iter() += -1;
}
constexpr auto operator--(int) requires std::derived_from<Category, std::bidirectional_iterator_tag>
{
const auto it = iter();
--iter();
return it;
}
constexpr decltype(auto)
operator-=(difference_type n) requires std::derived_from<Category, std::random_access_iterator_tag>
{
return iter() += -n;
}
friend constexpr auto operator-(Iterator lhs,
Iterator rhs) requires std::same_as<Category, std::bidirectional_iterator_tag>
{
return lhs - rhs;
}
friend constexpr auto
operator-(Iterator it, difference_type n) requires std::derived_from<Category, std::random_access_iterator_tag>
{
it += -n;
return it;
}
constexpr auto operator<=>(const iterator_interface&) const = default;
};
}