VR-Forces 4.1.1 Class Documentation
templateUtil.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2012 MAK Technologies, Inc.
3  * All rights reserved.
4  *****************************************************************************/
5 
9 
10 #pragma once
11 
12 #include <vlutil/vlExceptions.h>
13 #include <functional>
14 #include <algorithm>
15 #include <vector>
16 #include <map>
17 
18 // Expand the provide macro.
19 #define DO_PP(MACRO) MACRO
20 
21 // Theses macros make it easy to define VAR-ARG template classes.
22 
23 // Make stream puts an 'word' with the index prepended separated by "<<"
24 // Example MAKE_STREAM_1(A) output A1
25 // Example MAKE_STREAM_2(A) output A1 << A2
26 #define MAKE_STREAM_1(word) word##1
27 #define MAKE_STREAM_2(word) MAKE_STREAM_1(word)<<word##2
28 #define MAKE_STREAM_3(word) MAKE_STREAM_2(word)<<word##3
29 #define MAKE_STREAM_4(word) MAKE_STREAM_3(word)<<word##4
30 #define MAKE_STREAM_5(word) MAKE_STREAM_4(word)<<word##5
31 #define MAKE_STREAM_6(word) MAKE_STREAM_5(word)<<word##6
32 #define MAKE_STREAM_7(word) MAKE_STREAM_6(word)<<word##7
33 #define MAKE_STREAM_8(word) MAKE_STREAM_7(word)<<word##8
34 #define MAKE_STREAM_9(word) MAKE_STREAM_8(word)<<word##9
35 
36 #define MAKE_STREAM(word,count) DO_PP(MAKE_STREAM_##count(word))
37 
38 
39 // Make stream puts an 'word' with the index prepended separated by ">>"
40 // Example MAKE_STREAMOUT_1(A) output A1
41 // Example MAKE_STREAMOUT_2(A) output A1 >> A2
42 #define MAKE_STREAMOUT_1(word) word##1
43 #define MAKE_STREAMOUT_2(word) MAKE_STREAMOUT_1(word)>>word##2
44 #define MAKE_STREAMOUT_3(word) MAKE_STREAMOUT_2(word)>>word##3
45 #define MAKE_STREAMOUT_4(word) MAKE_STREAMOUT_3(word)>>word##4
46 #define MAKE_STREAMOUT_5(word) MAKE_STREAMOUT_4(word)>>word##5
47 #define MAKE_STREAMOUT_6(word) MAKE_STREAMOUT_5(word)>>word##6
48 #define MAKE_STREAMOUT_7(word) MAKE_STREAMOUT_6(word)>>word##7
49 #define MAKE_STREAMOUT_8(word) MAKE_STREAMOUT_7(word)>>word##8
50 #define MAKE_STREAMOUT_9(word) MAKE_STREAMOUT_8(word)>>word##9
51 
52 #define MAKE_STREAMOUT(word,count) DO_PP(MAKE_STREAMOUT_##count(word))
53 
54 
55 
56 //Make list puts an 'word' with the index prepended separated by ","
57 //Example MAKE_LIST_1(A) output A1
58 //Example MAKE_LIST_2(A) output A1,A2
59 #define MAKE_LIST_1(word) word##1
60 #define MAKE_LIST_2(word) MAKE_LIST_1(word),word##2
61 #define MAKE_LIST_3(word) MAKE_LIST_2(word),word##3
62 #define MAKE_LIST_4(word) MAKE_LIST_3(word),word##4
63 #define MAKE_LIST_5(word) MAKE_LIST_4(word),word##5
64 #define MAKE_LIST_6(word) MAKE_LIST_5(word),word##6
65 #define MAKE_LIST_7(word) MAKE_LIST_6(word),word##7
66 #define MAKE_LIST_8(word) MAKE_LIST_7(word),word##8
67 #define MAKE_LIST_9(word) MAKE_LIST_8(word),word##9
68 
69 #define MAKE_LIST(word,count) DO_PP(MAKE_LIST_##count(word))
70 
71 //Make multilist puts two words 'first' then 'second' each with the index of the
72 //pair, prepended separated by ","
73 //Example MAKE_MULTILIST_1(A,::B) output A1::B1
74 //Example MAKE_MULTILIST_2(A,::B) output A1::B1,A2::B2
75 #define MAKE_MULTILIST_1(first,second) first##1 second##1
76 #define MAKE_MULTILIST_2(first,second) MAKE_MULTILIST_1(first,second),first##2 second##2
77 #define MAKE_MULTILIST_3(first,second) MAKE_MULTILIST_2(first,second),first##3 second##3
78 #define MAKE_MULTILIST_4(first,second) MAKE_MULTILIST_3(first,second),first##4 second##4
79 #define MAKE_MULTILIST_5(first,second) MAKE_MULTILIST_4(first,second),first##5 second##5
80 #define MAKE_MULTILIST_6(first,second) MAKE_MULTILIST_5(first,second),first##6 second##6
81 #define MAKE_MULTILIST_7(first,second) MAKE_MULTILIST_6(first,second),first##7 second##7
82 #define MAKE_MULTILIST_8(first,second) MAKE_MULTILIST_7(first,second),first##8 second##8
83 #define MAKE_MULTILIST_9(first,second) MAKE_MULTILIST_8(first,second),first##9 second##9
84 
85 #define MAKE_MULTILIST(first,second,count) DO_PP(MAKE_MULTILIST_##count(first,second))
86 
87 
88 //A slightly odd macro, needed to for a series of inline functions.
89 //pair, prepended separated by ","
90 //Example MAKE_CAST_CALL_1(A,B,C,D) output A1B(C,D1)
91 //Example MAKE_CAST_CALL_2(A,::B,C)output A1B(C,D1),A2B(C,D2)
92 #define MAKE_CAST_CALL_1(first,second,third,forth) first##1 second(third,forth##1)
93 #define MAKE_CAST_CALL_2(first,second,third,forth) MAKE_CAST_CALL_1(first,second,third,forth),first##2 second(third,forth##2)
94 #define MAKE_CAST_CALL_3(first,second,third,forth) MAKE_CAST_CALL_2(first,second,third,forth),first##3 second(third,forth##3)
95 #define MAKE_CAST_CALL_4(first,second,third,forth) MAKE_CAST_CALL_3(first,second,third,forth),first##4 second(third,forth##4)
96 #define MAKE_CAST_CALL_5(first,second,third,forth) MAKE_CAST_CALL_4(first,second,third,forth),first##5 second(third,forth##5)
97 #define MAKE_CAST_CALL_6(first,second,third,forth) MAKE_CAST_CALL_5(first,second,third,forth),first##6 second(third,forth##6)
98 #define MAKE_CAST_CALL_7(first,second,third,forth) MAKE_CAST_CALL_6(first,second,third,forth),first##7 second(third,forth##7)
99 #define MAKE_CAST_CALL_8(first,second,third,forth) MAKE_CAST_CALL_7(first,second,third,forth),first##8 second(third,forth##8)
100 #define MAKE_CAST_CALL_9(first,second,third,forth) MAKE_CAST_CALL_8(first,second,third,forth),first##9 second(third,forth##9)
101 
102 #define MAKE_CAST_CALL(first,second,third,forth,count) DO_PP(MAKE_CAST_CALL_##count(first,second,third,forth))
103 
104 
105 //Make list puts an 'word' with the index prepended separated by ";"
106 //Example MAKE_DECL_LIST_1(int A) output int A
107 //Example MAKE_DECL_LIST_1(int A) output int A1; int A2
108 #define MAKE_DECL_LIST_1(word) word##1
109 #define MAKE_DECL_LIST_2(word) MAKE_DECL_LIST_1(word);word##2
110 #define MAKE_DECL_LIST_3(word) MAKE_DECL_LIST_2(word);word##3
111 #define MAKE_DECL_LIST_4(word) MAKE_DECL_LIST_3(word);word##4
112 #define MAKE_DECL_LIST_5(word) MAKE_DECL_LIST_4(word);word##5
113 #define MAKE_DECL_LIST_6(word) MAKE_DECL_LIST_5(word);word##6
114 #define MAKE_DECL_LIST_7(word) MAKE_DECL_LIST_6(word);word##7
115 #define MAKE_DECL_LIST_8(word) MAKE_DECL_LIST_7(word);word##8
116 #define MAKE_DECL_LIST_9(word) MAKE_DECL_LIST_8(word);word##9
117 
118 #define MAKE_DECL_LIST(word,count) DO_PP(MAKE_DECL_LIST_##count(word))
119 
120 //Make list puts an 'word' with the index prepended separated by ";"
121 //Example MAKE_DECL_LIST_1(int A) output int A
122 //Example MAKE_DECL_LIST_1(int A) output int A1; int A2
123 #define MAKE_DECL_MULTILIST_1(first,second) first##1 second##1
124 #define MAKE_DECL_MULTILIST_2(first,second) MAKE_DECL_MULTILIST_1(first,second);first##2 second##2
125 #define MAKE_DECL_MULTILIST_3(first,second) MAKE_DECL_MULTILIST_2(first,second);first##3 second##3
126 #define MAKE_DECL_MULTILIST_4(first,second) MAKE_DECL_MULTILIST_3(first,second);first##4 second##4
127 #define MAKE_DECL_MULTILIST_5(first,second) MAKE_DECL_MULTILIST_4(first,second);first##5 second##5
128 #define MAKE_DECL_MULTILIST_6(first,second) MAKE_DECL_MULTILIST_5(first,second);first##6 second##6
129 #define MAKE_DECL_MULTILIST_7(first,second) MAKE_DECL_MULTILIST_6(first,second);first##7 second##7
130 #define MAKE_DECL_MULTILIST_8(first,second) MAKE_DECL_MULTILIST_7(first,second);first##8 second##8
131 #define MAKE_DECL_MULTILIST_9(first,second) MAKE_DECL_MULTILIST_8(first,second);first##9 second##9
132 
133 #define MAKE_DECL_MULTILIST(first,second,count) DO_PP(MAKE_DECL_MULTILIST_##count(first,second))
134 
135 #ifdef _WIN32
136 #define EXPORT_TEMPLATE_TYPEDEF(C,TD)\
137  typedef C TD;
138 #else
139 #define EXPORT_TEMPLATE_TYPEDEF(C,TD)\
140  typedef C TD;\
141  template class C;
142 #endif
143 
144 // FAST_REPEATED_CALL implements/mimics Duff's Device.
145 // A Google search will provide examples and explanations.
146 #define FAST_REPEATED_CALL(count,x) \
147 { \
148  if(count > 0) \
149  { \
150  size_t __FAST_ITERATE_count = count;\
151  size_t __FAST_ITERATE_n = (__FAST_ITERATE_count + 7) >> 3; \
152  switch (__FAST_ITERATE_count & 7) \
153  { \
154  case 0: do { x;\
155  case 7: x; \
156  case 6: x; \
157  case 5: x; \
158  case 4: x; \
159  case 3: x; \
160  case 2: x; \
161  case 1: x; \
162  } while (--__FAST_ITERATE_n > 0);\
163  }\
164  }\
165 }
166 
167 
168 namespace makVrv
169 {
170 
171 //Used to search a key in a map, and return NULL if it is not found.
172 template <typename K,typename V, typename Pr,typename Alloc>
173 V* DtFindPointerInMap(const std::map<K,V,Pr,Alloc>& map,K key)
174 {
175  typename std::map<K,V,Pr,Alloc>::const_iterator iter = map.find(key);
176  if(iter == map.end())
177  {
178  return 0;
179  }
180  else
181  {
182  return const_cast<V*>(&iter->second);
183  }
184 }
185 
191 template <typename M>
193 {
194  typename M::mapped_type ptr;
195  typename M::iterator curIter = map.begin();
196  typename M::const_iterator endIter = map.end();
197  for ( ; curIter != endIter; ++curIter )
198  {
199  ptr = curIter->second;
200  curIter->second = 0;
201  delete ptr;
202  }
203  map.clear();
204 }
205 
211 template <typename V>
213 {
214  typename V::value_type ptr;
215  typename V::iterator curIter = vec.begin();
216  typename V::const_iterator endIter = vec.end();
217  for ( ; curIter != endIter; ++curIter )
218  {
219  ptr = *curIter;
220  (*curIter) = 0;
221  delete ptr;
222  }
223  vec.clear();
224 }
225 
226 template <typename Iter>
227 void DtDeletePointersInIterators(Iter begin, Iter end)
228 {
229  for(Iter cur = begin;cur != end;++cur)
230  {
231  delete *cur;
232  }
233 }
234 
235 template <typename Key, typename Value>
237 {
238  inline bool operator()(const std::pair<Key,Value>& a, const std::pair<Key,Value>& b) const
239  {
240  return a.first < b.first;
241  }
242 };
243 
244 
254 template <typename T,typename R,typename A>
255 std::binder1st<std::mem_fun1_t<R,T,A> > callMemberFunction(R (T::*memfun)(A),T* ptr)
256 {
257  return std::bind1st(std::mem_fun(memfun),ptr);
258 }
259 
260 template <typename T,typename R,typename A>
261 std::binder1st<std::mem_fun1_t<R,T,A> > callMemberRefFunction(R (T::*memfun)(A&),T* ptr)
262 {
263  return std::bind1st(std::mem_fun(memfun),ptr);
264 }
265 
266 template <typename T,typename R,typename A>
267 std::binder1st<std::mem_fun1_t<R,T,A> > callMemberConstRefFunction(R (T::*memfun)(const A&),T* ptr)
268 {
269  return std::bind1st(std::mem_fun(memfun),ptr);
270 }
271 
272 template <typename T,typename R,typename A,typename Col>
273 void forEachCallMember( T* _this, R (T::*memfun)(A),Col& col)
274 {
275  typename Col::iterator curIter = col.begin();
276  typename Col::iterator endIter = col.end();
277  for(;curIter != endIter;++curIter)
278  {
279  (_this->*memfun)(*curIter);
280  }
281 }
282 
283 template <typename Ret,typename AT,typename Class>
284 Ret callConstFunction1(const Class* _this,
285  const Ret (Class::* memberPtr)(AT) const,
286  AT param)
287 {
288  return const_cast<Ret>(_this->*(memberPtr)(param));
289 }
290 
291 class DtDe;
292 
293 template <typename T, void(T::*MF)()>
294 void DtMemberFunctionCallback(DtDe* de,void* data)
295 {
296  (((T*)data)->*MF)();
297 }
298 
299 template <class InputIterator1, class InputIterator2, class OutputIterator1,class OutputIterator2>
300 void set_split_difference ( InputIterator1 first1, InputIterator1 last1,
301  InputIterator2 first2, InputIterator2 last2,
302  OutputIterator1 result1,
303  OutputIterator2 result2 )
304 {
305  while (first1!=last1 && first2!=last2)
306  {
307  if (*first1<*first2)
308  {
309  *result1++ = *first1++;
310  }
311  else if (*first2<*first1)
312  {
313  *result2++ = *first2++;
314  }
315  else
316  {
317  first1++;
318  first2++;
319  }
320 
321  }
322  copy(first1,last1,result1);
323  copy(first2,last2,result2);
324 }
325 
326 //#include <boost/bind.hpp>
327 //#include <boost/signals.hpp>
328 //
329 //template <typename Argument>
330 //void forwardSignal(boost::signal<void (Argument)>& emitter,
332 //{
338 //}
339 //
340 //template <typename Argument,typename Argument2>
341 //void forwardSignal(boost::signal<void (Argument,Argument2)>& emitter,
343 //{
349 //}
350 
351 template <typename iter, typename T>
352 iter fasterFind(size_t size, iter begin, iter end,const T& value)
353 {
354  FAST_REPEATED_CALL(size, {if(*begin == value) return begin; else ++begin;} )
355  return end;
356 }
357 
358 template <typename iter, typename F>
359 iter fastFindPred(size_t size, iter begin, iter end,const F& pred)
360 {
361  FAST_REPEATED_CALL(size, {if(pred(*begin)) return begin; else ++begin;} )
362  return end;
363 }
364 
365 template <typename T, typename Ax >
366 void fastEraseFromUnsortedVector(std::vector<T,Ax>& list, const T& value)
367 {
368  size_t size = list.size();
369  if(size == 0)
370  {
371  return;
372  }
373  else if(size == 1)
374  {
375  list.resize(0);
376  }
377  else
378  {
379  typename std::vector<T,Ax>::iterator i = fasterFind(size,list.begin(),list.end(),value);
380  if(i != list.end())
381  {
382  if(&(*i) != &list.back())
383  {
384  *i = list.back();
385  }
386  list.resize(size - 1);
387  }
388  }
389 }
390 
391 template <typename T, typename Ax >
392 void fastEraseFromUnsortedVector(std::vector<T*,Ax>& list, const T* value)
393 {
394  size_t size = list.size();
395  if(size == 0)
396  {
397  return;
398  }
399  else if(size == 1)
400  {
401  list.resize(0);
402  }
403  else
404  {
405  typename std::vector<T*,Ax>::iterator i = fasterFind(size,list.begin(),list.end(),value);
406  if(i != list.end())
407  {
408  if(&(*i) != &list.back())
409  {
410  *i = list.back();
411  }
412  list.resize(size - 1);
413  }
414  }
415 }
416 
417 template <typename T, typename Ax, typename Function >
418 void fastEraseFromUnsortedVectorPred(std::vector<T,Ax>& list, const Function& f)
419 {
420  size_t size = list.size();
421  if(size == 0)
422  {
423  return;
424  }
425  else if(size == 1)
426  {
427  list.resize(0);
428  }
429  else
430  {
431  typename std::vector<T,Ax>::iterator i = fastFindPred(size,list.begin(),list.end(),f);
432  if(i != list.end())
433  {
434  if(&(*i) != &list.back())
435  {
436  *i = list.back();
437  }
438  list.resize(size - 1);
439  }
440  }
441 }
442 
443 template <typename T, typename Ax, typename Function>
444 void fastEraseFromUnsortedVectorPred(std::vector<T*,Ax>& list, const Function& f)
445 {
446  size_t size = list.size();
447  if(size == 0)
448  {
449  return;
450  }
451  else if(size == 1)
452  {
453  list.resize(0);
454  }
455  else
456  {
457  typename std::vector<T*,Ax>::iterator i =fastFindPred(size,list.begin(),list.end(), f );
458  if(i != list.end())
459  {
460  if(&(*i) != &list.back())
461  {
462  *i = list.back();
463  }
464  list.resize(size - 1);
465  }
466  }
467 }
468 
469 template <typename Ret, typename T>
471 {
472  typedef Ret (T::*MemberFnPtr)() const;
474 
476  : myPtr(memFun)
477  {
478  }
479 
481  : myPtr(second.myPtr)
482  {
483  }
484 
485  bool operator()(const T* a, const T* b) const
486  {
487  return (a->*myPtr)() < (b->*myPtr)();
488  }
489 };
490 
491 template <typename Ret, typename T>
493 {
495 }
496 
497 template <typename Ret, typename T>
499 {
500  typedef Ret (T::*MemberFnPtr)() const;
502  Ret myValue;
503 
505  : myPtr(memFun)
506  , myValue(value)
507  {
508  }
509 
511  : myPtr(second.myPtr)
512  , myValue(second.myValue)
513  {
514  }
515 
516  bool operator()(const T* a) const
517  {
518  return (a->*myPtr)() == myValue;
519  }
520 };
521 
522 template <typename Ret, typename T>
523 inline EqualPointerByFunction_T<Ret,T> EqualPointerByFunction(Ret (T::*ptr)() const,Ret value)
524 {
525  return EqualPointerByFunction_T<Ret,T>(ptr,value);
526 }
527 
529 template <typename K,typename V>
530 const V& findOrThrow(const std::map<K,V,std::less<K>, std::allocator<std::pair<const K, V> > >& map, K key)
531 {
532  typename std::map<K,V>::const_iterator iter = map.find(key);
533  if(iter == map.end())
534  {
535  DtTHROW_NEW(DtInvalidInput,"Unable to find key");
536  }
537  return iter->second;
538 }
539 
541 template <typename K,typename V>
542 const V& findByIndexOrThrow(const std::map<K,V,std::less<K>, std::allocator<std::pair<const K, V> > >& map, int index)
543 {
544  if(index >= (int)map.size())
545  {
546  DtTHROW_NEW(DtInvalidInput,"Index out of range.");
547  }
548  typename std::map<K,V>::const_iterator i = map.begin();
549  std::advance(i,index);
550  return i->second;
551 }
552 
554 template <typename V>
555 const V& findByIndexOrThrow(const std::vector<V>& vec, int index)
556 {
557  if(index >= (int)vec.size())
558  {
559  DtTHROW_NEW(DtInvalidInput,"Index out of range.");
560  }
561  typename std::vector<V>::const_iterator i = vec.begin();
562  std::advance(i,index);
563  return *i;
564 }
565 
566 
567 }

Document ID: Generated on Mon Apr 8 19:24:01 EDT 2013 from SVN revision 125877
Copyright © 2005-2013 VT MÄK. All Rights Reserved (www.mak.com)