Emergency 20 Dokumentation  4.2.0
RandomEnumerator.h
Go to the documentation of this file.
1 // Copyright (C) 2012-2018 Promotion Software GmbH
2 
3 
4 //[-------------------------------------------------------]
5 //[ Header guard ]
6 //[-------------------------------------------------------]
7 #pragma once
8 
9 
10 //[-------------------------------------------------------]
11 //[ Includes ]
12 //[-------------------------------------------------------]
13 #include <qsf/math/Random.h>
14 #include <qsf/QsfHelper.h>
15 
16 #include <vector>
17 
18 
19 //[-------------------------------------------------------]
20 //[ Namespace ]
21 //[-------------------------------------------------------]
22 namespace em5
23 {
24 
25 
26  namespace constructionpolicy
27  {
28  enum Policy
29  {
30  COPY,
32  };
33  }
34 
35 
36  //[-------------------------------------------------------]
37  //[ Classes ]
38  //[-------------------------------------------------------]
46  template<typename T>
48  {
49 
50 
51  //[-------------------------------------------------------]
52  //[ Public methods ]
53  //[-------------------------------------------------------]
54  public:
59  inline explicit RandomEnumerator(const std::vector<T*>& inputToCopy, uint32 maxTries = std::numeric_limits<uint32>::max()) :
60  mTriesLeft(maxTries)
61  {
62  mElements = inputToCopy;
63  }
64 
69  inline RandomEnumerator(constructionpolicy::Policy policy, std::vector<T*>& inputToSwapWith, uint32 maxTries = std::numeric_limits<uint32>::max()) :
70  mTriesLeft(maxTries)
71  {
72  if (policy == constructionpolicy::SWAP)
73  mElements.swap(inputToSwapWith);
74  else
75  mElements = inputToSwapWith;
76  }
77 
78  // This constructor must not be used, see comment inside
79  inline explicit RandomEnumerator(std::vector<T*>& inputToCopy, uint32 maxTries = std::numeric_limits<uint32>::max()) :
80  mTriesLeft(maxTries)
81  {
82  // If you get there, you used a RandomEnumerator constructor with a non-const std::vector reference as first argument.
83  // In this case, use the constructor with "constructionpolicy::Policy" argument to specify whether to copy or swap contents with the given std::vector.
84  // Both may be beneficial depending on your case:
85  // - constructionpolicy::COPY is safer, but produces overhead due to copying of data
86  // - constructionpolicy::SWAP will swap contents and consequently leave the given std::vector empty afterwards, which is fine if it is not used afterwards any more
87  T::Used_ambiguous_RandomEnumerator_constructor;
88  }
89 
94  inline bool empty() const
95  {
96  return mElements.empty();
97  }
98 
106  inline T* getNext()
107  {
108  // Nothing left?
109  if (mElements.empty() || mTriesLeft == 0)
110  return nullptr;
111 
112  // Choose a random position and take element from there
113  const size_t position = qsf::Random::getRandomSize(0, mElements.size() - 1);
114  T* element = mElements[position];
115 
116  // Remove this element by moving the last element here
117  if (position < mElements.size() - 1)
118  {
119  mElements[position] = mElements.back();
120  }
121  mElements.pop_back();
122 
123  // Done
124  --mTriesLeft;
125  return element;
126  }
127 
128 
129  //[-------------------------------------------------------]
130  //[ Protected methods ]
131  //[-------------------------------------------------------]
132  protected:
133  inline explicit RandomEnumerator(uint32 maxTries = std::numeric_limits<uint32>::max()) :
134  mTriesLeft(maxTries)
135  {
136  // Subclass using this constructor will have to fill mElements
137  }
138 
139 
140  //[-------------------------------------------------------]
141  //[ Protected data ]
142  //[-------------------------------------------------------]
143  protected:
144  std::vector<T*> mElements;
146 
147 
148  };
149 
150 
151 //[-------------------------------------------------------]
152 //[ Namespace ]
153 //[-------------------------------------------------------]
154 } // em5
Copy vector passed to RandomEnumerator constructor.
Definition: RandomEnumerator.h:30
Definition: ActionPriority.h:13
Helper class for iterating over a list of instances of a specific type, in a random order...
Definition: RandomEnumerator.h:47
RandomEnumerator(uint32 maxTries=std::numeric_limits< uint32 >::max())
Definition: RandomEnumerator.h:133
unsigned int uint32
Definition: PlatformTypes.h:181
RandomEnumerator(std::vector< T * > &inputToCopy, uint32 maxTries=std::numeric_limits< uint32 >::max())
Definition: RandomEnumerator.h:79
Swap with vector passed to RandomEnumerator constructor, leaving it empty afterwards.
Definition: RandomEnumerator.h:31
uint32 mTriesLeft
Definition: RandomEnumerator.h:145
T * getNext()
Randomly choose an element that was not returned before.
Definition: RandomEnumerator.h:106
RandomEnumerator(const std::vector< T * > &inputToCopy, uint32 maxTries=std::numeric_limits< uint32 >::max())
Constructor to pass a vector of elements, which will be copied.
Definition: RandomEnumerator.h:59
bool empty() const
Check if all elements were read out already.
Definition: RandomEnumerator.h:94
static size_t getRandomSize(size_t minimum, size_t maximum)
Returns a random size_t value in the range [min...max], that is including min and max as possible val...
RandomEnumerator(constructionpolicy::Policy policy, std::vector< T * > &inputToSwapWith, uint32 maxTries=std::numeric_limits< uint32 >::max())
Constructor to pass a vector of elements, with the option to swap contents.
Definition: RandomEnumerator.h:69
Policy
Definition: RandomEnumerator.h:28
std::vector< T * > mElements
Definition: RandomEnumerator.h:144