DataContainerIterator.h 7.67 KB
Newer Older
1
2
3
4
5
6
7
#pragma once

#include <iterator>

namespace elsa::detail
{
    /**
Jens Petit's avatar
Jens Petit committed
8
9
     * \brief iterator which uses a non-owning raw pointer to iterate over a container. The iterator
     * is random access and assumes contiguous memory layout.
10
11
12
13
14
     *
     * \author David Frank - initial implementation
     *
     * \tparam T - the type of the container
     *
Jens Petit's avatar
Jens Petit committed
15
16
     * Note: comparing iterators from different containers is undefined behavior, so we do not check
     * for it.
17
18
     */
    template <typename T>
19
    class PtrIterator
20
21
22
    {
    public:
        /// alias for iterator type
23
        using self_type = PtrIterator;
24
25
26
27
28
29
30
31
32
33
34
35
36

        /// the iterator category
        using iterator_category = std::random_access_iterator_tag;
        /// the value type of container elements
        using value_type = typename T::value_type;
        /// pointer type of container elements
        using pointer = typename T::pointer;
        /// reference type of container elements
        using reference = typename T::reference;
        /// difference type of container
        using difference_type = typename T::difference_type;

        /// constructor taking a non-owning pointer to the data
37
        explicit PtrIterator(pointer ptr) : _ptr(ptr) {}
38
39

        /// de-referencing operator
Jens Petit's avatar
Jens Petit committed
40
        reference operator*() { return *_ptr; }
41
        /// pointer access operator
Jens Petit's avatar
Jens Petit committed
42
        pointer operator->() { return _ptr; }
43
        /// subscript operator
Jens Petit's avatar
Jens Petit committed
44
        reference operator[](int m) { return _ptr[m]; }
45
46

        /// prefix increment operator
Jens Petit's avatar
Jens Petit committed
47
48
49
50
51
        self_type operator++()
        {
            ++_ptr;
            return *this;
        }
52
        /// postfix increment operator
53
        self_type operator++(int) &
Jens Petit's avatar
Jens Petit committed
54
55
56
57
58
        {
            auto i = *this;
            ++_ptr;
            return i;
        }
59
60

        /// prefix decrement operator
Jens Petit's avatar
Jens Petit committed
61
62
63
64
65
        self_type operator--()
        {
            --_ptr;
            return *this;
        }
66
        /// postfix decrement operator
67
        self_type operator--(int) &
Jens Petit's avatar
Jens Petit committed
68
69
70
71
72
        {
            auto i = *this;
            --_ptr;
            return i;
        }
73
74

        /// moving iterator forward by n
Jens Petit's avatar
Jens Petit committed
75
76
77
78
79
        self_type& operator+=(int n)
        {
            _ptr += n;
            return *this;
        }
80
        /// moving iterator backward by n
Jens Petit's avatar
Jens Petit committed
81
82
83
84
85
        self_type& operator-=(int n)
        {
            _ptr -= n;
            return *this;
        }
86
87

        /// return new iterator moved forward by n
Jens Petit's avatar
Jens Petit committed
88
89
90
91
92
        self_type operator+(int n) const
        {
            self_type r(*this);
            return r += n;
        }
93
        /// return new iterator moved backward by n
Jens Petit's avatar
Jens Petit committed
94
95
96
97
98
        self_type operator-(int n) const
        {
            self_type r(*this);
            return r -= n;
        }
99
100

        /// return the difference between iterators
101
        difference_type operator-(PtrIterator const& r) const { return _ptr - r._ptr; }
102
103

        /// compare < with other iterator
104
        bool operator<(const PtrIterator& r) const { return _ptr < r._ptr; }
105
        /// compare <= with other iterator
106
        bool operator<=(const PtrIterator& r) const { return _ptr <= r._ptr; }
107
        /// compare > with other iterator
108
        bool operator>(const PtrIterator& r) const { return _ptr > r._ptr; }
109
        /// compare >= with other iterator
110
        bool operator>=(const PtrIterator& r) const { return _ptr >= r._ptr; }
111
        /// compare != with other iterator
112
        bool operator!=(const PtrIterator& r) const { return _ptr != r._ptr; }
113
        /// compare == with other iterator
114
        bool operator==(const PtrIterator& r) const { return _ptr == r._ptr; }
115
116
117

    private:
        /// non-owning (!) pointer to data (do not clean up or anything)
Jens Petit's avatar
Jens Petit committed
118
        pointer _ptr{};
119
120
121
    };

