PLCnext API Documentation 23.0.2.9
Enumerator.hxx
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Core/IEnumerator.hxx"
9#include "Arp/System/Core/Exception.hpp"
10#include <stack>
11namespace Arp
12{
13
20template<class T>
21class Enumerator : public IEnumerator<T>
22{
23public: // nested class Empty
26 class Empty : public IEnumerator<T>
27 {
28 public: // construction/destruction
30 Empty(void) = default;
33 Empty(const Empty& arg) = default;
37 Empty& operator=(const Empty& arg) = default;
39 virtual ~Empty(void) = default;
40
41 public: // overridden operations
42 bool MoveNext(void)override;
43 T GetCurrent(void)override;
44 };
45
46public: // nested class Composite
52 class Composite : public IEnumerator<T>
53 {
54 public: // construction/destruction
58 Composite(typename IEnumerator<T>::Ptr first, typename IEnumerator<T>::Ptr second);
61 Composite(const Composite& arg) = default;
65 Composite& operator=(const Composite& arg) = default;
67 virtual ~Composite(void) = default;
68
69 public: // overridden operations
70 // inherited doc
71 bool MoveNext(void)override;
72 // inherited doc
73 T GetCurrent(void)override;
74
75 private: // fields
76 typename IEnumerator<T>::Ptr first;
77 typename IEnumerator<T>::Ptr second;
78 };
79
80public: // nested class StackComposite
82 class StackComposite : public IEnumerator<T>
83 {
84 private: // usings/typdefs
85 using Stack = std::stack<typename IEnumerator<T>::Ptr>;
86
87 public: // construction/destruction
89 StackComposite(void) = default;
92 StackComposite(const StackComposite& arg) = default;
96 StackComposite& operator=(const StackComposite& arg) = default;
98 virtual ~StackComposite(void) = default;
99
100 public: // overridden operations
101 // inherited doc
102 bool MoveNext(void)override;
103 // inherited doc
104 T GetCurrent(void)override;
105
106 public: // operations
109 void Push(typename IEnumerator<T>::Ptr e);
112 size_t GetSize() const;
113
114 private: // fields
115 Stack enumerators;
116 };
117
118private:
119 template<class Iterator>
120 class IteratorAdapters
121 {
122 friend class Enumerator;
123
124 struct Value
125 {
126 typename Iterator::reference operator()(Iterator i)const
127 {
128 return *i;
129 }
130 };
131 struct ConstKey
132 {
133 const typename Iterator::value_type::first_type& operator()(Iterator i)const
134 {
135 return i->first;
136 }
137 };
138 struct Mapped
139 {
140 typename Iterator::value_type::second_type& operator()(Iterator i)const
141 {
142 return i->second;
143 }
144 };
145 struct ConstMapped
146 {
147 const typename Iterator::value_type::second_type& operator()(Iterator i)const
148 {
149 return i->second;
150 }
151 };
152 };
153
154public:
159 template<class Iterator, class IteratorAdapter = typename IteratorAdapters<Iterator>::Value>
160 class StlAdapter : public IEnumerator<T>
161 {
162 public: // construction/destruction
166 StlAdapter(Iterator begin, Iterator end);
169 StlAdapter(const StlAdapter& arg) = default;
173 StlAdapter& operator=(const StlAdapter& arg) = default;
175 virtual ~StlAdapter(void) = default;
176
177 public: // overridden operations
178 // inherited doc
179 bool MoveNext(void)override;
180 // inherited doc
181 T GetCurrent(void)override;
182
183 private: // fields
184 Iterator begin;
185 Iterator end;
186 bool firstMove = true;
187 IteratorAdapter iteratorAdapter;
188 };
189
190private:
193 template<class Predicate>
194 class FilterEnumerator : public IEnumerator<T>
195 {
196 public: // construction/destruction
200 FilterEnumerator(typename IEnumerator<T>::Ptr source, Predicate predicate);
201
202 public: // overridden operations
203 // inherited doc
204 bool MoveNext(void)override;
205 // inherited doc
206 T GetCurrent(void)override;
207
208 private: // fields
209 typename IEnumerator<T>::Ptr source;
210 Predicate predicate;
211 };
212
213private:
216 template<typename SourceEnumerator, typename TransformOperation>
217 class TransformEnumerator : public Arp::IEnumerator<T>
218 {
219 public:
221 using Source = SourceEnumerator;
222
226 TransformEnumerator(std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp);
227
228 bool MoveNext() override;
229 T GetCurrent() override;
230
231 private:
232 std::shared_ptr<SourceEnumerator> source;
233 TransformOperation transformOp;
234 };
235
236
237public: // construction/destruction
239 Enumerator(void) = default;
242 Enumerator(const Enumerator& arg) = default;
246 Enumerator& operator=(const Enumerator& arg) = default;
248 virtual ~Enumerator(void) = default;
249
250public: // static fields
252 static Empty Null;
253
254public: // static facrory operations
257 static typename IEnumerator<T>::Ptr CreateEmpty(void);
258
270 static typename IEnumerator<T>::Ptr CreateComposite(typename IEnumerator<T>::Ptr first, typename IEnumerator<T>::Ptr second);
271
277 template<class TIterator>
278 static typename IEnumerator<T>::Ptr CreateStlAdapter(TIterator begin, TIterator end);
279
284 template<class TContainer>
285 static typename IEnumerator<T>::Ptr CreateStlAdapter(TContainer& c);
286
291 template<class TContainer>
292 static typename IEnumerator<T>::Ptr CreateKeysAdapter(TContainer& c);
293
298 template<class TContainer>
299 static typename IEnumerator<T>::Ptr CreateKeysAdapter(const TContainer& c);
300
305 template<class TContainer>
306 static typename IEnumerator<T>::Ptr CreateMappedAdapter(TContainer& c);
307
312 template<class TContainer>
313 static typename IEnumerator<T>::Ptr CreateMappedAdapter(const TContainer& c);
314
320 template<class Predicate>
321 static typename IEnumerator<T>::Ptr CreateFilter(typename IEnumerator<T>::Ptr source, Predicate predicate);
322
329 template<class SourceEnumerator, class TransformOperation>
330 static typename IEnumerator<T>::Ptr CreateTransform(std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp);
331
332
333public: // abstract/overridden operations inherited from IEnumerator
334 // inherited doc
335 virtual bool MoveNext(void) = 0;
336 // inherited doc
337 T GetCurrent(void)override;
338
339private: // usings
340 using TCurrent = typename std::remove_const<typename std::remove_reference<T>::type>::type;
341
342protected:
343 TCurrent current;
344};
345
347// inline methods of class Enumerator<T>::Empty
348template<class T>
350{
351 return false;
352}
353
354template<class T>
356{
357 throw Exception("IEnumerator::GetCurrent() is not supported by empty enumerators");
358}
359
361// inline methods of class Enumerator<T>::Composite
362template<class T>
364 : first(first)
365 , second(second)
366{
367}
368
369template<class T>
371{
372 if (this->first)
373 {
374 if (this->first->MoveNext())
375 {
376 return true;
377 }
378 // else
379 this->first.reset();
380 }
381 return this->second->MoveNext();
382}
383
384template<class T>
386{
387 if (this->first)
388 {
389 return this->first->GetCurrent();
390 }
391 // else
392 return this->second->GetCurrent();
393}
394
396// inline methods of class Enumerator<T>::StackComposite
397template<class T>
399{
400 this->enumerators.push(e);
401}
402
403template<class T>
405{
406 while (!this->enumerators.empty())
407 {
408 if (this->enumerators.top()->MoveNext())
409 {
410 return true;
411 }
412 // else must pop last enumerator
413 this->enumerators.pop();
414 }
415 // reaching this point means stack is empty
416 return false;
417}
418
419template<class T>
421{
422 return this->enumerators.top()->GetCurrent();
423}
424
425template<class T>
427{
428 return this->enumerators.size();
429}
430
432// inline methods of class Enumerator<T>::StlAdapter
433template<class T>
434template<class Iterator, class IteratorAdapter>
436 : begin(begin)
437 , end(end)
438 , iteratorAdapter()
439{
440}
441
442template<class T>
443template<class Iterator, class IteratorAdapter>
445{
446 if (this->firstMove)
447 {
448 this->firstMove = false;
449 return this->begin != this->end;
450 }
451 // else
452 return ++this->begin != this->end;
453}
454
455template<class T>
456template<class Iterator, class IteratorAdapter>
458{
459 return this->iteratorAdapter(this->begin);
460}
461
463// inline methods of class Enumerator<T>::FilterEnumerator
464template<class T>
465template<class Predicate>
467 typename IEnumerator<T>::Ptr source, Predicate predicate)
468 : source(std::move(source)), predicate(std::move(predicate))
469{
470}
471
472
473template<class T>
474template<class Predicate>
476{
477 while (this->source->MoveNext())
478 {
479 if (this->predicate(this->source->GetCurrent()))
480 {
481 return true;
482 }
483 }
484 return false;
485}
486
487
488template<class T>
489template<class Predicate>
491{
492 return this->source->GetCurrent();
493}
494
496// inline methods of class Enumerator<T>::TransformEnumerator
497template<class T>
498template<class SourceEnumerator, class TransformOperation>
499Enumerator<T>::TransformEnumerator<SourceEnumerator, TransformOperation>::TransformEnumerator(
500 std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp)
501 : source(std::move(source)), transformOp(std::move(transformOp))
502{
503}
504
505
506template<class T>
507template<class SourceEnumerator, class TransformOperation>
509{
510 return this->source->MoveNext();
511}
512
513
514template<class T>
515template<class SourceEnumerator, class TransformOperation>
517{
518 return this->transformOp(this->source->GetCurrent());
519}
520
521
523// inline methods of class Enumerator<T>
524template<class T>
526{
527 return this->current;
528}
529
530template<class T>
532{
533 return std::make_shared<Empty>();
534}
535
536template<class T>
538{
539 return std::make_shared<Composite>(first, second);
540}
541
542template<class T>
543template<class TIterator>
544inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateStlAdapter(TIterator begin, TIterator end)
545{
546 return std::make_shared<StlAdapter<TIterator>>(begin, end);
547}
548
549template<class T>
550template<class TContainer>
552{
553 return CreateStlAdapter(c.begin(), c.end());
554}
555
556template<class T>
557template<class TContainer>
559{
560 return std::make_shared<StlAdapter<typename TContainer::iterator, typename IteratorAdapters<typename TContainer::iterator>::ConstKey>>(c.begin(), c.end());
561}
562
563template<class T>
564template<class TContainer>
565inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateKeysAdapter(const TContainer& c)
566{
567 return std::make_shared<StlAdapter<typename TContainer::const_iterator, typename IteratorAdapters<typename TContainer::const_iterator>::ConstKey>>(c.begin(), c.end());
568}
569
570template<class T>
571template<class TContainer>
573{
574 return std::make_shared<StlAdapter<typename TContainer::iterator, typename IteratorAdapters<typename TContainer::iterator>::Mapped>>(c.begin(), c.end());
575}
576
577template<class T>
578template<class TContainer>
579inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateMappedAdapter(const TContainer& c)
580{
581 return std::make_shared<StlAdapter<typename TContainer::const_iterator, typename IteratorAdapters<typename TContainer::const_iterator>::ConstMapped>>(c.begin(), c.end());
582}
583
584template<class T>
585template<class Predicate>
587 typename IEnumerator<T>::Ptr source, Predicate predicate)
588{
589 return std::make_shared<Enumerator<T>::FilterEnumerator<Predicate>>(std::move(source), predicate);
590}
591
592template<class T>
593template<class SourceEnumerator, class TransformOperation>
594inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateTransform(std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp)
595{
596 return std::make_shared<Enumerator<T>::TransformEnumerator<SourceEnumerator, TransformOperation>>(
597 std::move(source), transformOp);
598}
599
601// Initializing of static fields of class Enumerator<T>
602template<class T>
604
605} // end of namespace Arp
Use this class to build a single enumerator by two given enumerator, e.g. to enumerate multiple conta...
Definition: Enumerator.hxx:53
Composite(typename IEnumerator< T >::Ptr first, typename IEnumerator< T >::Ptr second)
Constructs an Composite instance.
Definition: Enumerator.hxx:363
Composite(const Composite &arg)=default
Copy constructor.
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:370
virtual ~Composite(void)=default
Destructs this instance and frees all resources.
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:385
Composite & operator=(const Composite &arg)=default
Assignment operator.
Implements an empty enumerator, that is, the first call of MoveNext() will return false.
Definition: Enumerator.hxx:27
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:349
Empty & operator=(const Empty &arg)=default
Assignment operator.
virtual ~Empty(void)=default
Destructs this instance and frees all resources.
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:355
Empty(const Empty &arg)=default
Copy constructor.
Empty(void)=default
Constructs an Empty instance.
Use this class to build a single enumerator by two given enumerator, e.g. to enumerate multiple conta...
Definition: Enumerator.hxx:83
void Push(typename IEnumerator< T >::Ptr e)
Adds the as argument passed enumerator to this stack.
Definition: Enumerator.hxx:398
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:404
StackComposite(void)=default
Constructs an StackComposite instance.
virtual ~StackComposite(void)=default
Destructs this instance and frees all resources.
size_t GetSize() const
Get the size of this stack.
Definition: Enumerator.hxx:426
StackComposite(const StackComposite &arg)=default
Copy constructor.
StackComposite & operator=(const StackComposite &arg)=default
Assignment operator.
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:420
This class implements an enumerator adapter for STL container based on iterators.
Definition: Enumerator.hxx:161
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:444
StlAdapter & operator=(const StlAdapter &arg)=default
Assignment operator.
StlAdapter(Iterator begin, Iterator end)
Constructs an StlAdapter instance.
Definition: Enumerator.hxx:435
virtual ~StlAdapter(void)=default
Destructs this instance and frees all resources.
StlAdapter(const StlAdapter &arg)=default
Copy constructor.
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:457
This class defines a base class for all enumerator implementations and some predefined enumerators as...
Definition: Enumerator.hxx:22
virtual bool MoveNext(void)=0
Moves this enumerator to the next position.
TCurrent current
The current field of this enumerator.
Definition: Enumerator.hxx:343
static IEnumerator< T >::Ptr CreateTransform(std::shared_ptr< SourceEnumerator > source, TransformOperation transformOp)
Creates a transforming adapter enumerating applying a transform operation to each element.
Definition: Enumerator.hxx:594
static IEnumerator< T >::Ptr CreateKeysAdapter(const TContainer &c)
Creates an enumerator adapter from the given const STL map enumerating the keys.
Definition: Enumerator.hxx:565
static IEnumerator< T >::Ptr CreateMappedAdapter(const TContainer &c)
Creates an enumerator adapter from the given const STL map enumerating the mapped items.
Definition: Enumerator.hxx:579
Enumerator(void)=default
Constructs an Enumerator instance.
static IEnumerator< T >::Ptr CreateKeysAdapter(TContainer &c)
Creates an enumerator adapter from the given STL map enumerating the keys.
Definition: Enumerator.hxx:558
virtual ~Enumerator(void)=default
Destructs this instance and frees all resources.
static IEnumerator< T >::Ptr CreateEmpty(void)
Creates an empty enumerator.
Definition: Enumerator.hxx:531
static Empty Null
A static empty enumerator instance.
Definition: Enumerator.hxx:252
static IEnumerator< T >::Ptr CreateMappedAdapter(TContainer &c)
Creates an enumerator adapter from the given STL map enumerating the mapped items.
Definition: Enumerator.hxx:572
static IEnumerator< T >::Ptr CreateStlAdapter(TIterator begin, TIterator end)
Creates an enumerator adapter from the given STL iterators.
Definition: Enumerator.hxx:544
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:525
Enumerator & operator=(const Enumerator &arg)=default
Assignment operator.
static IEnumerator< T >::Ptr CreateComposite(typename IEnumerator< T >::Ptr first, typename IEnumerator< T >::Ptr second)
Creates a composite enumerator from the two given enumerators, e.g. to enumerate trees easily.
Definition: Enumerator.hxx:537
static IEnumerator< T >::Ptr CreateStlAdapter(TContainer &c)
Creates an enumerator adapter from the given STL container.
Definition: Enumerator.hxx:551
static IEnumerator< T >::Ptr CreateFilter(typename IEnumerator< T >::Ptr source, Predicate predicate)
Creates a filtering adapter enumerating only the nodes matching a given predicate.
Definition: Enumerator.hxx:586
Enumerator(const Enumerator &arg)=default
Copy constructor.
This is the base class of all Arp exception classes.
Definition: Exception.hpp:16
Declares the interface of the enumerator pattern, which is leaned on .NET enumerator idiom.
Definition: IEnumerator.hxx:48
std::shared_ptr< IEnumerator > Ptr
The smart pointer tpye of this interface.
Definition: IEnumerator.hxx:51
Root namespace for the PLCnext API
Namespace of the C++ standard library