neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
container_iterator.hpp
Go to the documentation of this file.
1// 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>
41
42namespace neolib
43{
44 namespace container
45 {
46 struct pure_iterator : std::logic_error { pure_iterator() : std::logic_error{ "neolib iterator is pure" } {} };
47
48 template <typename, typename, typename, typename>
49 class iterator;
50
51 template <typename T, typename ContainerIterator, typename AbstractIterator = i_const_iterator<abstract_t<T>>>
52 class const_iterator : public reference_counted<AbstractIterator, false>
53 {
56 public:
57 typedef AbstractIterator abstract_type;
58 public:
59 typedef const T value_type;
61 typedef ContainerIterator container_iterator;
62 using typename base_type::difference_type;
63 using typename base_type::pointer;
64 using typename base_type::reference;
65 using typename base_type::abstract_iterator;
66 using typename base_type::abstract_const_iterator;
67 using typename base_type::abstract_base_iterator;
68 using typename base_type::abstract_base_const_iterator;
69 public:
71 const_iterator(container_iterator aContainerIterator) : iContainerIterator(aContainerIterator) {}
72 const_iterator(const self_type& aOther) : iContainerIterator(aOther.iContainerIterator) {}
73 template <typename ContainerIterator2, typename AbstractIterator2>
75 template <typename ContainerIterator2, typename ContainerConstIterator, typename AbstractIterator2>
77 public:
78 const_iterator& operator=(const self_type& aOther) { iContainerIterator = aOther.iContainerIterator; return *this; }
79 template <typename ContainerIterator2, typename ContainerConstIterator, typename AbstractIterator2>
81 public:
82 operator container_iterator() const { return iContainerIterator; }
83 public:
84 abstract_iterator& operator++() override { ++iContainerIterator; return *this; }
85 abstract_iterator& operator--() override { --iContainerIterator; return *this; }
86 reference operator*() const override { return to_abstract(*iContainerIterator); }
87 pointer operator->() const override { return &(**this); }
88 bool operator==(const abstract_base_iterator& aOther) const override { return iContainerIterator == static_cast<const self_type&>(aOther).iContainerIterator; }
89 bool operator!=(const abstract_base_iterator& aOther) const override { return iContainerIterator != static_cast<const self_type&>(aOther).iContainerIterator; }
90 public:
91 abstract_iterator* clone(void* memory) const override { if constexpr (!std::is_abstract_v<self_type>) return new (memory) self_type{ iContainerIterator }; else throw pure_iterator(); }
92 private:
93 abstract_iterator* do_post_increment(void* memory) override { if constexpr (!std::is_abstract_v<self_type>) return new (memory) self_type{ iContainerIterator++ }; else throw pure_iterator(); }
94 abstract_iterator* do_post_decrement(void* memory) override { if constexpr (!std::is_abstract_v<self_type>) return new (memory) self_type{ iContainerIterator-- }; else throw pure_iterator(); }
95 protected:
97 };
98
99 template <typename, typename, typename>
101
102 template <typename T, typename ContainerIterator>
103 class random_access_const_iterator : public const_iterator<T, ContainerIterator, i_random_access_const_iterator<abstract_t<T>>>
104 {
107 public:
108 using typename base_type::abstract_type;
109 using typename base_type::value_type;
110 using typename base_type::abstract_value_type;
111 using typename base_type::container_iterator;
112 using typename base_type::difference_type;
113 using typename base_type::pointer;
114 using typename base_type::reference;
115 using typename base_type::abstract_iterator;
116 using typename base_type::abstract_const_iterator;
117 using typename base_type::abstract_base_iterator;
118 using typename base_type::abstract_base_const_iterator;
119 using typename base_type::abstract_random_access_iterator;
120 using typename base_type::abstract_random_access_const_iterator;
121 public:
123 random_access_const_iterator(container_iterator aContainerIterator) : base_type(aContainerIterator) {}
125 template <typename ContainerIterator2>
127 template <typename ContainerIterator2, typename ContainerConstIterator>
129 public:
130 random_access_const_iterator& operator=(const self_type& aOther) { base_type::operator=(aOther); return *this; }
131 template <typename ContainerIterator2, typename ContainerConstIterator>
133 public:
135 public:
136 abstract_iterator& operator+=(difference_type aDifference) override { base_type::iContainerIterator += aDifference; return *this; }
137 abstract_iterator& operator-=(difference_type aDifference) override { base_type::iContainerIterator -= aDifference; return *this; }
138 reference operator[](difference_type aDifference) const override { return base_type::iContainerIterator[aDifference]; }
139 difference_type operator-(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator - static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
140 bool operator<(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator < static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
141 bool operator<=(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator <= static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
142 bool operator>(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator > static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
143 bool operator>=(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator >= static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
144 public:
145 abstract_iterator* clone(void* memory) const override { return new (memory) self_type{ base_type::iContainerIterator }; }
146 private:
147 abstract_iterator* do_post_increment(void* memory) override { return new (memory) self_type{ base_type::iContainerIterator++ }; }
148 abstract_iterator* do_post_decrement(void* memory) override { return new (memory) self_type{ base_type::iContainerIterator-- }; }
149 abstract_random_access_iterator* do_add(void* memory, difference_type aDifference) const override { return new (memory) self_type{ base_type::iContainerIterator + aDifference }; }
150 abstract_random_access_iterator* do_subtract(void* memory, difference_type aDifference) const override { return new (memory) self_type{ base_type::iContainerIterator - aDifference }; }
151 };
152
153 template <typename T, typename ContainerIterator, typename ContainerConstIterator, typename AbstractIterator = i_iterator<abstract_t<T>>>
154 class iterator : public reference_counted<AbstractIterator, false>
155 {
158 template <typename, typename, typename>
159 friend class const_iterator;
160 public:
161 typedef AbstractIterator abstract_type;
162 typedef T value_type;
164 typedef ContainerIterator container_iterator;
165 typedef ContainerConstIterator container_const_iterator;
166 using typename base_type::difference_type;
167 using typename base_type::pointer;
168 using typename base_type::reference;
169 using typename base_type::abstract_iterator;
170 using typename base_type::abstract_const_iterator;
171 using typename base_type::abstract_base_iterator;
172 using typename base_type::abstract_base_const_iterator;
173 public:
175 iterator(container_iterator aContainerIterator) : iContainerIterator(aContainerIterator) {}
177 iterator& operator=(const iterator& aOther) { iContainerIterator = aOther.iContainerIterator; return *this; }
178 public:
179 operator container_iterator() const { return iContainerIterator; }
180 public:
181 abstract_iterator& operator++() override { ++iContainerIterator; return *this; }
182 abstract_iterator& operator--() override { --iContainerIterator; return *this; }
183 reference operator*() const override { return to_abstract(*iContainerIterator); }
184 pointer operator->() const override { return &(**this); }
185 bool operator==(const abstract_base_iterator& aOther) const override { return iContainerIterator == static_cast<const self_type&>(aOther).iContainerIterator; }
186 bool operator!=(const abstract_base_iterator& aOther) const override { return iContainerIterator != static_cast<const self_type&>(aOther).iContainerIterator; }
187 public:
188 abstract_iterator* clone(void* memory) const override { if constexpr (!std::is_abstract_v<self_type>) return new (memory) self_type{ iContainerIterator }; else throw pure_iterator(); }
189 abstract_const_iterator* const_clone(void* memory) const override { if constexpr (!std::is_abstract_v<self_type>) return new (memory) const_iterator<T, container_const_iterator, abstract_const_iterator>{ *this }; else throw pure_iterator(); }
190 private:
191 abstract_iterator* do_post_increment(void* memory) override { if constexpr (!std::is_abstract_v<self_type>) return new (memory) self_type{ iContainerIterator++ }; else throw pure_iterator(); }
192 abstract_iterator* do_post_decrement(void* memory) override { if constexpr (!std::is_abstract_v<self_type>) return new (memory) self_type{ iContainerIterator-- }; else throw pure_iterator(); }
193 protected:
195 };
196
197 template <typename T, typename ContainerIterator, typename ContainerConstIterator>
198 class random_access_iterator : public iterator<T, ContainerIterator, ContainerConstIterator, i_random_access_iterator<abstract_t<T>>>
199 {
202 template <typename, typename>
204 public:
205 using typename base_type::abstract_type;
206 using typename base_type::value_type;
207 using typename base_type::abstract_value_type;
208 using typename base_type::container_iterator;
210 using typename base_type::difference_type;
211 using typename base_type::pointer;
212 using typename base_type::reference;
213 using typename base_type::abstract_iterator;
214 using typename base_type::abstract_const_iterator;
215 using typename base_type::abstract_base_iterator;
216 using typename base_type::abstract_base_const_iterator;
217 using typename base_type::abstract_random_access_iterator;
218 using typename base_type::abstract_random_access_const_iterator;
219 public:
221 random_access_iterator(container_iterator aContainerIterator) : base_type{ aContainerIterator } {}
224 public:
225 abstract_iterator& operator+=(difference_type aDifference) override { base_type::iContainerIterator += aDifference; return *this; }
226 abstract_iterator& operator-=(difference_type aDifference) override { base_type::iContainerIterator -= aDifference; return *this; }
227 reference operator[](difference_type aDifference) const override { return base_type::iContainerIterator[aDifference]; }
228 difference_type operator-(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator - static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
229 bool operator<(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator < static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
230 bool operator<=(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator <= static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
231 bool operator>(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator > static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
232 bool operator>=(const abstract_random_access_iterator& aOther) const override { return base_type::iContainerIterator >= static_cast<const self_type&>(aOther).base_type::iContainerIterator; }
233 public:
234 abstract_random_access_iterator* clone(void* memory) const override { return new (memory) self_type{ base_type::iContainerIterator }; }
235 abstract_random_access_const_iterator* const_clone(void* memory) const override { return new (memory) random_access_const_iterator<T, ContainerConstIterator>{ *this }; }
236 private:
237 abstract_random_access_iterator* do_add(void* memory, difference_type aDifference) const override { return new (memory) self_type{ base_type::iContainerIterator + aDifference }; }
238 abstract_random_access_iterator* do_subtract(void* memory, difference_type aDifference) const override { return new (memory) self_type{ base_type::iContainerIterator - aDifference }; }
239 };
240 }
241}
bool operator==(const abstract_base_iterator &aOther) const override
const_iterator(const iterator< T, ContainerIterator2, ContainerConstIterator, AbstractIterator2 > &aOther)
const_iterator(container_iterator aContainerIterator)
bool operator!=(const abstract_base_iterator &aOther) const override
const_iterator & operator=(const self_type &aOther)
abstract_iterator & operator++() override
abstract_iterator & operator--() override
const_iterator(const self_type &aOther)
const_iterator(const const_iterator< T, ContainerIterator2, AbstractIterator2 > &aOther)
abstract_iterator * clone(void *memory) const override
reference operator*() const override
const_iterator & operator=(const iterator< T, ContainerIterator2, ContainerConstIterator, AbstractIterator2 > &aOther)
bool operator==(const abstract_base_iterator &aOther) const override
abstract_iterator & operator++() override
bool operator!=(const abstract_base_iterator &aOther) const override
iterator(container_iterator aContainerIterator)
abstract_iterator * clone(void *memory) const override
abstract_iterator & operator--() override
iterator & operator=(const iterator &aOther)
pointer operator->() const override
abstract_const_iterator * const_clone(void *memory) const override
ContainerConstIterator container_const_iterator
reference operator*() const override
iterator(const iterator &aOther)
abstract_iterator & operator+=(difference_type aDifference) override
difference_type operator-(const abstract_random_access_iterator &aOther) const override
abstract_iterator & operator-=(difference_type aDifference) override
bool operator>=(const abstract_random_access_iterator &aOther) const override
bool operator<=(const abstract_random_access_iterator &aOther) const override
bool operator<(const abstract_random_access_iterator &aOther) const override
random_access_const_iterator(container_iterator aContainerIterator)
random_access_const_iterator(const random_access_iterator< T, ContainerIterator2, ContainerConstIterator > &aOther)
reference operator[](difference_type aDifference) const override
random_access_const_iterator(const random_access_const_iterator< T, ContainerIterator2 > &aOther)
random_access_const_iterator & operator=(const self_type &aOther)
bool operator>(const abstract_random_access_iterator &aOther) const override
random_access_const_iterator & operator=(const random_access_iterator< T, ContainerIterator2, ContainerConstIterator > &aOther)
abstract_iterator * clone(void *memory) const override
bool operator>(const abstract_random_access_iterator &aOther) const override
difference_type operator-(const abstract_random_access_iterator &aOther) const override
bool operator<=(const abstract_random_access_iterator &aOther) const override
abstract_iterator & operator+=(difference_type aDifference) override
abstract_iterator & operator-=(difference_type aDifference) override
random_access_iterator(container_iterator aContainerIterator)
abstract_random_access_const_iterator * const_clone(void *memory) const override
random_access_iterator & operator=(const random_access_iterator &aOther)
reference operator[](difference_type aDifference) const override
random_access_iterator(const random_access_iterator &aOther)
bool operator<(const abstract_random_access_iterator &aOther) const override
bool operator>=(const abstract_random_access_iterator &aOther) const override
abstract_random_access_iterator * clone(void *memory) const override
typename detail::abstract_type< T >::type abstract_t
Definition neolib.hpp:178
const abstract_t< T > & to_abstract(const T &aArgument)
Definition neolib.hpp:181