    /**
Jens Petit's avatar
Jens Petit committed
122
123
124
     * \brief constant iterator which uses a non-owning raw pointer to iterate over a container. The
     * iterator is random access and assumes contiguous memory layout. It is const in the sense that
     * it cannot mutate the state of the object it iterates over.
125
126
127
128
129
     *
     * \author David Frank - initial implementation
     *
     * \tparam T - the type of the container
     *
Jens Petit's avatar
Jens Petit committed
130
131
     * Note: comparing iterators from different containers is undefined behavior, so we do not check
     * for it.
132
     */
Jens Petit's avatar
Jens Petit committed
133
    template <typename T>
134
    class ConstPtrIterator
135
136
137
    {
    public:
        /// alias for iterator type
138
        using self_type = ConstPtrIterator;
139
140
141
142
143
144
145
146
147
148
149
150
151

        /// the iterator category
        using iterator_category = std::random_access_iterator_tag;
        /// the value type of container elements
        using value_type = typename T::value_type;
        /// pointer type of container elements
        using pointer = typename T::const_pointer;
        /// reference type of container elements
        using reference = typename T::const_reference;
        /// difference type of container
        using difference_type = typename T::difference_type;

        /// constructor taking a non-owning pointer to the data
152
        explicit ConstPtrIterator(pointer ptr) : _ptr(ptr) {}
153
154

        /// de-referencing operator
Jens Petit's avatar
Jens Petit committed
155
        reference operator*() { return *_ptr; }
156
        /// pointer access operator
Jens Petit's avatar
Jens Petit committed
157
        pointer operator->() { return _ptr; }
158
        /// subscript operator
Jens Petit's avatar
Jens Petit committed
159
        reference operator[](int m) { return _ptr[m]; }
160
161

        /// prefix increment operator
Jens Petit's avatar
Jens Petit committed
162
163
164
165
166
        self_type operator++()
        {
            ++_ptr;
            return *this;
        }
167
        /// postfix increment operator
168
        self_type operator++(int) &
Jens Petit's avatar
Jens Petit committed
169
170
171
172
173
        {
            auto i = *this;
            ++_ptr;
            return i;
        }
174
175

        /// prefix decrement operator
Jens Petit's avatar
Jens Petit committed
176
177
178
179
180
        self_type operator--()
        {
            --_ptr;
            return *this;
        }
181
        /// postfix decrement operator
182
        self_type operator--(int) &
Jens Petit's avatar
Jens Petit committed
183
184
185
186
187
        {
            auto i = *this;
            --_ptr;
            return i;
        }
188
189

        /// moving iterator forward by n
Jens Petit's avatar
Jens Petit committed
190
191
192
193
194
        self_type& operator+=(int n)
        {
            _ptr += n;
            return *this;
        }
195
        /// moving iterator backward by n
Jens Petit's avatar
Jens Petit committed
196
197
198
199
200
        self_type& operator-=(int n)
        {
            _ptr -= n;
            return *this;
        }
201
202

        /// return new iterator moved forward by n
Jens Petit's avatar
Jens Petit committed
203
204
205
206
207
        self_type operator+(int n) const
        {
            self_type r(*this);
            return r += n;
        }
208
        /// return new iterator moved backward by n
Jens Petit's avatar
Jens Petit committed
209
210
211
212
213
        self_type operator-(int n) const
        {
            self_type r(*this);
            return r -= n;
        }
214
215

        /// return the difference between iterators
216
        difference_type operator-(ConstPtrIterator const& r) const { return _ptr - r._ptr; }
217
218

        /// compare < with other iterator
Jens Petit's avatar
Jens Petit committed
219
        bool operator<(const self_type& r) const { return _ptr < r._ptr; }
220
221
222
        /// compare <= with other iterator
        bool operator<=(const self_type& r) const { return _ptr <= r._ptr; }
        /// compare > with other iterator
Jens Petit's avatar
Jens Petit committed
223
        bool operator>(const self_type& r) const { return _ptr > r._ptr; }
224
225
226
        /// compare >= with other iterator
        bool operator>=(const self_type& r) const { return _ptr >= r._ptr; }
        /// compare != with other iterator
Jens Petit's avatar
Jens Petit committed
227
        bool operator!=(const self_type& r) const { return _ptr != r._ptr; }
228
        /// compare == with other iterator
Jens Petit's avatar
Jens Petit committed
229
        bool operator==(const self_type& r) const { return _ptr == r._ptr; }
230
231
232

    private:
        /// non-owning (!) pointer to data (do not clean up or anything)
Jens Petit's avatar
Jens Petit committed
233
        pointer _ptr{};
234
235
236
237
238
239
240
241
    };

} // end namespace elsa::detail

namespace elsa
{
    /// alias for the iterator for DataContainer
    template <typename T>
242
    using DataContainerIterator = detail::PtrIterator<T>;
243
244
245

    /// alias for the constant iterator for DataContainer
    template <typename T>
246
    using ConstDataContainerIterator = detail::ConstPtrIterator<T>;
247
} // end namespace elsa