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