PLCnext API Documentation  21.0.0.35466
Enumerator.hxx
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
8 #include "Arp/System/Core/IEnumerator.hxx"
9 #include "Arp/System/Core/Exception.hpp"
10 #include <stack>
11 namespace Arp
12 {
13 
20 template<class T>
21 class Enumerator : public IEnumerator<T>
22 {
23 public: // 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 
46 public: // 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 
80 public: // 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 
118 private:
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 
154 public:
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 
190 private:
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 
213 private:
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 
237 public: // 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 
250 public: // static fields
252  static Empty Null;
253 
254 public: // 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 
333 public: // abstract/overridden operations inherited from IEnumerator
334  // inherited doc
335  virtual bool MoveNext(void) = 0;
336  // inherited doc
337  virtual T GetCurrent(void)override;
338 
339 private: // usings
340  using TCurrent = typename std::remove_const<typename std::remove_reference<T>::type>::type;
341 
342 protected:
343  TCurrent current;
344 };
345 
347 // inline methods of class Enumerator<T>::Empty
348 template<class T>
350 {
351  return false;
352 }
353 
354 template<class T>
356 {
357  throw Exception("IEnumerator::GetCurrent() is not supported by empty enumerators");
358 }
359 
361 // inline methods of class Enumerator<T>::Composite
362 template<class T>
364  : first(first)
365  , second(second)
366 {
367 }
368 
369 template<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 
384 template<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
397 template<class T>
399 {
400  this->enumerators.push(e);
401 }
402 
403 template<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 
419 template<class T>
421 {
422  return this->enumerators.top()->GetCurrent();
423 }
424 
425 template<class T>
427 {
428  return this->enumerators.size();
429 }
430 
432 // inline methods of class Enumerator<T>::StlAdapter
433 template<class T>
434 template<class Iterator, class IteratorAdapter>
436  : begin(begin)
437  , end(end)
438  , iteratorAdapter()
439 {
440 }
441 
442 template<class T>
443 template<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 
455 template<class T>
456 template<class Iterator, class IteratorAdapter>
458 {
459  return this->iteratorAdapter(this->begin);
460 }
461 
463 // inline methods of class Enumerator<T>::FilterEnumerator
464 template<class T>
465 template<class Predicate>
467  typename IEnumerator<T>::Ptr source, Predicate predicate)
468  : source(std::move(source)), predicate(std::move(predicate))
469 {
470 }
471 
472 
473 template<class T>
474 template<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 
488 template<class T>
489 template<class Predicate>
491 {
492  return this->source->GetCurrent();
493 }
494 
496 // inline methods of class Enumerator<T>::TransformEnumerator
497 template<class T>
498 template<class SourceEnumerator, class TransformOperation>
500  std::shared_ptr<SourceEnumerator> source, TransformOperation transformOp)
501  : source(std::move(source)), transformOp(std::move(transformOp))
502 {
503 }
504 
505 
506 template<class T>
507 template<class SourceEnumerator, class TransformOperation>
509 {
510  return this->source->MoveNext();
511 }
512 
513 
514 template<class T>
515 template<class SourceEnumerator, class TransformOperation>
517 {
518  return this->transformOp(this->source->GetCurrent());
519 }
520 
521 
523 // inline methods of class Enumerator<T>
524 template<class T>
526 {
527  return this->current;
528 }
529 
530 template<class T>
532 {
533  return std::make_shared<Empty>();
534 }
535 
536 template<class T>
538 {
539  return std::make_shared<Composite>(first, second);
540 }
541 
542 template<class T>
543 template<class TIterator>
544 inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateStlAdapter(TIterator begin, TIterator end)
545 {
546  return std::make_shared<StlAdapter<TIterator>>(begin, end);
547 }
548 
549 template<class T>
550 template<class TContainer>
552 {
553  return CreateStlAdapter(c.begin(), c.end());
554 }
555 
556 template<class T>
557 template<class TContainer>
559 {
560  return std::make_shared<StlAdapter<typename TContainer::iterator, typename IteratorAdapters<typename TContainer::iterator>::ConstKey>>(c.begin(), c.end());
561 }
562 
563 template<class T>
564 template<class TContainer>
565 inline 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 
570 template<class T>
571 template<class TContainer>
573 {
574  return std::make_shared<StlAdapter<typename TContainer::iterator, typename IteratorAdapters<typename TContainer::iterator>::Mapped>>(c.begin(), c.end());
575 }
576 
577 template<class T>
578 template<class TContainer>
579 inline 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 
584 template<class T>
585 template<class Predicate>
587  typename IEnumerator<T>::Ptr source, Predicate predicate)
588 {
589  return std::make_shared<Enumerator<T>::FilterEnumerator<Predicate>>(source, predicate);
590 }
591 
592 template<class T>
593 template<class SourceEnumerator, class TransformOperation>
594 inline 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  source, transformOp);
598 }
599 
601 // Initializing of static fields of class Enumerator<T>
602 template<class T>
604 
605 } // end of namespace Arp
Declares the interface of the enumerator pattern, which is leaned on .NET enumerator idiom...
Definition: IEnumerator.hxx:47
static IEnumerator< T >::Ptr CreateStlAdapter(TIterator begin, TIterator end)
Creates an enumerator adapter from the given STL iterators.
Definition: Enumerator.hxx:544
std::shared_ptr< IEnumerator > Ptr
The smart pointer tpye of this interface.
Definition: IEnumerator.hxx:51
Enumerator(void)=default
Constructs an Enumerator instance.
virtual bool MoveNext(void)=0
Moves this enumerator to the next position.
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
Composite(typename IEnumerator< T >::Ptr first, typename IEnumerator< T >::Ptr second)
Constructs an Composite instance.
Definition: Enumerator.hxx:363
Implements an empty enumerator, that is, the first call of MoveNext() will return false...
Definition: Enumerator.hxx:26
size_t GetSize() const
Get the size of this stack.
Definition: Enumerator.hxx:426
static IEnumerator< T >::Ptr CreateMappedAdapter(TContainer &c)
Creates an enumerator adapter from the given STL map enumerating the mapped items.
Definition: Enumerator.hxx:572
Use this class to build a single enumerator by two given enumerator, e.g. to enumerate multiple conta...
Definition: Enumerator.hxx:82
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:385
void Push(typename IEnumerator< T >::Ptr e)
Adds the as argument passed enumerator to this stack.
Definition: Enumerator.hxx:398
Empty(void)=default
Constructs an Empty instance.
static IEnumerator< T >::Ptr CreateEmpty(void)
Creates an empty enumerator.
Definition: Enumerator.hxx:531
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
static Empty Null
A static empty enumerator instance.
Definition: Enumerator.hxx:252
Root namespace for the PLCnext API
Empty & operator=(const Empty &arg)=default
Assignment operator.
virtual T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:525
This class implements an enumerator adapter for STL container based on iterators.
Definition: Enumerator.hxx:160
virtual ~Enumerator(void)=default
Destructs this instance and frees all resources.
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:370
virtual ~Empty(void)=default
Destructs this instance and frees all resources.
virtual bool MoveNext(void)=0
Moves this enumerator to the next position.
This is the base class of all Arp exception classes.
Definition: Exception.hpp:15
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:420
This class defines a base class for all enumerator implementations and some predefined enumerators as...
Definition: Enumerator.hxx:21
static IEnumerator< T >::Ptr CreateKeysAdapter(TContainer &c)
Creates an enumerator adapter from the given STL map enumerating the keys.
Definition: Enumerator.hxx:558
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:404
virtual T GetCurrent(void)=0
Gets the element at the current position.
Use this class to build a single enumerator by two given enumerator, e.g. to enumerate multiple conta...
Definition: Enumerator.hxx:52
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
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:349
TCurrent current
The current field of this enumerator.
Definition: Enumerator.hxx:343
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:355