VR-Vantage 1.4.1 API Class Documentation
templateUtil.h
Go to the documentation of this file.
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


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