Drive Engine  1.0.0
Plateforme de reconstruction 3D
ListImplementationUtilities.h
1 // Copyright (c) 2015. All rights reserved to DriveEngine Team.
2 
3 #pragma once
4 
5 #include <vector>
6 
7 #define GENERATE_LIST_H(elementClassName) \
8 private: \
9  typedef std::vector<elementClassName*> List; \
10  List list; \
11 \
12 public: \
13 \
14  /* ICollection */\
15 \
16  virtual Size GetSize() const; \
17  virtual bool IsEmpty() const; \
18  virtual IEnumerator* GetEnumerator() const; \
19  virtual IConstEnumerator* GetConstEnumerator() const; \
20  virtual void Clear(); \
21 \
22 \
23  /* IList */ \
24 \
25  virtual IExportable* GetElement(Index index) const; \
26  virtual const IExportable* GetConstElement(Index index) const; \
27  virtual void Add(IExportable &element); \
28  virtual void Remove(IExportable &element); \
29  virtual void AddList(const IList &list); \
30  virtual void RemoveList(const IList &list); \
31 \
32  /* elementClassName */ \
33 \
34  virtual void Add(elementClassName &element); \
35  virtual void Remove(elementClassName &element); \
36  elementClassName* Get##elementClassName##(Index index) const; \
37 \
38 private: \
39  elementClassName* Convert(IExportable& element); \
40 \
41 private: \
42  class Enumerator : public IEnumerator \
43  { \
44  private: \
45  bool hasMovedAtLeastOnce; \
46  List::const_iterator iterator; \
47  List::const_iterator begin; \
48  List::const_iterator end; \
49 \
50  public: \
51 \
52  Enumerator(List::const_iterator& begin, List::const_iterator& end); \
53 \
54  /* IExportable */ \
55 \
56  virtual void Delete() const; \
57 \
58 \
59  /* IEnumerator */ \
60 \
61  virtual bool MoveNext(); \
62  virtual IExportable* GetCurrent() const; \
63  virtual void Reset(); \
64  }; \
65 \
66  class ConstEnumerator : public IConstEnumerator \
67  { \
68  private: \
69  bool hasMovedAtLeastOnce; \
70  List::const_iterator iterator; \
71  List::const_iterator begin; \
72  List::const_iterator end; \
73 \
74  public: \
75 \
76  ConstEnumerator(List::const_iterator& begin, List::const_iterator& end); \
77 \
78 \
79  /* IExportable */ \
80 \
81  virtual void Delete() const; \
82 \
83 \
84  /* IEnumerator */ \
85 \
86  virtual bool MoveNext(); \
87  virtual const IExportable* GetCurrent() const; \
88  virtual void Reset(); \
89  };
90 
91 
92 
93 
94 #define GENERATE_LIST(listClassName, elementClassName) \
95 \
96 \
97 /* ICollection */\
98 \
99 Size listClassName::GetSize() const \
100 { \
101  return (Size)this->list.size(); \
102 } \
103 \
104 bool listClassName::IsEmpty() const \
105 { \
106  return this->list.empty(); \
107 } \
108 \
109 IEnumerator* listClassName::GetEnumerator() const \
110 { \
111  return new Enumerator(list.begin(), list.end()); \
112 } \
113 \
114 IConstEnumerator* listClassName::GetConstEnumerator() const \
115 { \
116  return new ConstEnumerator(list.begin(), list.end()); \
117 } \
118 \
119 void listClassName::Clear() \
120 { \
121  list.clear(); \
122 } \
123 \
124 \
125 /* IList */\
126 \
127 IExportable* listClassName::GetElement(Index index) const \
128 { \
129  return Get##elementClassName##(index); \
130 } \
131 \
132 const IExportable* listClassName::GetConstElement(Index index) const \
133 { \
134  return GetElement(index); \
135 } \
136 \
137 void listClassName::Add(IExportable &element) \
138 { \
139  elementClassName* convertedElement = Convert(element); \
140  if (convertedElement == nullptr){ /* An error has been thrown */ return; } \
141 \
142  Add(*convertedElement); \
143 } \
144 \
145 void listClassName::Remove(IExportable &element) \
146 { \
147  elementClassName* convertedElement = Convert(element); \
148  if (convertedElement == nullptr){ /* An error has been thrown */ return; } \
149 \
150  Remove(*convertedElement); \
151 } \
152 \
153 void listClassName::AddList(const IList &list) \
154 { \
155  if (Precondition::IsNotNull(list, "The list must not be null.")) \
156  { \
157  IEnumerator* enumerator = list.GetEnumerator(); \
158  while (enumerator->MoveNext()) \
159  { \
160  Add(*enumerator->GetCurrent()); \
161  } \
162  } \
163 } \
164 \
165 void listClassName::RemoveList(const IList &list) \
166 { \
167  if (Precondition::IsNotNull(list, "The list must not be null.")) \
168  { \
169  IEnumerator* enumerator = list.GetEnumerator(); \
170  while (enumerator->MoveNext()) \
171  { \
172  Remove(*enumerator->GetCurrent()); \
173  } \
174  } \
175 } \
176 \
177 \
178 /* elementClassName */\
179 \
180 elementClassName* listClassName::Get##elementClassName##(Index index) const \
181 { \
182  elementClassName* element = nullptr; \
183  if (Precondition::IsTrue(0 <= index && index < (Index)list.size(), "Outbound index.")) \
184  { \
185  element = list[index]; \
186  } \
187  return element; \
188 } \
189 \
190 void listClassName::Add(elementClassName &element) \
191 { \
192  if (Precondition::IsNotNull(element, "The element to add must not be null.")) \
193  { \
194  ::AddReference(&element); \
195  list.push_back(&element); \
196  } \
197 } \
198 \
199 void listClassName::Remove(elementClassName &element) \
200 { \
201  if (Precondition::IsNotNull(element, "The element to remove must not be null.")) \
202  { \
203  List::iterator iterator = std::find(list.begin(), list.end(), &element); \
204  if (iterator == list.end()){ return; } \
205  \
206  ::DeleteReference(*iterator); \
207  list.erase(iterator); \
208  } \
209 } \
210 \
211 elementClassName* listClassName::Convert(IExportable& element) \
212 { \
213  if (Precondition::IsNotNull(element, "The element must not be null.")) \
214  { \
215  elementClassName* convertedElement = dynamic_cast<elementClassName*>(&element); \
216  if (Precondition::IsNotNull(convertedElement, "The element cannot be converted.")) \
217  { \
218  return convertedElement; \
219  } \
220  } \
221  return nullptr; \
222 } \
223 \
224 /* Enumerator */ \
225 \
226 \
227 void listClassName::Enumerator::Delete() const \
228 { \
229  delete this; \
230 } \
231 \
232 \
233 listClassName::Enumerator::Enumerator(List::const_iterator& begin, List::const_iterator& end) \
234  : begin(begin), \
235  end(end), \
236  iterator(begin), \
237  hasMovedAtLeastOnce(false) \
238 {} \
239 \
240 \
241 bool listClassName::Enumerator::MoveNext() \
242 { \
243  if (!hasMovedAtLeastOnce) \
244  { \
245  iterator = begin; \
246  hasMovedAtLeastOnce = true; \
247  } \
248  else if (iterator != end) \
249  { \
250  ++iterator; \
251  } \
252 \
253  return (iterator != end); \
254 } \
255 \
256 \
257 IExportable* listClassName::Enumerator::GetCurrent() const \
258 { \
259  IExportable* result = nullptr; \
260  if (hasMovedAtLeastOnce && iterator != end) \
261  { \
262  result = *iterator; \
263  } \
264  return result; \
265 } \
266 \
267 \
268 void listClassName::Enumerator::Reset() \
269 { \
270  iterator = begin; \
271  hasMovedAtLeastOnce = false; \
272 } \
273 \
274 \
275 /* ConstEnumerator */ \
276 \
277 \
278 void listClassName::ConstEnumerator::Delete() const \
279 { \
280  delete this; \
281 } \
282 \
283 \
284 listClassName::ConstEnumerator::ConstEnumerator(List::const_iterator& begin, List::const_iterator& end) \
285  : begin(begin), \
286  end(end), \
287  iterator(begin), \
288  hasMovedAtLeastOnce(false) \
289 {} \
290 \
291 \
292 bool listClassName::ConstEnumerator::MoveNext() \
293 { \
294  if (!hasMovedAtLeastOnce) \
295  { \
296  iterator = begin; \
297  hasMovedAtLeastOnce = true; \
298  } \
299  else if (iterator != end) \
300  { \
301  ++iterator; \
302  } \
303 \
304  return (iterator != end); \
305 } \
306 \
307 \
308 const IExportable* listClassName::ConstEnumerator::GetCurrent() const \
309 { \
310  IExportable* result = nullptr; \
311  if (hasMovedAtLeastOnce && iterator != end) \
312  { \
313  result = *iterator; \
314  } \
315  return result; \
316 } \
317 \
318 \
319 void listClassName::ConstEnumerator::Reset() \
320 { \
321  iterator = begin; \
322  hasMovedAtLeastOnce = false; \
323 }