VR-Forces 4.0.4 Class Documentation
include/vrvUtil/templateUtil.h
Go to the documentation of this file.
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 }

Document ID: Generated on Fri Jun 29 16:33:32 EDT 2012 from SVN revision 116588
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)