arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

nrroDispatch.h

Go to the documentation of this file.
00001 //------------------------------------------------------------------------
00002 //
00003 //   Joe Kniss
00004 //     9-17-02
00005 //                   ________    ____   ___ 
00006 //                  |        \  /    | /  /
00007 //                  +---+     \/     |/  /
00008 //                  +--+|  |\    /|     < 
00009 //                  |  ||  | \  / |  |\  \ 
00010 //                  |      |  \/  |  | \  \ 
00011 //                   \_____|      |__|  \__\
00012 //                       Copyright  2002 
00013 //                      Joe Michael Kniss
00014 //                   <<< jmk@cs.utah.edu >>>
00015 //               "All Your Base are Belong to Us"
00016 //-------------------------------------------------------------------------
00017 
00018 //nrroDispatch.h
00019 
00020 /// a way to create generic functions for this typeless object
00021 
00022 #ifndef __NRRO_DISPATCH_DOT_H
00023 #define __NRRO_DISPATCH_DOT_H
00024 
00025 #include "nrro.h"
00026 
00027 ///////////////////////////////////////////////////////////////////////////
00028 /// things to call functions on nrros using typed iterators.
00029 /// these are like functions, they take NrroSP's as input, however,
00030 /// they call a function using Nrro::NrroIter<>'s, this means that
00031 /// although the function you are calling takes NrroIters you dispatch
00032 /// to them using a NrroSP (or a raw pointer).  This makes your code
00033 /// typeless even though you are "really" calling typed functions.
00034 ///////////////////////////////////////////////////////////////////////////
00035 
00036 ///////////////////////////////////////////////////////////////////////////
00037 /// call a templated function that takes 1 NrroIterator<>, using a NrroSP
00038 /// example:
00039 //
00040 // template<class T>
00041 // void myFunc(NrroIter<T> ni) {...}
00042 // ...
00043 // NrroSP n = new Nrro("some nrro file");
00044 //
00045 // dispatchIter1(myFunc, n);
00046 //
00047 // notice there is no return value
00048 ///////////////////////////////////////////////////////////////////////////
00049 
00050 #define dispatchIter1( FUNC , NSP ) \
00051    switch( NSP->getType() ) { \
00052    case Nrro::CHAR: \
00053       FUNC( NSP->begin<char>()); \
00054       break; \
00055    case Nrro::UCHAR:  \
00056       FUNC( NSP->begin<unsigned char>()); \
00057       break; \
00058    case Nrro::SHORT: \
00059       FUNC( NSP->begin<short>());  \
00060       break; \
00061    case Nrro::USHORT: \
00062       FUNC( NSP->begin<unsigned short>()); \
00063       break; \
00064    case Nrro::INT: \
00065       FUNC( NSP->begin<int>()); \
00066       break; \
00067    case Nrro::UINT: \
00068       FUNC( NSP->begin<unsigned int>()); \
00069       break; \
00070    case Nrro::FLOAT: \
00071       FUNC( NSP->begin<float>()); \
00072       break; \
00073    case Nrro::DOUBLE: \
00074       FUNC( NSP->begin<double>()); \
00075       break; \
00076    }
00077 
00078 ///////////////////////////////////////////////////////////////////////////
00079 /// call a templated function that takes 1 NrroIterator<>,
00080 /// and captures the return value
00081 /// example:
00082 //
00083 // template<class T>
00084 // <ReturnVal> myFunc(NrroIter<T> ni) {...}
00085 //
00086 // NrroSP n = new Nrro("some nrro file");
00087 // <ReturnVal> ret;
00088 //
00089 // dispatchIter1(ret, myFunc, n);
00090 //
00091 // ret should now contain the return value
00092 ///////////////////////////////////////////////////////////////////////////
00093 
00094 #define retDispatchIter1( RET, FUNC , NSP ) \
00095    switch( NSP->getType() ) { \
00096    case Nrro::CHAR: \
00097       RET = FUNC( NSP->begin<char>()); \
00098       break; \
00099    case Nrro::UCHAR:  \
00100       RET = FUNC( NSP->begin<unsigned char>()); \
00101       break; \
00102    case Nrro::SHORT: \
00103       RET = FUNC( NSP->begin<short>());  \
00104       break; \
00105    case Nrro::USHORT: \
00106       RET = FUNC( NSP->begin<unsigned short>()); \
00107       break; \
00108    case Nrro::INT: \
00109       RET = FUNC( NSP->begin<int>()); \
00110       break; \
00111    case Nrro::UINT: \
00112       RET = FUNC( NSP->begin<unsigned int>()); \
00113       break; \
00114    case Nrro::FLOAT: \
00115       RET = FUNC( NSP->begin<float>()); \
00116       break; \
00117    case Nrro::DOUBLE: \
00118       RET = FUNC( NSP->begin<double>()); \
00119       break; \
00120    }
00121 
00122 ///////////////////////////////////////////////////////////////////////////
00123 /// a helper function ignore this...
00124 ///////////////////////////////////////////////////////////////////////////
00125 #define tdis2(FUNC,NSP1,NSP2) \
00126    switch(NSP2->getType()) { \
00127    case Nrro::CHAR: \
00128       FUNC(NSP1,NSP2->begin<char>()); \
00129       break; \
00130    case Nrro::UCHAR:  \
00131       FUNC(NSP1,NSP2->begin<unsigned char>()); \
00132       break; \
00133    case Nrro::SHORT: \
00134       FUNC(NSP1,NSP2->begin<short>());  \
00135       break; \
00136    case Nrro::USHORT: \
00137       FUNC(NSP1,NSP2->begin<unsigned short>()); \
00138       break; \
00139    case Nrro::INT: \
00140       FUNC(NSP1,NSP2->begin<int>()); \
00141       break; \
00142    case Nrro::UINT: \
00143       FUNC(NSP1,NSP2->begin<unsigned int>()); \
00144       break; \
00145    case Nrro::FLOAT: \
00146       FUNC(NSP1,NSP2->begin<float>()); \
00147       break; \
00148    case Nrro::DOUBLE: \
00149       FUNC(NSP1,NSP2->begin<double>()); \
00150       break; \
00151    }
00152 
00153 ///////////////////////////////////////////////////////////////////////////
00154 /// call a templated function that takes 2 NrroIterator<>s
00155 /// example:
00156 //
00157 // template<class T1, class T2>
00158 // void myFunc(NrroIter<T1> ni1, NrroIter<T2> ni2) {...}
00159 //
00160 // NrroSP n  = new Nrro("some nrro file");
00161 // NrroSP n2 = new Nrro("some nrro file");
00162 //
00163 // dispatchIter2(myFunc, n, n2);
00164 //
00165 // notice there is no return value
00166 ///////////////////////////////////////////////////////////////////////////
00167 
00168 #define dispatchIter2(FUNC,NSP1,NSP2) \
00169    switch(NSP1->getType()) { \
00170    case Nrro::CHAR: \
00171       tdis2(FUNC,NSP1->begin<char>(),NSP2) \
00172       break; \
00173    case Nrro::UCHAR:  \
00174       tdis2(FUNC,NSP1->begin<unsigned char>(),NSP2) \
00175       break; \
00176    case Nrro::SHORT: \
00177       tdis2(FUNC,NSP1->begin<short>(),NSP2)  \
00178       break; \
00179    case Nrro::USHORT: \
00180       tdis2(FUNC,NSP1->begin<unsigned short>(),NSP2) \
00181       break; \
00182    case Nrro::INT: \
00183       tdis2(FUNC,NSP1->begin<int>(),NSP2) \
00184       break; \
00185    case Nrro::UINT: \
00186       tdis2(FUNC,NSP1->begin<unsigned int>(),NSP2) \
00187       break; \
00188    case Nrro::FLOAT: \
00189       tdis2(FUNC,NSP1->begin<float>(),NSP2) \
00190       break; \
00191    case Nrro::DOUBLE: \
00192       tdis2(FUNC,NSP1->begin<double>(),NSP2) \
00193       break; \
00194    }
00195 
00196 ///////////////////////////////////////////////////////////////////////////
00197 /// a helper function ignore this...
00198 ///////////////////////////////////////////////////////////////////////////
00199 #define retDis2(RET,FUNC,NSP1,NSP2) \
00200    switch(NSP2->getType()) { \
00201    case Nrro::CHAR: \
00202       RET = FUNC(NSP1,NSP2->begin<char>()); \
00203       break; \
00204    case Nrro::UCHAR:  \
00205       RET = FUNC(NSP1,NSP2->begin<unsigned char>()); \
00206       break; \
00207    case Nrro::SHORT: \
00208       RET = FUNC(NSP1,NSP2->begin<short>());  \
00209       break; \
00210    case Nrro::USHORT: \
00211       RET = FUNC(NSP1,NSP2->begin<unsigned short>()); \
00212       break; \
00213    case Nrro::INT: \
00214       RET = FUNC(NSP1,NSP2->begin<int>()); \
00215       break; \
00216    case Nrro::UINT: \
00217       RET = FUNC(NSP1,NSP2->begin<unsigned int>()); \
00218       break; \
00219    case Nrro::FLOAT: \
00220       RET = FUNC(NSP1,NSP2->begin<float>()); \
00221       break; \
00222    case Nrro::DOUBLE: \
00223       RET = FUNC(NSP1,NSP2->begin<double>()); \
00224       break; \
00225    }
00226 
00227 ///////////////////////////////////////////////////////////////////////////
00228 /// call a templated function that takes 2 NrroIterator<>s and
00229 /// captures the return value
00230 /// example:
00231 //
00232 // template<class T1, class T2>
00233 // <ReturnVal> myFunc(NrroIter<T1> ni1, NrroIter<T2> ni2) {...}
00234 //
00235 // NrroSP n  = new Nrro("some nrro file");
00236 // NrroSP n2 = new Nrro("some nrro file");
00237 //
00238 // <ReturnVal> r;
00239 // retDispatchIter2(r,myFunc, n, n2);
00240 //
00241 // the return value will be filled with "myFuncs" return value from
00242 // the correct typed function
00243 ///////////////////////////////////////////////////////////////////////////
00244 
00245 #define retDispatchIter2(RET,FUNC,NSP1,NSP2) \
00246    switch(NSP1->getType()) { \
00247    case Nrro::CHAR: \
00248       retDis2(RET,FUNC,NSP1->begin<char>(),NSP2) \
00249       break; \
00250    case Nrro::UCHAR:  \
00251       retDis2(RET,FUNC,NSP1->begin<unsigned char>(),NSP2) \
00252       break; \
00253    case Nrro::SHORT: \
00254       retDis2(RET,FUNC,NSP1->begin<short>(),NSP2)  \
00255       break; \
00256    case Nrro::USHORT: \
00257       retDis2(RET,FUNC,NSP1->begin<unsigned short>(),NSP2) \
00258       break; \
00259    case Nrro::INT: \
00260       retDis2(RET,FUNC,NSP1->begin<int>(),NSP2) \
00261       break; \
00262    case Nrro::UINT: \
00263       retDis2(RET,FUNC,NSP1->begin<unsigned int>(),NSP2) \
00264       break; \
00265    case Nrro::FLOAT: \
00266       retDis2(RET,FUNC,NSP1->begin<float>(),NSP2) \
00267       break; \
00268    case Nrro::DOUBLE: \
00269       retDis2(RET,FUNC,NSP1->begin<double>(),NSP2) \
00270       break; \
00271    }
00272 
00273 ///////////////////////////////////////////////////////////////////////////
00274 /// a interface clss that handles the dispatch for you,
00275 /// templated by return type
00276 /// example:
00277 //  class myCmd : public cmdDispatchIF<NrroSP>
00278 //  {
00279 //    template<class T1, class T2>
00280 //    NrroSP operator()(Nrro::NrroIter<T1> n1, NrroIter<T2> n2) {....}
00281 //  };
00282 //
00283 //  myCmd command;
00284 //  NrroSP n1 = ...
00285 //  NrroSP n2 = ...
00286 //  NrroSP retN;
00287 //  retN = command(n2,n2)
00288 ///
00289 /// There are two types below 1 iter and 2 iter
00290 ///////////////////////////////////////////////////////////////////////////
00291 /// ok this doesn't work yet, limmitations on virtual template functions...
00292 /// you just need to mimick this approach in your own commands ...
00293 /// just a few extra lines of code
00294 /*
00295 template<class R> /// templated by return value
00296 class cmdDispatchIF1 {
00297 public:
00298    cmdDispatchIF1(){}
00299    virtual ~cmdDispatchIF1(){}
00300    
00301    /// override this one in your class
00302    template<class T1>
00303       //virtual //virtual template members not allowed???
00304       R operator()(Nrro::NrroIter<T1> n1){};
00305 
00306    /// call this one on a NrroSP
00307    R operator()(NrroSP n1)
00308    {
00309       R ret;
00310       retDispatchIter1(ret,operator(), n1);
00311       return ret;
00312    }
00313 };
00314 
00315 template<class R> /// templated by return value
00316 class cmdDispatchIF2 {
00317 public:
00318    cmdDispatchIF2(){}
00319    virtual ~cmdDispatchIF2(){}
00320 
00321    /// override this one in your class
00322    template<class T1, class T2>
00323       //virtual // virtual template members not allowed??
00324       R operator()(Nrro::NrroIter<T1> n1, Nrro::NrroIter<T2> n2){};
00325 
00326    /// call this one on a NrroSP
00327    R operator()(NrroSP n1, NrroSP n2)
00328    {
00329       R ret;
00330       retDispatchIter2(ret,operator(), n1, n2);
00331       return ret;
00332    }
00333 };
00334 */
00335 #endif
00336 
00337 

Send questions, comments, and bug reports to:
jmk