![]() |
VR-Vantage 1.4.1 API Class Documentation
|
00001 /****************************************************************************** 00002 ** Copyright (c) 2007 MAK Technologies, Inc. 00003 ** All rights reserved. 00004 ******************************************************************************/ 00005 /****************************************************************************** 00006 ** $RCSfile: templateUtil.h,v $ $Revision: 1.28 $ $State: Exp $ 00007 ******************************************************************************/ 00008 00011 00012 #ifndef igTemplateUtil_H_ 00013 #define igTemplateUtil_H_ 00014 00015 #include <vlutil/vlExceptions.h> 00016 #include <functional> 00017 #include <algorithm> 00018 #include <vector> 00019 #include <map> 00020 00021 //Expand the provide macro. 00022 #define DO_PP(MACRO) MACRO 00023 00024 //Theses macros make it easy to define VAR-ARG template classes. 00025 00026 //Make stream puts an 'word' with the index prepended separated by "<<" 00027 //Example MAKE_STREAM_1(A) output A1 00028 //Example MAKE_STREAM_2(A) output A1 << A2 00029 #define MAKE_STREAM_1(word) word##1 00030 #define MAKE_STREAM_2(word) MAKE_STREAM_1(word)<<word##2 00031 #define MAKE_STREAM_3(word) MAKE_STREAM_2(word)<<word##3 00032 #define MAKE_STREAM_4(word) MAKE_STREAM_3(word)<<word##4 00033 #define MAKE_STREAM_5(word) MAKE_STREAM_4(word)<<word##5 00034 #define MAKE_STREAM_6(word) MAKE_STREAM_5(word)<<word##6 00035 #define MAKE_STREAM_7(word) MAKE_STREAM_6(word)<<word##7 00036 #define MAKE_STREAM_8(word) MAKE_STREAM_7(word)<<word##8 00037 #define MAKE_STREAM_9(word) MAKE_STREAM_8(word)<<word##9 00038 00039 #define MAKE_STREAM(word,count) DO_PP(MAKE_STREAM_##count(word)) 00040 00041 00042 //Make stream puts an 'word' with the index prepended separated by ">>" 00043 //Example MAKE_STREAMOUT_1(A) output A1 00044 //Example MAKE_STREAMOUT_2(A) output A1 >> A2 00045 #define MAKE_STREAMOUT_1(word) word##1 00046 #define MAKE_STREAMOUT_2(word) MAKE_STREAMOUT_1(word)>>word##2 00047 #define MAKE_STREAMOUT_3(word) MAKE_STREAMOUT_2(word)>>word##3 00048 #define MAKE_STREAMOUT_4(word) MAKE_STREAMOUT_3(word)>>word##4 00049 #define MAKE_STREAMOUT_5(word) MAKE_STREAMOUT_4(word)>>word##5 00050 #define MAKE_STREAMOUT_6(word) MAKE_STREAMOUT_5(word)>>word##6 00051 #define MAKE_STREAMOUT_7(word) MAKE_STREAMOUT_6(word)>>word##7 00052 #define MAKE_STREAMOUT_8(word) MAKE_STREAMOUT_7(word)>>word##8 00053 #define MAKE_STREAMOUT_9(word) MAKE_STREAMOUT_8(word)>>word##9 00054 00055 #define MAKE_STREAMOUT(word,count) DO_PP(MAKE_STREAMOUT_##count(word)) 00056 00057 00058 00059 //Make list puts an 'word' with the index prepended separated by "," 00060 //Example MAKE_LIST_1(A) output A1 00061 //Example MAKE_LIST_2(A) output A1,A2 00062 #define MAKE_LIST_1(word) word##1 00063 #define MAKE_LIST_2(word) MAKE_LIST_1(word),word##2 00064 #define MAKE_LIST_3(word) MAKE_LIST_2(word),word##3 00065 #define MAKE_LIST_4(word) MAKE_LIST_3(word),word##4 00066 #define MAKE_LIST_5(word) MAKE_LIST_4(word),word##5 00067 #define MAKE_LIST_6(word) MAKE_LIST_5(word),word##6 00068 #define MAKE_LIST_7(word) MAKE_LIST_6(word),word##7 00069 #define MAKE_LIST_8(word) MAKE_LIST_7(word),word##8 00070 #define MAKE_LIST_9(word) MAKE_LIST_8(word),word##9 00071 00072 #define MAKE_LIST(word,count) DO_PP(MAKE_LIST_##count(word)) 00073 00074 //Make multilist puts two words 'first' then 'second' each with the index of the 00075 //pair, prepended separated by "," 00076 //Example MAKE_MULTILIST_1(A,::B) output A1::B1 00077 //Example MAKE_MULTILIST_2(A,::B) output A1::B1,A2::B2 00078 #define MAKE_MULTILIST_1(first,second) first##1 second##1 00079 #define MAKE_MULTILIST_2(first,second) MAKE_MULTILIST_1(first,second),first##2 second##2 00080 #define MAKE_MULTILIST_3(first,second) MAKE_MULTILIST_2(first,second),first##3 second##3 00081 #define MAKE_MULTILIST_4(first,second) MAKE_MULTILIST_3(first,second),first##4 second##4 00082 #define MAKE_MULTILIST_5(first,second) MAKE_MULTILIST_4(first,second),first##5 second##5 00083 #define MAKE_MULTILIST_6(first,second) MAKE_MULTILIST_5(first,second),first##6 second##6 00084 #define MAKE_MULTILIST_7(first,second) MAKE_MULTILIST_6(first,second),first##7 second##7 00085 #define MAKE_MULTILIST_8(first,second) MAKE_MULTILIST_7(first,second),first##8 second##8 00086 #define MAKE_MULTILIST_9(first,second) MAKE_MULTILIST_8(first,second),first##9 second##9 00087 00088 #define MAKE_MULTILIST(first,second,count) DO_PP(MAKE_MULTILIST_##count(first,second)) 00089 00090 00091 //A slightly odd macro, needed to for a series of inline functions. 00092 //pair, prepended separated by "," 00093 //Example MAKE_CAST_CALL_1(A,B,C,D) output A1B(C,D1) 00094 //Example MAKE_CAST_CALL_2(A,::B,C)output A1B(C,D1),A2B(C,D2) 00095 #define MAKE_CAST_CALL_1(first,second,third,forth) first##1 second(third,forth##1) 00096 #define MAKE_CAST_CALL_2(first,second,third,forth) MAKE_CAST_CALL_1(first,second,third,forth),first##2 second(third,forth##2) 00097 #define MAKE_CAST_CALL_3(first,second,third,forth) MAKE_CAST_CALL_2(first,second,third,forth),first##3 second(third,forth##3) 00098 #define MAKE_CAST_CALL_4(first,second,third,forth) MAKE_CAST_CALL_3(first,second,third,forth),first##4 second(third,forth##4) 00099 #define MAKE_CAST_CALL_5(first,second,third,forth) MAKE_CAST_CALL_4(first,second,third,forth),first##5 second(third,forth##5) 00100 #define MAKE_CAST_CALL_6(first,second,third,forth) MAKE_CAST_CALL_5(first,second,third,forth),first##6 second(third,forth##6) 00101 #define MAKE_CAST_CALL_7(first,second,third,forth) MAKE_CAST_CALL_6(first,second,third,forth),first##7 second(third,forth##7) 00102 #define MAKE_CAST_CALL_8(first,second,third,forth) MAKE_CAST_CALL_7(first,second,third,forth),first##8 second(third,forth##8) 00103 #define MAKE_CAST_CALL_9(first,second,third,forth) MAKE_CAST_CALL_8(first,second,third,forth),first##9 second(third,forth##9) 00104 00105 #define MAKE_CAST_CALL(first,second,third,forth,count) DO_PP(MAKE_CAST_CALL_##count(first,second,third,forth)) 00106 00107 00108 //Make list puts an 'word' with the index prepended separated by ";" 00109 //Example MAKE_DECL_LIST_1(int A) output int A 00110 //Example MAKE_DECL_LIST_1(int A) output int A1; int A2 00111 #define MAKE_DECL_LIST_1(word) word##1 00112 #define MAKE_DECL_LIST_2(word) MAKE_DECL_LIST_1(word);word##2 00113 #define MAKE_DECL_LIST_3(word) MAKE_DECL_LIST_2(word);word##3 00114 #define MAKE_DECL_LIST_4(word) MAKE_DECL_LIST_3(word);word##4 00115 #define MAKE_DECL_LIST_5(word) MAKE_DECL_LIST_4(word);word##5 00116 #define MAKE_DECL_LIST_6(word) MAKE_DECL_LIST_5(word);word##6 00117 #define MAKE_DECL_LIST_7(word) MAKE_DECL_LIST_6(word);word##7 00118 #define MAKE_DECL_LIST_8(word) MAKE_DECL_LIST_7(word);word##8 00119 #define MAKE_DECL_LIST_9(word) MAKE_DECL_LIST_8(word);word##9 00120 00121 #define MAKE_DECL_LIST(word,count) DO_PP(MAKE_DECL_LIST_##count(word)) 00122 00123 //Make list puts an 'word' with the index prepended separated by ";" 00124 //Example MAKE_DECL_LIST_1(int A) output int A 00125 //Example MAKE_DECL_LIST_1(int A) output int A1; int A2 00126 #define MAKE_DECL_MULTILIST_1(first,second) first##1 second##1 00127 #define MAKE_DECL_MULTILIST_2(first,second) MAKE_DECL_MULTILIST_1(first,second);first##2 second##2 00128 #define MAKE_DECL_MULTILIST_3(first,second) MAKE_DECL_MULTILIST_2(first,second);first##3 second##3 00129 #define MAKE_DECL_MULTILIST_4(first,second) MAKE_DECL_MULTILIST_3(first,second);first##4 second##4 00130 #define MAKE_DECL_MULTILIST_5(first,second) MAKE_DECL_MULTILIST_4(first,second);first##5 second##5 00131 #define MAKE_DECL_MULTILIST_6(first,second) MAKE_DECL_MULTILIST_5(first,second);first##6 second##6 00132 #define MAKE_DECL_MULTILIST_7(first,second) MAKE_DECL_MULTILIST_6(first,second);first##7 second##7 00133 #define MAKE_DECL_MULTILIST_8(first,second) MAKE_DECL_MULTILIST_7(first,second);first##8 second##8 00134 #define MAKE_DECL_MULTILIST_9(first,second) MAKE_DECL_MULTILIST_8(first,second);first##9 second##9 00135 00136 #define MAKE_DECL_MULTILIST(first,second,count) DO_PP(MAKE_DECL_MULTILIST_##count(first,second)) 00137 00138 #ifdef _WIN32 00139 #define EXPORT_TEMPLATE_TYPEDEF(C,TD)\ 00140 typedef C TD; 00141 #else 00142 #define EXPORT_TEMPLATE_TYPEDEF(C,TD)\ 00143 typedef C TD;\ 00144 template class C; 00145 #endif 00146 00147 #define FAST_REPEATED_CALL(count,x) \ 00148 { \ 00149 if(count > 0) \ 00150 { \ 00151 size_t __FAST_ITERATE_count = count;\ 00152 size_t __FAST_ITERATE_n = (__FAST_ITERATE_count + 7) >> 3; \ 00153 switch (__FAST_ITERATE_count & 7) \ 00154 { \ 00155 case 0: do { x;\ 00156 case 7: x; \ 00157 case 6: x; \ 00158 case 5: x; \ 00159 case 4: x; \ 00160 case 3: x; \ 00161 case 2: x; \ 00162 case 1: x; \ 00163 } while (--__FAST_ITERATE_n > 0);\ 00164 }\ 00165 }\ 00166 } 00167 00168 00169 namespace makVrv 00170 { 00171 00172 //Used to search a key in a map, and return NULL if it is not found. 00173 template <typename K,typename V, typename Pr,typename Alloc> 00174 V* DtFindPointerInMap(const std::map<K,V,Pr,Alloc>& map,K key) 00175 { 00176 typename std::map<K,V,Pr,Alloc>::const_iterator iter = map.find(key); 00177 if(iter == map.end()) 00178 { 00179 return 0; 00180 } 00181 else 00182 { 00183 return const_cast<V*>(&iter->second); 00184 } 00185 } 00186 00187 template <typename M> 00188 void DtClearAndDeletePointersInMap(M& map) 00189 { 00190 typename M::const_iterator curIter = map.begin(); typename M::const_iterator endIter = map.end(); 00191 for(;curIter != endIter;++curIter) 00192 { 00193 delete curIter->second; 00194 } 00195 map.clear(); 00196 } 00197 00198 template <typename Iter> 00199 void DtDeletePointersInIterators(Iter begin, Iter end) 00200 { 00201 for(Iter cur = begin;cur != end;++cur) 00202 { 00203 delete *cur; 00204 } 00205 } 00206 00207 template <typename Key, typename Value> 00208 struct SortByFirst 00209 { 00210 inline bool operator()(const std::pair<Key,Value>& a, const std::pair<Key,Value>& b) const 00211 { 00212 return a.first < b.first; 00213 } 00214 }; 00215 00216 00226 template <typename T,typename R,typename A> 00227 std::binder1st<std::mem_fun1_t<R,T,A> > callMemberFunction(R (T::*memfun)(A),T* ptr) 00228 { 00229 return std::bind1st(std::mem_fun(memfun),ptr); 00230 } 00231 00232 template <typename T,typename R,typename A> 00233 std::binder1st<std::mem_fun1_t<R,T,A> > callMemberRefFunction(R (T::*memfun)(A&),T* ptr) 00234 { 00235 return std::bind1st(std::mem_fun(memfun),ptr); 00236 } 00237 00238 template <typename T,typename R,typename A> 00239 std::binder1st<std::mem_fun1_t<R,T,A> > callMemberConstRefFunction(R (T::*memfun)(const A&),T* ptr) 00240 { 00241 return std::bind1st(std::mem_fun(memfun),ptr); 00242 } 00243 00244 template <typename T,typename R,typename A,typename Col> 00245 void forEachCallMember( T* _this, R (T::*memfun)(A),Col& col) 00246 { 00247 typename Col::iterator curIter = col.begin(); 00248 typename Col::iterator endIter = col.end(); 00249 for(;curIter != endIter;++curIter) 00250 { 00251 (_this->*memfun)(*curIter); 00252 } 00253 } 00254 00255 template <typename Ret,typename AT,typename Class> 00256 Ret callConstFunction1(const Class* _this, 00257 const Ret (Class::* memberPtr)(AT) const, 00258 AT param) 00259 { 00260 return const_cast<Ret>(_this->*(memberPtr)(param)); 00261 } 00262 00263 class DtDe; 00264 00265 template <typename T, void(T::*MF)()> 00266 void DtMemberFunctionCallback(DtDe* de,void* data) 00267 { 00268 (((T*)data)->*MF)(); 00269 } 00270 00271 00272 00273 template <class InputIterator1, class InputIterator2, class OutputIterator1,class OutputIterator2> 00274 void set_split_difference ( InputIterator1 first1, InputIterator1 last1, 00275 InputIterator2 first2, InputIterator2 last2, 00276 OutputIterator1 result1, 00277 OutputIterator2 result2 ) 00278 { 00279 while (first1!=last1 && first2!=last2) 00280 { 00281 if (*first1<*first2) 00282 { 00283 *result1++ = *first1++; 00284 } 00285 else if (*first2<*first1) 00286 { 00287 *result2++ = *first2++; 00288 } 00289 else 00290 { 00291 first1++; 00292 first2++; 00293 } 00294 00295 } 00296 copy(first1,last1,result1); 00297 copy(first2,last2,result2); 00298 } 00299 00300 //#include <boost/bind.hpp> 00301 //#include <boost/signals.hpp> 00302 // 00303 //template <typename Argument> 00304 //void forwardSignal(boost::signal<void (Argument)>& emitter, 00306 //{ 00312 //} 00313 // 00314 //template <typename Argument,typename Argument2> 00315 //void forwardSignal(boost::signal<void (Argument,Argument2)>& emitter, 00317 //{ 00323 //} 00324 00325 template <typename iter, typename T> 00326 iter fasterFind(size_t size, iter begin, iter end,const T& value) 00327 { 00328 FAST_REPEATED_CALL(size, {if(*begin == value) return begin; else ++begin;} ) 00329 return end; 00330 } 00331 00332 template <typename iter, typename F> 00333 iter fastFindPred(size_t size, iter begin, iter end,const F& pred) 00334 { 00335 FAST_REPEATED_CALL(size, {if(pred(*begin)) return begin; else ++begin;} ) 00336 return end; 00337 } 00338 00339 template <typename T, typename Ax > 00340 void fastEraseFromUnsortedVector(std::vector<T,Ax>& list, const T& value) 00341 { 00342 size_t size = list.size(); 00343 if(size == 0) 00344 { 00345 return; 00346 } 00347 else if(size == 1) 00348 { 00349 list.resize(0); 00350 } 00351 else 00352 { 00353 typename std::vector<T,Ax>::iterator i = fasterFind(size,list.begin(),list.end(),value); 00354 if(i != list.end()) 00355 { 00356 if(&(*i) != &list.back()) 00357 { 00358 *i = list.back(); 00359 } 00360 list.resize(size - 1); 00361 } 00362 } 00363 } 00364 00365 template <typename T, typename Ax > 00366 void fastEraseFromUnsortedVector(std::vector<T*,Ax>& list, const T* value) 00367 { 00368 size_t size = list.size(); 00369 if(size == 0) 00370 { 00371 return; 00372 } 00373 else if(size == 1) 00374 { 00375 list.resize(0); 00376 } 00377 else 00378 { 00379 typename std::vector<T*,Ax>::iterator i = fasterFind(size,list.begin(),list.end(),value); 00380 if(i != list.end()) 00381 { 00382 if(&(*i) != &list.back()) 00383 { 00384 *i = list.back(); 00385 } 00386 list.resize(size - 1); 00387 } 00388 } 00389 } 00390 00391 template <typename T, typename Ax, typename Function > 00392 void fastEraseFromUnsortedVectorPred(std::vector<T,Ax>& list, const Function& f) 00393 { 00394 size_t size = list.size(); 00395 if(size == 0) 00396 { 00397 return; 00398 } 00399 else if(size == 1) 00400 { 00401 list.resize(0); 00402 } 00403 else 00404 { 00405 typename std::vector<T,Ax>::iterator i = fastFindPred(size,list.begin(),list.end(),f); 00406 if(i != list.end()) 00407 { 00408 if(&(*i) != &list.back()) 00409 { 00410 *i = list.back(); 00411 } 00412 list.resize(size - 1); 00413 } 00414 } 00415 } 00416 00417 template <typename T, typename Ax, typename Function > 00418 void fastEraseFromUnsortedVectorPred(std::vector<T*,Ax>& list, const Function& f) 00419 { 00420 size_t size = list.size(); 00421 if(size == 0) 00422 { 00423 return; 00424 } 00425 else if(size == 1) 00426 { 00427 list.resize(0); 00428 } 00429 else 00430 { 00431 typename std::vector<T*,Ax>::iterator i =fastFindPred(size,list.begin(),list.end(), f ); 00432 if(i != list.end()) 00433 { 00434 if(&(*i) != &list.back()) 00435 { 00436 *i = list.back(); 00437 } 00438 list.resize(size - 1); 00439 } 00440 } 00441 } 00442 00443 template <typename Ret, typename T> 00444 struct SortPointersByFunction_T 00445 { 00446 typedef Ret (T::*MemberFnPtr)() const; 00447 MemberFnPtr myPtr; 00448 00449 SortPointersByFunction_T(MemberFnPtr memFun) 00450 : myPtr(memFun) 00451 { 00452 } 00453 00454 SortPointersByFunction_T(const SortPointersByFunction_T<Ret,T>& second) 00455 : myPtr(second.myPtr) 00456 { 00457 } 00458 00459 bool operator()(const T* a, const T* b) const 00460 { 00461 return (a->*myPtr)() < (b->*myPtr)(); 00462 } 00463 }; 00464 00465 template <typename Ret, typename T> 00466 inline SortPointersByFunction_T<Ret,T> SortPointersByFunction(Ret (T::*ptr)() const) 00467 { 00468 return SortPointersByFunction_T<Ret,T>(ptr); 00469 } 00470 00471 template <typename Ret, typename T> 00472 struct EqualPointerByFunction_T 00473 { 00474 typedef Ret (T::*MemberFnPtr)() const; 00475 MemberFnPtr myPtr; 00476 Ret myValue; 00477 00478 EqualPointerByFunction_T(MemberFnPtr memFun, Ret value) 00479 : myPtr(memFun) 00480 , myValue(value) 00481 { 00482 } 00483 00484 EqualPointerByFunction_T(const SortPointersByFunction_T<Ret,T>& second) 00485 : myPtr(second.myPtr) 00486 , myValue(second.myValue) 00487 { 00488 } 00489 00490 bool operator()(const T* a) const 00491 { 00492 return (a->*myPtr)() == myValue; 00493 } 00494 }; 00495 00496 template <typename Ret, typename T> 00497 inline EqualPointerByFunction_T<Ret,T> EqualPointerByFunction(Ret (T::*ptr)() const,Ret value) 00498 { 00499 return EqualPointerByFunction_T<Ret,T>(ptr,value); 00500 } 00501 00503 template <typename K,typename V> 00504 const V& findOrThrow(const std::map<K,V,std::less<K>, std::allocator<std::pair<const K, V> > >& map, K key) 00505 { 00506 typename std::map<K,V>::const_iterator iter = map.find(key); 00507 if(iter == map.end()) 00508 { 00509 DtTHROW_NEW(DtInvalidInput,"Unable to find key"); 00510 } 00511 return iter->second; 00512 } 00513 00515 template <typename K,typename V> 00516 const V& findByIndexOrThrow(const std::map<K,V,std::less<K>, std::allocator<std::pair<const K, V> > >& map, int index) 00517 { 00518 if(index >= (int)map.size()) 00519 { 00520 DtTHROW_NEW(DtInvalidInput,"Index out of range."); 00521 } 00522 typename std::map<K,V>::const_iterator i = map.begin(); 00523 std::advance(i,index); 00524 return i->second; 00525 } 00526 00528 template <typename V> 00529 const V& findByIndexOrThrow(const std::vector<V>& vec, int index) 00530 { 00531 if(index >= (int)vec.size()) 00532 { 00533 DtTHROW_NEW(DtInvalidInput,"Index out of range."); 00534 } 00535 typename std::vector<V>::const_iterator i = vec.begin(); 00536 std::advance(i,index); 00537 return *i; 00538 } 00539 00540 00541 } 00542 00543 #endif