2
2
#ifndef BEMAN_OPTIONAL26_OPTIONAL_DETAIL_ITERATOR_HPP
3
3
#define BEMAN_OPTIONAL26_OPTIONAL_DETAIL_ITERATOR_HPP
4
4
5
+ #include < Beman/Optional26/detail/stl_interfaces/iterator_interface.hpp>
6
+
5
7
#include < iterator>
6
- #include < type_traits>
7
8
8
9
namespace beman ::optional::detail {
9
- // Implementation inspired by libstdc++'s normal_iterator
10
- // (https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_iterator.h)
11
- //
12
- //
13
- // This iterator adapter is a normal iterator in the sense that it does not
14
- // change the semantics of any of the operators of its iterator
15
- // parameter. Its primary purpose is to convert an iterator that is
16
- // not a class, e.g. a pointer, into an iterator that is a class.
17
- //
18
- // The ContainerType parameter exists solely so that different containers
19
- // using this template can instantiate different types, even if the
20
- // IteratorType parameter is the same.
10
+
11
+ // This is a minimal contiguous iterator. It uses stl_interfaces library from Boost
12
+ // (current implementation based on https://wg21.link/P2727R4).
21
13
//
22
- // FUTURE Use std::iterator_interface from https://wg21.link/P2727R4.
23
- // Adopt Boost's iterator_interface (https://github.com/boostorg/stl_interfaces) into a Beman library.
14
+ // TODO: Change this to use the stl_interfaces library from Beman when available.
24
15
//
25
- template <typename IteratorType, typename ContainerType>
26
- class normal_iterator {
27
- public:
28
- using iterator_type = IteratorType;
16
+ // @tparam T - The type of the elements the iterator points to.
17
+ // @tparam Container - The type of the container the iterator points to. This parameter exists solely so that different
18
+ // containers using this template can instantiate different types, even if the T parameter is the same.
19
+ template <class T , class Container >
20
+ struct contiguous_iterator : boost::stl_interfaces::iterator_interface<
21
+ #if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
22
+ contiguous_iterator<T, Container>,
23
+ #endif
24
+ std::contiguous_iterator_tag,
25
+ T> {
26
+ using iterator_type = T*;
29
27
using iterator_category = std::iterator_traits<iterator_type>::iterator_category;
30
28
using iterator_concept = std::iterator_traits<iterator_type>::iterator_concept;
31
29
using value_type = std::iterator_traits<iterator_type>::value_type;
@@ -34,114 +32,23 @@ class normal_iterator {
34
32
using pointer = std::iterator_traits<iterator_type>::pointer;
35
33
36
34
// Default constructor.
37
- constexpr normal_iterator () noexcept : m_current(IteratorType()) {}
38
-
39
- // Constructor from an iterator.
40
- explicit constexpr normal_iterator (const IteratorType& iter) noexcept : m_current(iter) {}
41
-
42
- // Allow iterator to const_iterator conversion.
43
- template <typename OtherIteratorType,
44
- typename = std::enable_if_t <std::is_convertible_v<OtherIteratorType, IteratorType>>>
45
- constexpr normal_iterator (const normal_iterator<OtherIteratorType, ContainerType>& iter) noexcept
46
- : m_current(iter.base()) {}
47
-
48
- constexpr const auto & base () const noexcept { return m_current; }
35
+ contiguous_iterator () noexcept : m_current() {}
49
36
50
- // Forward iterator requirements
51
- constexpr reference operator *() const noexcept { return * m_current; }
37
+ // Pointer to iterator constructor.
38
+ contiguous_iterator (pointer it) noexcept : m_current(it) { }
52
39
53
- constexpr pointer operator ->() const noexcept { return m_current; }
54
-
55
- constexpr normal_iterator& operator ++() noexcept {
56
- ++m_current;
57
- return *this ;
58
- }
59
-
60
- constexpr normal_iterator operator ++(int ) noexcept { return normal_iterator (m_current++); }
61
-
62
- // Bidirectional iterator requirements
63
- constexpr normal_iterator& operator --() noexcept {
64
- --m_current;
40
+ // As per P2727R4, for contiguous iterator we only need to provide operator*, operator+= and operator-.
41
+ reference operator *() const noexcept { return *m_current; }
42
+ auto & operator +=(difference_type pos) noexcept {
43
+ m_current += pos;
65
44
return *this ;
66
45
}
46
+ difference_type operator -(contiguous_iterator other) const noexcept { return m_current - other.m_current ; }
67
47
68
- constexpr normal_iterator operator --(int ) noexcept { return normal_iterator (m_current--); }
69
-
70
- // Random access iterator requirements
71
- constexpr reference operator [](difference_type n) const noexcept { return m_current[n]; }
72
-
73
- constexpr normal_iterator& operator +=(difference_type n) noexcept {
74
- m_current += n;
75
- return *this ;
76
- }
77
-
78
- constexpr normal_iterator operator +(difference_type n) const noexcept { return normal_iterator (m_current + n); }
79
-
80
- constexpr normal_iterator& operator -=(difference_type n) noexcept {
81
- m_current -= n;
82
- return *this ;
83
- }
84
-
85
- constexpr normal_iterator operator -(difference_type n) const noexcept { return normal_iterator (m_current - n); }
86
-
87
- protected:
88
- // The underlying pointer iterator.
89
- IteratorType m_current;
48
+ private:
49
+ T* m_current;
90
50
};
91
51
92
- // Forward iterator requirements
93
- template <typename IteratorTypeL, typename IteratorTypeR, typename ContainerType>
94
- [[nodiscard]] constexpr inline bool operator ==(const normal_iterator<IteratorTypeL, ContainerType>& lhs,
95
- const normal_iterator<IteratorTypeR, ContainerType>& rhs) noexcept {
96
- return lhs.base () == rhs.base ();
97
- }
98
-
99
- template <typename IteratorTypeL, typename IteratorTypeR, typename ContainerType>
100
- [[nodiscard]] constexpr inline bool operator !=(const normal_iterator<IteratorTypeL, ContainerType>& lhs,
101
- const normal_iterator<IteratorTypeR, ContainerType>& rhs) noexcept {
102
- return lhs.base () != rhs.base ();
103
- }
104
-
105
- // Random access iterator requirements
106
- template <typename IteratorTypeL, typename IteratorTypeR, typename ContainerType>
107
- [[nodiscard]] inline bool operator <(const normal_iterator<IteratorTypeL, ContainerType>& lhs,
108
- const normal_iterator<IteratorTypeR, ContainerType>& rhs) noexcept {
109
- return lhs.base () < rhs.base ();
110
- }
111
-
112
- template <typename IteratorTypeL, typename IteratorTypeR, typename ContainerType>
113
- [[nodiscard]] inline bool operator >(const normal_iterator<IteratorTypeL, ContainerType>& lhs,
114
- const normal_iterator<IteratorTypeR, ContainerType>& rhs) noexcept {
115
- return lhs.base () > rhs.base ();
116
- }
117
-
118
- template <typename IteratorTypeL, typename IteratorTypeR, typename ContainerType>
119
- [[nodiscard]] inline bool operator <=(const normal_iterator<IteratorTypeL, ContainerType>& lhs,
120
- const normal_iterator<IteratorTypeR, ContainerType>& rhs) noexcept {
121
- return lhs.base () <= rhs.base ();
122
- }
123
-
124
- template <typename IteratorTypeL, typename IteratorTypeR, typename ContainerType>
125
- [[nodiscard]] inline bool operator >=(const normal_iterator<IteratorTypeL, ContainerType>& lhs,
126
- const normal_iterator<IteratorTypeR, ContainerType>& rhs) noexcept {
127
- return lhs.base () >= rhs.base ();
128
- }
129
-
130
- // According to the resolution of DR179 not only the various comparison
131
- // operators but also operator- must accept mixed iterator/const_iterator
132
- template <typename IteratorTypeL, typename IteratorTypeR, typename ContainerType>
133
- [[nodiscard]] constexpr inline auto operator -(const normal_iterator<IteratorTypeL, ContainerType>& lhs,
134
- const normal_iterator<IteratorTypeR, ContainerType>& rhs) noexcept {
135
- return lhs.base () - rhs.base ();
136
- }
137
-
138
- template <typename IteratorType, typename ContainerType>
139
- [[nodiscard]] constexpr inline normal_iterator<IteratorType, ContainerType>
140
- operator +(typename normal_iterator<IteratorType, ContainerType>::difference_type n,
141
- const normal_iterator<IteratorType, ContainerType>& iter) noexcept {
142
- return normal_iterator (iter.base () + n);
143
- }
144
-
145
52
} // namespace beman::optional::detail
146
53
147
54
#endif // BEMAN_OPTIONAL26_OPTIONAL_DETAIL_ITERATOR_HPP
0 commit comments