VR-Vantage API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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)()>
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
374  {
375  typename std::vector<T,Ax>::iterator i = fasterFind(size,list.begin(),list.end(),value);
376  if(i != list.end())
377  {
378  if(size == 1)
379  {
380  list.resize(0);
381  }
382  else
383  {
384  if(&(*i) != &list.back())
385  {
386  *i = list.back();
387  }
388  list.resize(size - 1);
389  }
390  }
391  }
392 }
393 
394 template <typename T, typename Ax >
395 void fastEraseFromUnsortedVector(std::vector<T*,Ax>& list, const T* value)
396 {
397  size_t size = list.size();
398  if(size == 0)
399  {
400  return;
401  }
402  else if(size == 1)
403  {
404  list.resize(0);
405  }
406  else
407  {
408  typename std::vector<T*,Ax>::iterator i = fasterFind(size,list.begin(),list.end(),value);
409  if(i != list.end())
410  {
411  if(&(*i) != &list.back())
412  {
413  *i = list.back();
414  }
415  list.resize(size - 1);
416  }
417  }
418 }
419 
420 template <typename T, typename Ax, typename Function >
421 void fastEraseFromUnsortedVectorPred(std::vector<T,Ax>& list, const Function& f)
422 {
423  size_t size = list.size();
424  if(size == 0)
425  {
426  return;
427  }
428  else if(size == 1)
429  {
430  list.resize(0);
431  }
432  else
433  {
434  typename std::vector<T,Ax>::iterator i = fastFindPred(size,list.begin(),list.end(),f);
435  if(i != list.end())
436  {
437  if(&(*i) != &list.back())
438  {
439  *i = list.back();
440  }
441  list.resize(size - 1);
442  }
443  }
444 }
445 
446 template <typename T, typename Ax, typename Function>
447 void fastEraseFromUnsortedVectorPred(std::vector<T*,Ax>& list, const Function& f)
448 {
449  size_t size = list.size();
450  if(size == 0)
451  {
452  return;
453  }
454  else if(size == 1)
455  {
456  list.resize(0);
457  }
458  else
459  {
460  typename std::vector<T*,Ax>::iterator i =fastFindPred(size,list.begin(),list.end(), f );
461  if(i != list.end())
462  {
463  if(&(*i) != &list.back())
464  {
465  *i = list.back();
466  }
467  list.resize(size - 1);
468  }
469  }
470 }
471 
472 template <typename Ret, typename T>
474 {
475  typedef Ret (T::*MemberFnPtr)() const;
477 
479  : myPtr(memFun)
480  {
481  }
482 
484  : myPtr(second.myPtr)
485  {
486  }
487 
488  bool operator()(const T* a, const T* b) const
489  {
490  return (a->*myPtr)() < (b->*myPtr)();
491  }
492 };
493 
494 template <typename Ret, typename T>
496 {
498 }
499 
500 template <typename Ret, typename T>
502 {
503  typedef Ret (T::*MemberFnPtr)() const;
505  Ret myValue;
506 
508  : myPtr(memFun)
509  , myValue(value)
510  {
511  }
512 
514  : myPtr(second.myPtr)
515  , myValue(second.myValue)
516  {
517  }
518 
519  bool operator()(const T* a) const
520  {
521  return (a->*myPtr)() == myValue;
522  }
523 };
524 
525 template <typename Ret, typename T>
527 {
529 }
530 
532 template <typename K,typename V>
533 const V& findOrThrow(const std::map<K,V,std::less<K>, std::allocator<std::pair<const K, V> > >& map, K key)
534 {
535  typename std::map<K,V>::const_iterator iter = map.find(key);
536  if(iter == map.end())
537  {
538  DtTHROW_NEW(DtInvalidInput,"Unable to find key");
539  }
540  return iter->second;
541 }
542 
544 template <typename K,typename V>
545 const V& findByIndexOrThrow(const std::map<K,V,std::less<K>, std::allocator<std::pair<const K, V> > >& map, int index)
546 {
547  if(index >= (int)map.size())
548  {
549  DtTHROW_NEW(DtInvalidInput,"Index out of range.");
550  }
551  typename std::map<K,V>::const_iterator i = map.begin();
552  std::advance(i,index);
553  return i->second;
554 }
555 
557 template <typename V>
558 const V& findByIndexOrThrow(const std::vector<V>& vec, int index)
559 {
560  if(index >= (int)vec.size())
561  {
562  DtTHROW_NEW(DtInvalidInput,"Index out of range.");
563  }
564  typename std::vector<V>::const_iterator i = vec.begin();
565  std::advance(i,index);
566  return *i;
567 }
568 
569 
570 }


Copyright © 2005-2013 VT MÄK. All Rights Reserved (www.mak.com)