IEnumerable.h
1
26
27#ifndef COSMO_ENUMERABLE_INTERFACE_H
28#define COSMO_ENUMERABLE_INTERFACE_H
29
30#include <Pt/Cosmo/AutoPtr.h>
31#include <Pt/Cosmo/IAutoReleasePool.h>
32#include <utility>
33
34namespace Pt {
35
36namespace Cosmo {
37
39
40template <typename T>
41class IEnumeration;
42
43class EnumeratorBase;
44
45template <typename T>
46class Enumerator;
47
56template <typename T>
58{
59 public:
60 virtual ~IEnumerable()
61 { }
62
63 Enumerator<T> enumerate() const
64 {
65 return onEnumerate();
66 }
67
68 protected:
69 virtual Enumerator<T> onEnumerate() const = 0;
70};
71
72
73template <typename T>
74Enumerator<T> begin(const IEnumerable<T>& e)
75{
76 return e.enumerate();
77}
78
79
80template <typename T>
81Enumerator<T> end(const IEnumerable<T>& e)
82{
83 return Enumerator<T>();
84}
85
91{
92 public:
93 virtual ~IEnumerationBase()
94 {}
95
96 bool isValid() const
97 {
98 return onIsValid();
99 }
100
101 void advance()
102 {
103 return onAdvance();
104 }
105
106 protected:
107 virtual bool onIsValid() const = 0;
108
109 virtual void onAdvance() = 0;
110};
111
116template <typename T>
118{
119 public:
120 typedef T Value;
121 typedef const T& Reference;
122
123 public:
124 virtual ~IEnumeration()
125 {}
126
127 const T& get() const
128 {
129 return onGet();
130 }
131
132 protected:
133 virtual const T& onGet() const = 0;
134};
135
138template <typename T>
140{
141 public:
142 typedef T* Value;
143 typedef const T* Reference;
144
145 public:
146 virtual ~IEnumeration()
147 {}
148
149 const T* get() const
150 {
151 return onGet();
152 }
153
154 protected:
155 virtual const T* onGet() const = 0;
156};
157
160class EnumeratorBase : public AutoReleasable
161{
162 public:
163 EnumeratorBase()
164 : AutoReleasable()
165 , _e(&_invalid)
166 , _res()
167 { }
168
169 EnumeratorBase(IAutoReleasePool& pool,
171 : AutoReleasable(pool)
172 , _e(&_invalid)
173 , _res(e)
174 {
175 if(e)
176 _e = e;
177 }
178
179 template <typename Enumeration, typename Deleter>
180 EnumeratorBase(IAutoReleasePool& pool,
181 Enumeration* e,
182 Deleter d)
183 : AutoReleasable(pool)
184 , _e(&_invalid)
185 , _res(e, d)
186 {
187 if(e)
188 _e = e;
189 }
190
191 EnumeratorBase(EnumeratorBase&& other) noexcept
192 : AutoReleasable( std::move(other) )
193 , _e(&_invalid)
194 , _res( std::move(other._res) )
195 {
196 if(other._e == &other._invalid)
197 _e = &_invalid;
198 else
199 _e = other._e;
200 }
201
202 virtual ~EnumeratorBase()
203 { }
204
205 EnumeratorBase& operator=(EnumeratorBase&& other) noexcept
206 {
207 if(this == &other)
208 return *this;
209
210 if(other._e == &other._invalid)
211 _e = &_invalid;
212 else
213 _e = other._e;
214
215 _res = std::move(other._res);
216
217 return *this;
218 }
219
220 bool isValid() const
221 {
222 return _e->isValid();
223 }
224
225 void advance()
226 {
227 _e->advance();
228 }
229
230 explicit operator bool() const
231 {
232 return this->isValid();
233 }
234
235 bool operator !() const
236 {
237 return ! this->isValid();
238 }
239
240 bool operator ==(const EnumeratorBase& other) const
241 {
242 return ! operator !=(other);
243 }
244
245 bool operator !=(const EnumeratorBase& other) const
246 {
247 const bool isValid = this->isValid() || other.isValid();
248 return _e != other._e && isValid;
249 }
250
251 protected:
252 virtual void onRelease() override
253 {
254 _e = &_invalid;
255 _res.reset();
256 }
257
258 private:
259 EnumeratorBase(const EnumeratorBase& other) = delete;
260
261 EnumeratorBase& operator=(const EnumeratorBase& other) = delete;
262
263 private:
264 class Invalid : public IEnumerationBase
265 {
266 protected:
267 virtual bool onIsValid() const
268 { return false; }
269
270 virtual void onAdvance()
271 { }
272 } _invalid;
273
274 private:
277};
278
281template <typename T>
282class Enumerator : public EnumeratorBase
283{
284 public:
285 template <typename P>
286 struct Proxy
287 {
288 typedef const P& Reference;
289
290 Proxy(IEnumeration<T>& e)
291 : _ref(&e.get() )
292 { }
293
294 const P& operator*() const
295 {
296 return _ref;
297 }
298
299 const P& _ref;
300 };
301
302 template <typename P>
303 struct Proxy<P*>
304 {
305 typedef const P* Reference;
306
307 Proxy(IEnumeration<T>& e)
308 : _ptr( e.get() )
309 { }
310
311 const P* operator*() const
312 {
313 return _ptr;
314 }
315
316 const P* _ptr;
317 };
318
319 typedef long difference_type;
320 typedef typename Proxy<T>::Reference Reference;
321
322 public:
323 Enumerator()
324 : _e(0)
325 { }
326
327 Enumerator(IAutoReleasePool& pool,
329 : EnumeratorBase(pool, e)
330 , _e(e)
331 { }
332
333 template <typename Enumeration, typename Deleter>
334 Enumerator(IAutoReleasePool& pool,
335 Enumeration* e,
336 Deleter d)
337 : EnumeratorBase(pool, e, d)
338 , _e(e)
339 { }
340
341 Enumerator(Enumerator&& other) noexcept
342 : EnumeratorBase( std::move(other) )
343 , _e(0)
344 {
345 _e = other._e;
346 }
347
348 Enumerator& operator=(Enumerator&& other) noexcept
349 {
350 _e = other._e;
351 EnumeratorBase::operator=(other);
352 return *this;
353 }
354
355 ~Enumerator()
356 { }
357
358 Reference get() const
359 {
360 return _e->get();
361 }
362
363 Reference operator*() const
364 {
365 return get();
366 }
367
368 const T* operator->() const
369 {
370 return &get();
371 }
372
373 Enumerator& operator++()
374 {
375 advance();
376 return *this;
377 }
378
379 Proxy<T> operator++(int)
380 {
381 Proxy<T> r(*_e);
382 advance();
383 return r;
384 }
385
386 protected:
387 virtual void onRelease() override
388 {
389 _e = 0;
390 EnumeratorBase::onRelease();
391 }
392
393 private:
394 IEnumeration<T>* _e;
395};
396
397} // namespace Cosmo
398
399} // namespace Pt
400
401#endif // include guard
Owning smart pointer.
Definition AutoPtr.h:123
Enumerator for IEnumerables.
Definition IEnumerable.h:161
Enumerator for IEnumerables.
Definition IEnumerable.h:283
Auto-release pool interface.
Definition IAutoReleasePool.h:46
Enumerable interface.
Definition IEnumerable.h:58
Enumerator base implementation.
Definition IEnumerable.h:91
Enumerator implementation.
Definition IEnumerable.h:118
Cosmo Component Model.
Definition Api.h:53
Core module.
Definition Allocator.h:33