PLCnext API Documentation 25.0.2.69
Enumerator.hxx
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
7
8#ifndef ARP_USE_ARP_SYSTEM_CORE
9
10#include "Arp/Base/Core/Enumerator.hxx"
11
12#else
13
14#include "Arp/System/Core/Arp.h"
15#include "Arp/System/Core/IEnumerator.hxx"
16#include "Arp/System/Core/Exception.hpp"
17#include <stack>
18
19namespace Arp
20{
21
28template<class T>
29class Enumerator : public IEnumerator<T>
30{
31public: // nested class Empty
34 class Empty : public IEnumerator<T>
35 {
36 public: // construction/destruction
38 Empty(void) = default;
41 Empty(const Empty& arg) = default;
45 Empty& operator=(const Empty& arg) = default;
47 virtual ~Empty(void) = default;
48
49 public: // overridden operations
50 bool MoveNext(void)override;
51 T GetCurrent(void)override;
52 };
53
54public: // nested class Composite
60 class Composite : public IEnumerator<T>
61 {
62 public: // construction/destruction
66 Composite(typename IEnumerator<T>::Ptr first, typename IEnumerator<T>::Ptr second);
69 Composite(const Composite& arg) = default;
73 Composite& operator=(const Composite& arg) = default;
75 virtual ~Composite(void) = default;
76
77 public: // overridden operations
78 // inherited doc
79 bool MoveNext(void)override;
80 // inherited doc
81 T GetCurrent(void)override;
82
83 private: // fields
84 typename IEnumerator<T>::Ptr first;
85 typename IEnumerator<T>::Ptr second;
86 };
87
88public: // nested class StackComposite
90 class StackComposite : public IEnumerator<T>
91 {
92 private: // usings/typdefs
93 using Stack = std::stack<typename IEnumerator<T>::Ptr>;
94
95 public: // construction/destruction
97 StackComposite(void) = default;
100 StackComposite(const StackComposite& arg) = default;
104 StackComposite& operator=(const StackComposite& arg) = default;
106 virtual ~StackComposite(void) = default;
107
108 public: // overridden operations
109 // inherited doc
110 bool MoveNext(void)override;
111 // inherited doc
112 T GetCurrent(void)override;
113
114 public: // operations
117 void Push(typename IEnumerator<T>::Ptr e);
120 size_t GetSize() const;
121
122 private: // fields
123 Stack enumerators;
124 };
125
126private:
127 template<class Iterator>
128 class IteratorAdapters
129 {
130 friend class Enumerator;
131
132 struct Value
133 {
134 typename Iterator::reference operator()(Iterator i)const
135 {
136 return *i;
137 }
138 };
139 struct ConstKey
140 {
141 const typename Iterator::value_type::first_type& operator()(Iterator i)const
142 {
143 return i->first;
144 }
145 };
146 struct Mapped
147 {
148 typename Iterator::value_type::second_type& operator()(Iterator i)const
149 {
150 return i->second;
151 }
152 };
153 struct ConstMapped
154 {
155 const typename Iterator::value_type::second_type& operator()(Iterator i)const
156 {
157 return i->second;
158 }
159 };
160 };
161
162public:
167 template<class Iterator, class IteratorAdapter = typename IteratorAdapters<Iterator>::Value>
168 class StlAdapter : public IEnumerator<T>
169 {
170 public: // construction/destruction
174 StlAdapter(Iterator begin, Iterator end);
177 StlAdapter(const StlAdapter& arg) = default;
181 StlAdapter& operator=(const StlAdapter& arg) = default;
183 virtual ~StlAdapter(void) = default;
184
185 public: // overridden operations
186 // inherited doc
187 bool MoveNext(void)override;
188 // inherited doc
189 T GetCurrent(void)override;
190
191 private: // fields
192 Iterator begin;
193 Iterator end;
194 bool firstMove = true;
195 IteratorAdapter iteratorAdapter;
196 };
197
198private:
201 template<class Predicate>
202 class FilterEnumerator : public IEnumerator<T>
203 {
204 public: // construction/destruction
208 FilterEnumerator(typename IEnumerator<T>::Ptr source, Predicate predicate);
209
210 public: // overridden operations
211 // inherited doc
212 bool MoveNext(void)override;
213 // inherited doc
214 T GetCurrent(void)override;
215
216 private: // fields
217 typename IEnumerator<T>::Ptr source;
218 Predicate predicate;
219 };
220
221private:
224 template<typename SourceEnumerator, typename TransformOperation>
225 class TransformEnumerator : public Arp::IEnumerator<T>
226 {
227 public:
229 using Source = SourceEnumerator;
230
234 TransformEnumerator(std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp);
235
236 bool MoveNext() override;
237 T GetCurrent() override;
238
239 private:
240 std::shared_ptr<SourceEnumerator> source;
241 TransformOperation transformOp;
242 };
243
244
245public: // construction/destruction
247 Enumerator(void) = default;
250 Enumerator(const Enumerator& arg) = default;
254 Enumerator& operator=(const Enumerator& arg) = default;
256 virtual ~Enumerator(void) = default;
257
258public: // static fields
260 static Empty Null;
261
262public: // static facrory operations
265 static typename IEnumerator<T>::Ptr CreateEmpty(void);
266
278 static typename IEnumerator<T>::Ptr CreateComposite(typename IEnumerator<T>::Ptr first, typename IEnumerator<T>::Ptr second);
279
285 template<class TIterator>
286 static typename IEnumerator<T>::Ptr CreateStlAdapter(TIterator begin, TIterator end);
287
292 template<class TContainer>
293 static typename IEnumerator<T>::Ptr CreateStlAdapter(TContainer& c);
294
299 template<class TContainer>
300 static typename IEnumerator<T>::Ptr CreateKeysAdapter(TContainer& c);
301
306 template<class TContainer>
307 static typename IEnumerator<T>::Ptr CreateKeysAdapter(const TContainer& c);
308
313 template<class TContainer>
314 static typename IEnumerator<T>::Ptr CreateMappedAdapter(TContainer& c);
315
320 template<class TContainer>
321 static typename IEnumerator<T>::Ptr CreateMappedAdapter(const TContainer& c);
322
328 template<class Predicate>
329 static typename IEnumerator<T>::Ptr CreateFilter(typename IEnumerator<T>::Ptr source, Predicate predicate);
330
337 template<class SourceEnumerator, class TransformOperation>
338 static typename IEnumerator<T>::Ptr CreateTransform(std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp);
339
340
341public: // abstract/overridden operations inherited from IEnumerator
342 // inherited doc
343 virtual bool MoveNext(void) = 0;
344 // inherited doc
345 T GetCurrent(void)override;
346
347private: // usings
348 using TCurrent = typename std::remove_const<typename std::remove_reference<T>::type>::type;
349
350protected:
351 TCurrent current;
352};
353
355// inline methods of class Enumerator<T>::Empty
356template<class T>
358{
359 return false;
360}
361
362template<class T>
364{
365 throw Exception("IEnumerator::GetCurrent() is not supported by empty enumerators");
366}
367
369// inline methods of class Enumerator<T>::Composite
370template<class T>
372 : first(first)
373 , second(second)
374{
375}
376
377template<class T>
378inline bool Enumerator<T>::Composite::MoveNext()
379{
380 if (this->first)
381 {
382 if (this->first->MoveNext())
383 {
384 return true;
385 }
386 // else
387 this->first.reset();
388 }
389 return this->second->MoveNext();
390}
391
392template<class T>
393inline T Enumerator<T>::Composite::GetCurrent()
394{
395 if (this->first)
396 {
397 return this->first->GetCurrent();
398 }
399 // else
400 return this->second->GetCurrent();
401}
402
404// inline methods of class Enumerator<T>::StackComposite
405template<class T>
406inline void Enumerator<T>::StackComposite::Push(typename IEnumerator<T>::Ptr e)
407{
408 this->enumerators.push(e);
409}
410
411template<class T>
412inline bool Enumerator<T>::StackComposite::MoveNext()
413{
414 while (!this->enumerators.empty())
415 {
416 if (this->enumerators.top()->MoveNext())
417 {
418 return true;
419 }
420 // else must pop last enumerator
421 this->enumerators.pop();
422 }
423 // reaching this point means stack is empty
424 return false;
425}
426
427template<class T>
428inline T Enumerator<T>::StackComposite::GetCurrent()
429{
430 return this->enumerators.top()->GetCurrent();
431}
432
433template<class T>
434inline size_t Enumerator<T>::StackComposite::GetSize() const
435{
436 return this->enumerators.size();
437}
438
440// inline methods of class Enumerator<T>::StlAdapter
441template<class T>
442template<class Iterator, class IteratorAdapter>
443inline Enumerator<T>::StlAdapter<Iterator, IteratorAdapter>::StlAdapter(Iterator begin, Iterator end)
444 : begin(begin)
445 , end(end)
446 , iteratorAdapter()
447{
448}
449
450template<class T>
451template<class Iterator, class IteratorAdapter>
452inline bool Enumerator<T>::StlAdapter<Iterator, IteratorAdapter>::MoveNext()
453{
454 if (this->firstMove)
455 {
456 this->firstMove = false;
457 return this->begin != this->end;
458 }
459 // else
460 return ++this->begin != this->end;
461}
462
463template<class T>
464template<class Iterator, class IteratorAdapter>
465inline T Enumerator<T>::StlAdapter<Iterator, IteratorAdapter>::GetCurrent()
466{
467 return this->iteratorAdapter(this->begin);
468}
469
471// inline methods of class Enumerator<T>::FilterEnumerator
472template<class T>
473template<class Predicate>
474inline Enumerator<T>::FilterEnumerator<Predicate>::FilterEnumerator(
475 typename IEnumerator<T>::Ptr source, Predicate predicate)
476 : source(std::move(source)), predicate(std::move(predicate))
477{
478}
479
480
481template<class T>
482template<class Predicate>
483inline bool Enumerator<T>::FilterEnumerator<Predicate>::MoveNext()
484{
485 while (this->source->MoveNext())
486 {
487 if (this->predicate(this->source->GetCurrent()))
488 {
489 return true;
490 }
491 }
492 return false;
493}
494
495
496template<class T>
497template<class Predicate>
498inline T Enumerator<T>::FilterEnumerator<Predicate>::GetCurrent()
499{
500 return this->source->GetCurrent();
501}
502
504// inline methods of class Enumerator<T>::TransformEnumerator
505template<class T>
506template<class SourceEnumerator, class TransformOperation>
507Enumerator<T>::TransformEnumerator<SourceEnumerator, TransformOperation>::TransformEnumerator(
508 std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp)
509 : source(std::move(source)), transformOp(std::move(transformOp))
510{
511}
512
513
514template<class T>
515template<class SourceEnumerator, class TransformOperation>
516bool Enumerator<T>::TransformEnumerator<SourceEnumerator, TransformOperation>::MoveNext()
517{
518 return this->source->MoveNext();
519}
520
521
522template<class T>
523template<class SourceEnumerator, class TransformOperation>
524T Enumerator<T>::TransformEnumerator<SourceEnumerator, TransformOperation>::GetCurrent()
525{
526 return this->transformOp(this->source->GetCurrent());
527}
528
529
531// inline methods of class Enumerator<T>
532template<class T>
533inline T Enumerator<T>::GetCurrent()
534{
535 return this->current;
536}
537
538template<class T>
539inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateEmpty()
540{
541 return std::make_shared<Empty>();
542}
543
544template<class T>
545inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateComposite(typename IEnumerator<T>::Ptr first, typename IEnumerator<T>::Ptr second)
546{
547 return std::make_shared<Composite>(first, second);
548}
549
550template<class T>
551template<class TIterator>
552inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateStlAdapter(TIterator begin, TIterator end)
553{
554 return std::make_shared<StlAdapter<TIterator>>(begin, end);
555}
556
557template<class T>
558template<class TContainer>
559inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateStlAdapter(TContainer& c)
560{
561 return CreateStlAdapter(c.begin(), c.end());
562}
563
564template<class T>
565template<class TContainer>
566inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateKeysAdapter(TContainer& c)
567{
568 return std::make_shared<StlAdapter<typename TContainer::iterator, typename IteratorAdapters<typename TContainer::iterator>::ConstKey>>(c.begin(), c.end());
569}
570
571template<class T>
572template<class TContainer>
573inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateKeysAdapter(const TContainer& c)
574{
575 return std::make_shared<StlAdapter<typename TContainer::const_iterator, typename IteratorAdapters<typename TContainer::const_iterator>::ConstKey>>(c.begin(), c.end());
576}
577
578template<class T>
579template<class TContainer>
580inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateMappedAdapter(TContainer& c)
581{
582 return std::make_shared<StlAdapter<typename TContainer::iterator, typename IteratorAdapters<typename TContainer::iterator>::Mapped>>(c.begin(), c.end());
583}
584
585template<class T>
586template<class TContainer>
587inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateMappedAdapter(const TContainer& c)
588{
589 return std::make_shared<StlAdapter<typename TContainer::const_iterator, typename IteratorAdapters<typename TContainer::const_iterator>::ConstMapped>>(c.begin(), c.end());
590}
591
592template<class T>
593template<class Predicate>
594inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateFilter(
595 typename IEnumerator<T>::Ptr source, Predicate predicate)
596{
597 return std::make_shared<Enumerator<T>::FilterEnumerator<Predicate>>(std::move(source), predicate);
598}
599
600template<class T>
601template<class SourceEnumerator, class TransformOperation>
602inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateTransform(std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp)
603{
604 return std::make_shared<Enumerator<T>::TransformEnumerator<SourceEnumerator, TransformOperation>>(
605 std::move(source), transformOp);
606}
607
609// Initializing of static fields of class Enumerator<T>
610template<class T>
611typename Enumerator<T>::Empty Enumerator<T>::Null;
612
613} // end of namespace Arp
614
615#endif // ndef ARP_USE_ARP_SYSTEM_CORE
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.Composite.hxx:68
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.Composite.hxx:93
Composite(typename IEnumerator< T >::Ptr first, typename IEnumerator< T >::Ptr second)
Constructs an Enumerator<T>::Composite instance.
Definition: Enumerator.Composite.hxx:60
~Composite(void) override
Destructs this instance and frees all resources.
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.Empty.hxx:60
~Empty(void) override
Destructs this instance and frees all resources.
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.Empty.hxx:67
Empty(void)
Constructs an Enumerator<T>::Empty instance.
void Push(typename IEnumerator< T >::Ptr enumerator)
Adds the as argument passed enumerator to this stack.
Definition: Enumerator.StackComposite.hxx:100
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.StackComposite.hxx:88
StackComposite(void)
Constructs an StackComposite instance.
size_t GetSize(void) const
Get the size of this stack.
Definition: Enumerator.StackComposite.hxx:112
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.StackComposite.hxx:71
~StackComposite(void) override
Destructs this instance and frees all resources.
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.StlAdapter.hxx:98
StlAdapter(Iterator begin, Iterator end)
Constructs an StlAdapter instance.
Definition: Enumerator.StlAdapter.hxx:69
~StlAdapter(void) override
Destructs this instance and frees all resources.
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.StlAdapter.hxx:78
static IEnumerator< T >::Ptr CreateMappedAdapter(TContainer &c)
Creates an enumerator adapter from the given STL map enumerating the mapped items.
Definition: Enumerator.StlAdapter.hxx:171
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.Composite.hxx:122
static IEnumerator< T >::Ptr CreateKeysAdapter(TContainer &c)
Creates an enumerator adapter from the given STL map enumerating the keys.
Definition: Enumerator.StlAdapter.hxx:149
static IEnumerator< T >::Ptr CreateStlAdapter(TIterator begin, TIterator end)
Creates an enumerator adapter from the given STL iterators.
Definition: Enumerator.StlAdapter.hxx:116
TCurrent current
The current field of this enumerator.
Definition: Enumerator.hxx:86
static IEnumerator< T >::Ptr CreateEmpty(void)
Creates an empty enumerator.
Definition: Enumerator.Empty.hxx:77
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.Filter.hxx:104
Enumerator(void)
Constructs a default Enumerator instance.
~Enumerator(void) override
Destructs this instance and frees all resources.
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:113
Declares the interface of the enumerator pattern, which is leaned on .NET enumerator idiom.
Definition: IEnumerator.hxx:49
IEnumerator(void)=default
Constructs an IEnumerator instance.
virtual bool MoveNext(void)=0
Moves this enumerator to the next position.
std::shared_ptr< IEnumerator > Ptr
The smart pointer type of this interface.
Definition: IEnumerator.hxx:52
@ Empty
No sink assigned to session yet.
Root namespace for the PLCnext API
Namespace of the C++ standard library