Line data Source code
1 : #pragma once 2 : 3 : #include <iterator> 4 : 5 : namespace elsa::detail 6 : { 7 : /** 8 : * @brief iterator which uses a non-owning raw pointer to iterate over a container. The iterator 9 : * is random access and assumes contiguous memory layout. 10 : * 11 : * @author David Frank - initial implementation 12 : * 13 : * @tparam T - the type of the container 14 : * 15 : * Note: comparing iterators from different containers is undefined behavior, so we do not check 16 : * for it. 17 : */ 18 : template <typename T> 19 : class PtrIterator 20 : { 21 : public: 22 : /// alias for iterator type 23 : using self_type = PtrIterator; 24 : 25 : /// the iterator category 26 : using iterator_category = std::random_access_iterator_tag; 27 : /// the value type of container elements 28 : using value_type = typename T::value_type; 29 : /// pointer type of container elements 30 : using pointer = typename T::pointer; 31 : /// reference type of container elements 32 : using reference = typename T::reference; 33 : /// difference type of container 34 : using difference_type = typename T::difference_type; 35 : 36 : /// constructor taking a non-owning pointer to the data 37 520132 : explicit PtrIterator(pointer ptr) : _ptr(ptr) {} 38 : 39 : /// de-referencing operator 40 544722 : reference operator*() { return *_ptr; } 41 : /// pointer access operator 42 : pointer operator->() { return _ptr; } 43 : /// subscript operator 44 : reference operator[](int m) { return _ptr[m]; } 45 : 46 : /// prefix increment operator 47 : self_type operator++() 48 25532 : { 49 25532 : ++_ptr; 50 25532 : return *this; 51 25532 : } 52 : /// postfix increment operator 53 : self_type operator++(int) & 54 519190 : { 55 519190 : auto i = *this; 56 519190 : ++_ptr; 57 519190 : return i; 58 519190 : } 59 : 60 : /// prefix decrement operator 61 : self_type operator--() 62 : { 63 : --_ptr; 64 : return *this; 65 : } 66 : /// postfix decrement operator 67 : self_type operator--(int) & 68 : { 69 : auto i = *this; 70 : --_ptr; 71 : return i; 72 : } 73 : 74 : /// moving iterator forward by n 75 : self_type& operator+=(int n) 76 : { 77 : _ptr += n; 78 : return *this; 79 : } 80 : /// moving iterator backward by n 81 : self_type& operator-=(int n) 82 : { 83 : _ptr -= n; 84 : return *this; 85 : } 86 : 87 : /// return new iterator moved forward by n 88 : self_type operator+(int n) const 89 : { 90 : self_type r(*this); 91 : return r += n; 92 : } 93 : /// return new iterator moved backward by n 94 : self_type operator-(int n) const 95 : { 96 : self_type r(*this); 97 : return r -= n; 98 : } 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 544624 : 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 : private: 117 : /// non-owning (!) pointer to data (do not clean up or anything) 118 : pointer _ptr{}; 119 : }; 120 : 121 : /** 122 : * @brief constant iterator which uses a non-owning raw pointer to iterate over a container. The 123 : * iterator is random access and assumes contiguous memory layout. It is const in the sense that 124 : * it cannot mutate the state of the object it iterates over. 125 : * 126 : * @author David Frank - initial implementation 127 : * 128 : * @tparam T - the type of the container 129 : * 130 : * Note: comparing iterators from different containers is undefined behavior, so we do not check 131 : * for it. 132 : */ 133 : template <typename T> 134 : class ConstPtrIterator 135 : { 136 : public: 137 : /// alias for iterator type 138 : using self_type = ConstPtrIterator; 139 : 140 : /// the iterator category 141 : using iterator_category = std::random_access_iterator_tag; 142 : /// the value type of container elements 143 : using value_type = typename T::value_type; 144 : /// pointer type of container elements 145 : using pointer = typename T::const_pointer; 146 : /// reference type of container elements 147 : using reference = typename T::const_reference; 148 : /// difference type of container 149 : using difference_type = typename T::difference_type; 150 : 151 : /// constructor taking a non-owning pointer to the data 152 529382 : explicit ConstPtrIterator(pointer ptr) : _ptr(ptr) {} 153 : 154 : /// de-referencing operator 155 1338670 : reference operator*() { return *_ptr; } 156 : /// pointer access operator 157 : pointer operator->() { return _ptr; } 158 : /// subscript operator 159 : reference operator[](int m) { return _ptr[m]; } 160 : 161 : /// prefix increment operator 162 : self_type operator++() 163 17933 : { 164 17933 : ++_ptr; 165 17933 : return *this; 166 17933 : } 167 : /// postfix increment operator 168 : self_type operator++(int) & 169 519210 : { 170 519210 : auto i = *this; 171 519210 : ++_ptr; 172 519210 : return i; 173 519210 : } 174 : 175 : /// prefix decrement operator 176 : self_type operator--() 177 16840 : { 178 16840 : --_ptr; 179 16840 : return *this; 180 16840 : } 181 : /// postfix decrement operator 182 : self_type operator--(int) & 183 : { 184 : auto i = *this; 185 : --_ptr; 186 : return i; 187 : } 188 : 189 : /// moving iterator forward by n 190 : self_type& operator+=(int n) 191 : { 192 : _ptr += n; 193 : return *this; 194 : } 195 : /// moving iterator backward by n 196 : self_type& operator-=(int n) 197 : { 198 : _ptr -= n; 199 : return *this; 200 : } 201 : 202 : /// return new iterator moved forward by n 203 : self_type operator+(int n) const 204 : { 205 : self_type r(*this); 206 : return r += n; 207 : } 208 : /// return new iterator moved backward by n 209 : self_type operator-(int n) const 210 : { 211 : self_type r(*this); 212 : return r -= n; 213 : } 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 219 : bool operator<(const self_type& r) const { return _ptr < r._ptr; } 220 : /// compare <= with other iterator 221 : bool operator<=(const self_type& r) const { return _ptr <= r._ptr; } 222 : /// compare > with other iterator 223 : bool operator>(const self_type& r) const { return _ptr > r._ptr; } 224 : /// compare >= with other iterator 225 : bool operator>=(const self_type& r) const { return _ptr >= r._ptr; } 226 : /// compare != with other iterator 227 538010 : bool operator!=(const self_type& r) const { return _ptr != r._ptr; } 228 : /// compare == with other iterator 229 8429 : bool operator==(const self_type& r) const { return _ptr == r._ptr; } 230 : 231 : private: 232 : /// non-owning (!) pointer to data (do not clean up or anything) 233 : pointer _ptr{}; 234 : }; 235 : 236 : } // end namespace elsa::detail 237 : 238 : namespace elsa 239 : { 240 : /// alias for the iterator for DataContainer 241 : template <typename T> 242 : using DataContainerIterator = detail::PtrIterator<T>; 243 : 244 : /// alias for the constant iterator for DataContainer 245 : template <typename T> 246 : using ConstDataContainerIterator = detail::ConstPtrIterator<T>; 247 : } // end namespace elsa