PLCnext API Documentation  20.6.0.30321
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  T& operator()(Iterator i)const
127  {
128  return *i;
129  }
130  };
131  struct Key
132  {
133  T& operator()(Iterator i)const
134  {
135  return i->first;
136  }
137  };
138  struct Mapped
139  {
140  T& operator()(Iterator i)const
141  {
142  return i->second;
143  }
144  };
145  };
146 
147 public:
152  template<class Iterator, class IteratorAdapter = typename IteratorAdapters<Iterator>::Value>
153  class StlAdapter : public IEnumerator<T>
154  {
155  public: // construction/destruction
159  StlAdapter(Iterator begin, Iterator end);
162  StlAdapter(const StlAdapter& arg) = default;
166  StlAdapter& operator=(const StlAdapter& arg) = default;
168  virtual ~StlAdapter(void) = default;
169 
170  public: // overridden operations
171  // inherited doc
172  bool MoveNext(void)override;
173  // inherited doc
174  T GetCurrent(void)override;
175 
176  private: // fields
177  Iterator begin;
178  Iterator end;
179  bool firstMove = true;
180  IteratorAdapter iteratorAdapter;
181  };
182 
183 private:
186  template<class Predicate>
187  class FilterEnumerator : public IEnumerator<T>
188  {
189  public: // construction/destruction
193  FilterEnumerator(typename IEnumerator<T>::Ptr source, Predicate predicate);
194 
195  public: // overridden operations
196  // inherited doc
197  bool MoveNext(void)override;
198  // inherited doc
199  T GetCurrent(void)override;
200 
201  private: // fields
202  typename IEnumerator<T>::Ptr source;
203  Predicate predicate;
204  };
205 
206 public: // construction/destruction
208  Enumerator(void) = default;
211  Enumerator(const Enumerator& arg) = default;
215  Enumerator& operator=(const Enumerator& arg) = default;
217  virtual ~Enumerator(void) = default;
218 
219 public: // static fields
221  static Empty Null;
222 
223 public: // static facrory operations
226  static typename IEnumerator<T>::Ptr CreateEmpty(void);
227 
239  static typename IEnumerator<T>::Ptr CreateComposite(typename IEnumerator<T>::Ptr first, typename IEnumerator<T>::Ptr second);
240 
246  template<class TIterator>
247  static typename IEnumerator<T>::Ptr CreateStlAdapter(TIterator begin, TIterator end);
248 
253  template<class TContainer>
254  static typename IEnumerator<T>::Ptr CreateStlAdapter(TContainer& c);
255 
260  template<class TContainer>
261  static typename IEnumerator<T>::Ptr CreateKeysAdapter(TContainer& c);
262 
267  template<class TContainer>
268  static typename IEnumerator<T>::Ptr CreateMappedAdapter(TContainer& c);
269 
275  template<class Predicate>
276  static typename IEnumerator<T>::Ptr CreateFilter(typename IEnumerator<T>::Ptr source, Predicate predicate);
277 
278 public: // abstract/overridden operations inherited from IEnumerator
279  // inherited doc
280  virtual bool MoveNext(void) = 0;
281  // inherited doc
282  virtual T GetCurrent(void)override;
283 
284 private: // usings
285  using TCurrent = typename std::remove_const<typename std::remove_reference<T>::type>::type;
286 
287 protected:
288  TCurrent current;
289 };
290 
292 // inline methods of class Enumerator<T>::Empty
293 template<class T>
295 {
296  return false;
297 }
298 
299 template<class T>
301 {
302  throw Exception("IEnumerator::GetCurrent() is not supported by empty enumerators");
303 }
304 
306 // inline methods of class Enumerator<T>::Composite
307 template<class T>
309  : first(first)
310  , second(second)
311 {
312 }
313 
314 template<class T>
316 {
317  if (this->first)
318  {
319  if (this->first->MoveNext())
320  {
321  return true;
322  }
323  // else
324  this->first.reset();
325  }
326  return this->second->MoveNext();
327 }
328 
329 template<class T>
331 {
332  if (this->first)
333  {
334  return this->first->GetCurrent();
335  }
336  // else
337  return this->second->GetCurrent();
338 }
339 
341 // inline methods of class Enumerator<T>::StackComposite
342 template<class T>
344 {
345  this->enumerators.push(e);
346 }
347 
348 template<class T>
350 {
351  while (!this->enumerators.empty())
352  {
353  if (this->enumerators.top()->MoveNext())
354  {
355  return true;
356  }
357  // else must pop last enumerator
358  this->enumerators.pop();
359  }
360  // reaching this point means stack is empty
361  return false;
362 }
363 
364 template<class T>
366 {
367  return this->enumerators.top()->GetCurrent();
368 }
369 
370 template<class T>
372 {
373  return this->enumerators.size();
374 }
375 
377 // inline methods of class Enumerator<T>::StlAdapter
378 template<class T>
379 template<class Iterator, class IteratorAdapter>
381  : begin(begin)
382  , end(end)
383  , iteratorAdapter()
384 {
385 }
386 
387 template<class T>
388 template<class Iterator, class IteratorAdapter>
390 {
391  if (this->firstMove)
392  {
393  this->firstMove = false;
394  return this->begin != this->end;
395  }
396  // else
397  return ++this->begin != this->end;
398 }
399 
400 template<class T>
401 template<class Iterator, class IteratorAdapter>
403 {
404  return this->iteratorAdapter(this->begin);
405 }
406 
408 // inline methods of class Enumerator<T>::FilterEnumerator
409 template<class T>
410 template<class Predicate>
412  typename IEnumerator<T>::Ptr source, Predicate predicate)
413  : source(std::move(source)), predicate(std::move(predicate))
414 {
415 }
416 
417 
418 template<class T>
419 template<class Predicate>
421 {
422  while (this->source->MoveNext())
423  {
424  if (this->predicate(this->source->GetCurrent()))
425  {
426  return true;
427  }
428  }
429  return false;
430 }
431 
432 
433 template<class T>
434 template<class Predicate>
436 {
437  return this->source->GetCurrent();
438 }
439 
440 
442 // inline methods of class Enumerator<T>
443 template<class T>
445 {
446  return this->current;
447 }
448 
449 template<class T>
451 {
452  return std::make_shared<Empty>();
453 }
454 
455 template<class T>
457 {
458  return std::make_shared<Composite>(first, second);
459 }
460 
461 template<class T>
462 template<class TIterator>
463 inline typename IEnumerator<T>::Ptr Enumerator<T>::CreateStlAdapter(TIterator begin, TIterator end)
464 {
465  return std::make_shared<StlAdapter<TIterator>>(begin, end);
466 }
467 
468 template<class T>
469 template<class TContainer>
471 {
472  return CreateStlAdapter(c.begin(), c.end());
473 }
474 
475 template<class T>
476 template<class TContainer>
478 {
479  return std::make_shared<StlAdapter<typename TContainer::const_iterator, typename IteratorAdapters<typename TContainer::const_iterator>::Key>>(c.begin(), c.end());
480 }
481 
482 template<class T>
483 template<class TContainer>
485 {
486  return std::make_shared<StlAdapter<typename TContainer::const_iterator, typename IteratorAdapters<typename TContainer::const_iterator>::Mapped>>(c.begin(), c.end());
487 }
488 
489 
490 template<class T>
491 template<class Predicate>
493  typename IEnumerator<T>::Ptr source, Predicate predicate)
494 {
495  return std::make_shared<Enumerator<T>::FilterEnumerator<Predicate>>(source, predicate);
496 }
497 
498 
500 // Initializing of static fields of class Enumerator<T>
501 template<class T>
503 
504 } // 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:463
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:456
Composite(typename IEnumerator< T >::Ptr first, typename IEnumerator< T >::Ptr second)
Constructs an Composite instance.
Definition: Enumerator.hxx:308
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:371
static IEnumerator< T >::Ptr CreateMappedAdapter(TContainer &c)
Creates an enumerator adapter from the given STL map enumerating the mapped items.
Definition: Enumerator.hxx:484
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:330
void Push(typename IEnumerator< T >::Ptr e)
Adds the as argument passed enumerator to this stack.
Definition: Enumerator.hxx:343
Empty(void)=default
Constructs an Empty instance.
static IEnumerator< T >::Ptr CreateEmpty(void)
Creates an empty enumerator.
Definition: Enumerator.hxx:450
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:492
static Empty Null
A static empty enumerator instance.
Definition: Enumerator.hxx:221
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:444
This class implements an enumerator adapter for STL container based on iterators.
Definition: Enumerator.hxx:153
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:315
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:365
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:477
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:349
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
bool MoveNext(void) override
Moves this enumerator to the next position.
Definition: Enumerator.hxx:294
TCurrent current
The current field of this enumerator.
Definition: Enumerator.hxx:288
T GetCurrent(void) override
Gets the element at the current position.
Definition: Enumerator.hxx:300