neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
i_iterator.hpp
Go to the documentation of this file.
1// i_iterator.hpp
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <iterator>
41
42namespace neolib
43{
44 struct singular_iterator : std::logic_error { singular_iterator() : std::logic_error("neolib::singular_iterator") {} };
45
46 template <typename, typename, typename, typename, typename>
47 class const_iterator;
48
49 template <typename T, typename Category = std::bidirectional_iterator_tag, typename Difference = std::ptrdiff_t, typename Pointer = const T*, typename Reference = const T&>
51 {
53 public:
54 typedef self_type abstract_type;
55 typedef T value_type;
56 typedef Difference difference_type;
57 typedef Pointer pointer;
58 typedef Reference reference;
59 typedef Category iterator_category;
60 public:
61 typedef self_type abstract_iterator;
62 typedef self_type abstract_const_iterator;
66 public:
67 virtual self_type& operator++() = 0;
68 virtual self_type& operator--() = 0;
71 virtual reference operator*() const = 0;
72 virtual pointer operator->() const = 0;
73 virtual bool operator==(const self_type& aOther) const = 0;
74 virtual bool operator!=(const self_type& aOther) const = 0;
75 public:
76 virtual self_type* clone(void* memory) const = 0;
77 private:
78 virtual self_type* do_post_increment(void* memory) = 0;
79 virtual self_type* do_post_decrement(void* memory) = 0;
80 };
81
82 template <typename, typename, typename, typename, typename>
84
85 template <typename T, typename Category = std::random_access_iterator_tag, typename Difference = std::ptrdiff_t, typename Pointer = const T*, typename Reference = const T&>
86 class i_random_access_const_iterator : public i_const_iterator<T, Category, Difference, Pointer, Reference>
87 {
89 public:
90 typedef self_type abstract_type;
92 public:
93 using typename base_type::value_type;
95 using typename base_type::pointer;
96 using typename base_type::reference;
98 public:
99 typedef self_type abstract_iterator;
100 typedef self_type abstract_const_iterator;
104 public:
105 virtual self_type& operator+=(difference_type aDifference) = 0;
106 virtual self_type& operator-=(difference_type aDifference) = 0;
109 virtual reference operator[](difference_type aDifference) const = 0;
110 virtual difference_type operator-(const self_type& aOther) const = 0;
111 virtual bool operator<(const self_type& aOther) const = 0;
112 virtual bool operator<=(const self_type& aOther) const = 0;
113 virtual bool operator>(const self_type& aOther) const = 0;
114 virtual bool operator>=(const self_type& aOther) const = 0;
115 private:
116 virtual self_type* do_add(void* memory, difference_type aDifference) const = 0;
117 virtual self_type* do_subtract(void* memory, difference_type aDifference) const = 0;
118 };
119
120 template <typename, typename, typename, typename, typename>
121 class i_iterator;
122 template <typename, typename, typename, typename, typename>
123 class iterator;
124
125 template <typename T, typename Category = std::bidirectional_iterator_tag, typename Difference = std::ptrdiff_t, typename Pointer = const T*, typename Reference = const T&>
127 {
129 public:
130 typedef T value_type;
131 typedef Difference difference_type;
132 typedef Pointer pointer;
133 typedef Reference reference;
134 typedef Category iterator_category;
135 public:
138 public:
140 {
141 }
143 {
144 aWrappedIterator->clone(storage());
145 wrapped_iterator().add_ref();
146 }
148 {
149 aOther.clone(storage());
150 wrapped_iterator().add_ref();
151 }
153 {
154 aOther.const_clone(storage());
155 wrapped_iterator().add_ref();
156 }
158 {
159 aOther.const_clone(storage());
160 wrapped_iterator().add_ref();
161 }
163 {
164 if (!is_singular())
165 wrapped_iterator().release();
166 }
168 {
169 const_iterator temp(aOther);
170 if (!is_singular())
171 wrapped_iterator().release();
172 temp.clone(storage());
173 wrapped_iterator().add_ref();
174 return *this;
175 }
177 {
178 iterator temp(aOther);
179 if (!is_singular())
180 wrapped_iterator().release();
181 temp.const_clone(storage());
182 wrapped_iterator().add_ref();
183 return *this;
184 }
185 operator abstract_iterator& ()
186 {
187 return wrapped_iterator();
188 }
189 public:
194 reference operator*() const { return wrapped_iterator().operator*(); }
195 pointer operator->() const { return wrapped_iterator().operator->(); }
196 bool operator==(const self_type& aOther) const { return wrapped_iterator() == aOther.wrapped_iterator(); }
197 bool operator!=(const self_type& aOther) const { return !(*this == aOther); }
198 public:
199 bool is_singular() const
200 {
201 return iSingular;
202 }
204 {
205 if (is_singular())
206 throw singular_iterator();
207 return *static_cast<abstract_iterator*>(storage());
208 }
209 abstract_iterator* clone(void* memory) const
210 {
211 if (is_singular())
212 throw singular_iterator();
213 return wrapped_iterator().clone(memory);
214 }
215 void* storage() const
216 {
217 iSingular = false;
218 return &iStorage;
219 }
220 protected:
221 mutable bool iSingular = true;
222 mutable std::aligned_storage<sizeof(void*) * 10>::type iStorage;
223 };
224
225 template <typename, typename, typename, typename, typename>
227
228 template <typename T, typename Category = std::random_access_iterator_tag, typename Difference = std::ptrdiff_t, typename Pointer = const T*, typename Reference = const T&>
229 class random_access_const_iterator : public const_iterator<T, Category, Difference, Pointer, Reference>
230 {
233 public:
235 using typename base_type::value_type;
236 using typename base_type::difference_type;
237 using typename base_type::pointer;
238 using typename base_type::reference;
239 using typename base_type::iterator_category;
240 public:
243 public:
249 base_type(aWrappedIterator)
250 {
251 }
253 base_type(aOther)
254 {
255 }
268 {
269 base_type::operator=(aOther);
270 return *this;
271 }
278 {
279 base_type::operator=(aOther);
280 return *this;
281 }
282 operator abstract_iterator& ()
283 {
284 return wrapped_iterator();
285 }
286 public:
287 abstract_iterator& operator+=(difference_type aDifference) { return wrapped_iterator() += aDifference; }
288 abstract_iterator& operator-=(difference_type aDifference) { return wrapped_iterator() -= aDifference; }
289 self_type operator+(difference_type aDifference) const { return wrapped_iterator() + aDifference; }
290 self_type operator-(difference_type aDifference) const { return wrapped_iterator() - aDifference; }
291 reference operator[](difference_type aDifference) const { return wrapped_iterator()[aDifference]; }
292 difference_type operator-(const self_type& aOther) const { return wrapped_iterator() - (aOther.wrapped_iterator()); }
293 bool operator<(const self_type& aOther) const { return wrapped_iterator() < aOther.wrapped_iterator(); }
294 bool operator<=(const self_type& aOther) const { return wrapped_iterator() <= aOther.wrapped_iterator(); }
295 bool operator>(const self_type& aOther) const { return wrapped_iterator() > aOther.wrapped_iterator(); }
296 bool operator>=(const self_type& aOther) const { return wrapped_iterator() >= aOther.wrapped_iterator(); }
297 public:
299 };
300
301 template <typename T, typename Category, typename Difference, typename Pointer, typename Reference>
303 template <typename T, typename Category, typename Difference, typename Pointer, typename Reference>
305 template <typename T, typename Category, typename Difference, typename Pointer, typename Reference>
312 template <typename T, typename Category, typename Difference, typename Pointer, typename Reference>
319
320 template <typename, typename, typename, typename, typename>
321 class iterator;
322
323 template <typename T, typename Category = std::bidirectional_iterator_tag, typename Difference = std::ptrdiff_t, typename Pointer = T*, typename Reference = T&>
325 {
327 public:
328 typedef self_type abstract_type;
329 public:
330 typedef T value_type;
331 typedef Difference difference_type;
332 typedef Pointer pointer;
333 typedef Reference reference;
334 typedef Category iterator_category;
335 public:
336 typedef self_type abstract_iterator;
341 public:
342 virtual self_type& operator++() = 0;
343 virtual self_type& operator--() = 0;
346 virtual reference operator*() const = 0;
347 virtual pointer operator->() const = 0;
348 virtual bool operator==(const self_type& aOther) const = 0;
349 virtual bool operator!=(const self_type& aOther) const = 0;
350 public:
351 virtual self_type* clone(void* memory) const = 0;
352 virtual abstract_const_iterator* const_clone(void* memory) const = 0;
353 private:
354 virtual self_type* do_post_increment(void* memory) = 0;
355 virtual self_type* do_post_decrement(void* memory) = 0;
356 };
357
358 template <typename, typename, typename, typename, typename>
360
361 template <typename T, typename Category = std::random_access_iterator_tag, typename Difference = std::ptrdiff_t, typename Pointer = T*, typename Reference = T&>
362 class i_random_access_iterator : public i_iterator<T, Category, Difference, Pointer, Reference>
363 {
366 public:
367 typedef self_type abstract_type;
368 public:
369 using typename base_type::value_type;
371 using typename base_type::pointer;
372 using typename base_type::reference;
374 public:
375 typedef self_type abstract_iterator;
380 public:
381 virtual self_type& operator+=(difference_type aDifference) = 0;
382 virtual self_type& operator-=(difference_type aDifference) = 0;
385 virtual reference operator[](difference_type aDifference) const = 0;
386 virtual difference_type operator-(const self_type& aOther) const = 0;
387 virtual bool operator<(const self_type& aOther) const = 0;
388 virtual bool operator<=(const self_type& aOther) const = 0;
389 virtual bool operator>(const self_type& aOther) const = 0;
390 virtual bool operator>=(const self_type& aOther) const = 0;
391 private:
392 virtual self_type* do_add(void* memory, difference_type aDifference) const = 0;
393 virtual self_type* do_subtract(void* memory, difference_type aDifference) const = 0;
394 };
395
396 template <typename T, typename Category = std::bidirectional_iterator_tag, typename Difference = std::ptrdiff_t, typename Pointer = T*, typename Reference = T&>
398 {
400 public:
402 typedef T value_type;
403 typedef Difference difference_type;
404 typedef Pointer pointer;
405 typedef Reference reference;
406 typedef Category iterator_category;
407 public:
410 public:
412 {
413 }
414 iterator(abstract_iterator* aWrappedIterator)
415 {
416 aWrappedIterator->clone(storage());
417 wrapped_iterator().add_ref();
418 }
419 iterator(const self_type& aOther)
420 {
421 aOther.clone(storage());
422 wrapped_iterator().add_ref();
423 }
425 {
426 if (!is_singular())
427 wrapped_iterator().release();
428 }
430 {
431 self_type temp(aOther);
432 if (!is_singular())
433 wrapped_iterator().release();
434 temp.clone(storage());
435 wrapped_iterator().add_ref();
436 return *this;
437 }
439 {
440 return wrapped_iterator();
441 }
442 public:
447 reference operator*() const { return wrapped_iterator().operator*(); }
448 pointer operator->() const { return wrapped_iterator().operator->(); }
449 bool operator==(const self_type& aOther) const { return wrapped_iterator() == aOther.wrapped_iterator(); }
450 bool operator!=(const self_type& aOther) const { return !(*this == aOther); }
451 public:
452 bool is_singular() const
453 {
454 return iSingular;
455 }
457 {
458 if (is_singular())
459 throw singular_iterator();
460 return *static_cast<abstract_iterator*>(storage());
461 }
462 abstract_iterator* clone(void* memory) const
463 {
464 if (is_singular())
465 throw singular_iterator();
466 return wrapped_iterator().clone(memory);
467 }
469 {
470 if (is_singular())
471 throw singular_iterator();
472 return wrapped_iterator().const_clone(memory);
473 }
474 void* storage() const
475 {
476 iSingular = false;
477 return &iStorage;
478 }
479 protected:
480 mutable bool iSingular = true;
481 mutable std::aligned_storage<sizeof(void*) * 10>::type iStorage;
482 };
483
484 template <typename T, typename Category = std::random_access_iterator_tag, typename Difference = std::ptrdiff_t, typename Pointer = T*, typename Reference = T&>
485 class random_access_iterator : public iterator<T, Category, Difference, Pointer, Reference>
486 {
489 public:
491 using typename base_type::value_type;
492 using typename base_type::difference_type;
493 using typename base_type::pointer;
494 using typename base_type::reference;
495 using typename base_type::iterator_category;
496 public:
499 public:
501 base_type()
502 {
503 }
505 base_type(aWrappedIterator)
506 {
507 }
509 base_type(aOther)
510 {
511 }
516 {
517 base_type::operator=(aOther);
518 return *this;
519 }
521 {
522 return wrapped_iterator();
523 }
524 public:
525 abstract_iterator& operator+=(difference_type aDifference) { return wrapped_iterator() += aDifference; }
526 abstract_iterator& operator-=(difference_type aDifference) { return wrapped_iterator() -= aDifference; }
527 self_type operator+(difference_type aDifference) const { return wrapped_iterator() + aDifference; }
528 self_type operator-(difference_type aDifference) const { return wrapped_iterator() - aDifference; }
529 reference operator[](difference_type aDifference) const { return wrapped_iterator()[aDifference]; }
530 difference_type operator-(const self_type& aOther) const { return wrapped_iterator() - (aOther.wrapped_iterator()); }
531 bool operator<(const self_type& aOther) const { return wrapped_iterator() < aOther.wrapped_iterator(); }
532 bool operator<=(const self_type& aOther) const { return wrapped_iterator() <= aOther.wrapped_iterator(); }
533 bool operator>(const self_type& aOther) const { return wrapped_iterator() > aOther.wrapped_iterator(); }
534 bool operator>=(const self_type& aOther) const { return wrapped_iterator() >= aOther.wrapped_iterator(); }
535 public:
537 };
538
539 template <typename T, typename Category, typename Difference, typename Pointer, typename Reference>
541 template <typename T, typename Category, typename Difference, typename Pointer, typename Reference>
543 template <typename T, typename Category, typename Difference, typename Pointer, typename Reference>
550 template <typename T, typename Category, typename Difference, typename Pointer, typename Reference>
557}
const_iterator(abstract_iterator *aWrappedIterator)
const_iterator(const iterator< T, Category, Difference, T *, T & > &aOther)
abstract_iterator * clone(void *memory) const
abstract_iterator & operator++()
bool operator==(const self_type &aOther) const
i_const_iterator< T, Category, Difference, Pointer, Reference > abstract_const_iterator
std::aligned_storage< sizeof(void *) *10 >::type iStorage
self_type & operator=(const iterator< T, Category, Difference, T *, T & > &aOther)
pointer operator->() const
i_const_iterator< T, Category, Difference, Pointer, Reference > abstract_iterator
self_type operator++(int)
bool operator!=(const self_type &aOther) const
abstract_iterator & wrapped_iterator() const
abstract_iterator & operator--()
void * storage() const
self_type & operator=(const self_type &aOther)
self_type operator--(int)
const_iterator(const i_iterator< T, Category, Difference, T *, T & > &aOther)
reference operator*() const
const_iterator(const self_type &aOther)
virtual self_type & operator--()=0
virtual reference operator*() const =0
virtual bool operator!=(const self_type &aOther) const =0
abstract_iterator abstract_base_iterator
const_iterator< T, Category, Difference, Pointer, Reference > iterator_wrapper
virtual self_type & operator++()=0
abstract_const_iterator abstract_base_const_iterator
virtual self_type * clone(void *memory) const =0
iterator_wrapper operator++(int)
virtual bool operator==(const self_type &aOther) const =0
self_type abstract_const_iterator
iterator_wrapper operator--(int)
virtual pointer operator->() const =0
virtual reference operator*() const =0
virtual self_type * clone(void *memory) const =0
iterator< T, Category, Difference, Pointer, Reference > iterator_wrapper
Category iterator_category
virtual self_type & operator--()=0
self_type abstract_iterator
virtual abstract_const_iterator * const_clone(void *memory) const =0
iterator_wrapper operator++(int)
virtual self_type & operator++()=0
i_const_iterator< T, Category, Difference, const T *, const T & > abstract_const_iterator
Difference difference_type
abstract_iterator abstract_base_iterator
self_type abstract_type
virtual pointer operator->() const =0
iterator_wrapper operator--(int)
virtual bool operator!=(const self_type &aOther) const =0
abstract_const_iterator abstract_base_const_iterator
virtual bool operator==(const self_type &aOther) const =0
virtual self_type & operator-=(difference_type aDifference)=0
virtual bool operator>(const self_type &aOther) const =0
random_access_const_iterator< T, Category, Difference, Pointer, Reference > iterator_wrapper
virtual bool operator>=(const self_type &aOther) const =0
virtual bool operator<(const self_type &aOther) const =0
virtual reference operator[](difference_type aDifference) const =0
virtual self_type & operator+=(difference_type aDifference)=0
abstract_const_iterator abstract_random_access_const_iterator
virtual difference_type operator-(const self_type &aOther) const =0
abstract_iterator abstract_random_access_iterator
i_const_iterator< T, Category, Difference, Pointer, Reference > base_type
iterator_wrapper operator+(difference_type aDifference) const
virtual bool operator<=(const self_type &aOther) const =0
iterator_wrapper operator-(difference_type aDifference) const
virtual self_type & operator+=(difference_type aDifference)=0
virtual bool operator>=(const self_type &aOther) const =0
iterator_wrapper operator+(difference_type aDifference) const
virtual difference_type operator-(const self_type &aOther) const =0
virtual bool operator<(const self_type &aOther) const =0
iterator_wrapper operator-(difference_type aDifference) const
random_access_iterator< T, Category, Difference, Pointer, Reference > iterator_wrapper
abstract_iterator abstract_random_access_iterator
i_random_access_const_iterator< T, Category, Difference, const T *, const T & > abstract_const_iterator
virtual reference operator[](difference_type aDifference) const =0
abstract_const_iterator abstract_random_access_const_iterator
virtual self_type & operator-=(difference_type aDifference)=0
virtual bool operator>(const self_type &aOther) const =0
virtual bool operator<=(const self_type &aOther) const =0
abstract_iterator & wrapped_iterator() const
Category iterator_category
void * storage() const
bool is_singular() const
i_const_iterator< T, Category, Difference, const T *, const T & > abstract_const_iterator
self_type operator++(int)
std::aligned_storage< sizeof(void *) *10 >::type iStorage
abstract_iterator & operator--()
Reference reference
Difference difference_type
abstract_iterator & operator++()
reference operator*() const
bool operator!=(const self_type &aOther) const
i_iterator< T, Category, Difference, Pointer, Reference > abstract_type
bool operator==(const self_type &aOther) const
iterator(abstract_iterator *aWrappedIterator)
abstract_iterator * clone(void *memory) const
self_type operator--(int)
iterator(const self_type &aOther)
abstract_type abstract_iterator
pointer operator->() const
self_type & operator=(const self_type &aOther)
abstract_const_iterator * const_clone(void *memory) const
random_access_const_iterator(const self_type &aOther)
bool operator<=(const self_type &aOther) const
random_access_const_iterator(const iterator< T, Category, Difference, T *, T & > &aOther)
bool operator<(const self_type &aOther) const
self_type operator-(difference_type aDifference) const
bool operator>=(const self_type &aOther) const
self_type operator+(difference_type aDifference) const
difference_type operator-(const self_type &aOther) const
random_access_const_iterator(abstract_iterator *aWrappedIterator)
self_type & operator=(const self_type &aOther)
self_type & operator=(const iterator< T, Category, Difference, T *, T & > &aOther)
random_access_const_iterator(const i_random_access_iterator< T, Category, Difference, T *, T & > &aOther)
reference operator[](difference_type aDifference) const
self_type & operator=(const i_random_access_iterator< T, Category, Difference, T *, T & > &aOther)
bool operator>(const self_type &aOther) const
i_random_access_const_iterator< T, Category, Difference, Pointer, Reference > abstract_type
abstract_iterator & operator+=(difference_type aDifference)
abstract_iterator & wrapped_iterator() const
abstract_iterator & operator-=(difference_type aDifference)
difference_type operator-(const self_type &aOther) const
bool operator>(const self_type &aOther) const
abstract_iterator & operator-=(difference_type aDifference)
reference operator[](difference_type aDifference) const
i_random_access_const_iterator< T, Category, Difference, const T *, const T & > abstract_const_iterator
self_type & operator=(const self_type &aOther)
random_access_iterator(abstract_iterator *aWrappedIterator)
bool operator>=(const self_type &aOther) const
self_type operator+(difference_type aDifference) const
random_access_iterator(const self_type &aOther)
abstract_iterator & operator+=(difference_type aDifference)
bool operator<(const self_type &aOther) const
bool operator<=(const self_type &aOther) const
self_type operator-(difference_type aDifference) const
abstract_iterator & wrapped_iterator() const
i_random_access_iterator< T, Category, Difference, Pointer, Reference > abstract_type