ML Reference
MeVis/Foundation/Sources/ML/include/mlTypedHandlers.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //--------------------------------------------------------------------------------
00007 //--------------------------------------------------------------------------------
00008 
00009 #ifndef __mlTypedHandlers_H
00010 #define __mlTypedHandlers_H
00011 
00012 #ifndef __mlInitSystemML_H
00013 #include "mlInitSystemML.h"
00014 #endif
00015 
00016 #include "mlCarrierTypes.h"
00017 #include "mlTSubImage.h"
00018 #include "mlModuleInterfaces.h"
00019 #include "mlTypeTraits.h"
00020 #include "mlProcessAllPagesHandler.h"
00021 #include "mlPagedImage.h"
00022 
00023 ML_START_NAMESPACE
00024 
00025 //---------------------------------------------------------------------------
00027 
00028 //---------------------------------------------------------------------------
00029 
00033 #define ML_N_INPUTS 0x4000
00034 
00036 #define _ML_SWITCH_SELECT_OFFSET 32768
00037 
00039 #define _ML_OUTPUTINDEX -1
00040 
00042 const int MLVariableType0 = _ML_SWITCH_SELECT_OFFSET;
00044 const int MLVariableType1 = _ML_SWITCH_SELECT_OFFSET+1;
00046 const int MLVariableType2 = _ML_SWITCH_SELECT_OFFSET+2;
00048 const int MLVariableType3 = _ML_SWITCH_SELECT_OFFSET+3;
00050 const int MLGenericType   = _ML_SWITCH_SELECT_OFFSET+10;
00051 
00053 
00080 class VariableType {
00081 };
00082 
00083 namespace internal {
00084 
00085 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00086 
00087 //-------------------------------------------------------------------------------------------------
00088 
00090 template <int select, typename Types>
00091 struct SwitchOrFixedTypeSelector {
00092   typedef typename DataTypeSelector<select>::Type Type;
00093   typedef TSubImage<Type> SubImageType;
00094 };
00095 
00096 // Specializations for SwitchOrFixedTypeSelector
00097 template <typename Types>
00098 struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+0, Types> {
00099   typedef typename Types::T0 Type;
00100   typedef TSubImage<Type> SubImageType;
00101 };
00102 template <typename Types>
00103 struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+1, Types> {
00104   typedef typename Types::T1 Type;
00105   typedef TSubImage<Type> SubImageType;
00106 };
00107 template <typename Types>
00108 struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+2, Types> {
00109   typedef typename Types::T2 Type;
00110   typedef TSubImage<Type> SubImageType;
00111 };
00112 template <typename Types>
00113 struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+3, Types> {
00114   typedef typename Types::T3 Type;
00115   typedef TSubImage<Type> SubImageType;
00116 };
00117 template <typename Types>
00118 struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+10, Types> {
00119   typedef void Type;
00120   typedef SubImage SubImageType;
00121 };
00122 
00123 //-------------------------------------------------------------------------------------------------
00124 
00126 template <int shouldBeConst, typename InType>
00127 struct ConstTypeSelector {};
00128 
00129 // Specializations for ConstTypeSelector
00130 template <typename InType>
00131 struct ConstTypeSelector<0, InType> { typedef InType Type; };
00132 template <typename InType>
00133 struct ConstTypeSelector<1, InType> { typedef const InType Type; };
00134 
00135 //-------------------------------------------------------------------------------------------------
00136 
00138 template <int v>
00139 class InputImagesCount  {
00140 public:
00141   enum {
00142     count = v
00143   };
00144 };
00145 
00146 //------------------------------------------------------------------------------------------
00147 
00149 struct CalculateOutputSubImageArguments {
00151   CalculateOutputSubImageArguments() {
00152     outImg = NULL;
00153     inImgs = NULL;
00154     userThreadData = NULL;
00155   }
00156 
00158   CalculateOutputSubImageArguments(SubImage* outImage, SubImage* inImages, UserThreadData* threadData) {
00159     outImg = outImage;
00160     inImgs = inImages;
00161     userThreadData = threadData;
00162   }
00163 
00164   // Members are intentionally public, since this is used as replacement for individual arguments
00165   SubImage* outImg;
00166   SubImage* inImgs;
00167   UserThreadData* userThreadData;
00168   int variableDataType[4];
00169 };
00170 
00171 //------------------------------------------------------------------------------------------
00172 
00174 template<typename InT0, typename InT1, typename InT2, typename InT3>
00175 struct TypeTuple4 {
00176   typedef InT0 T0;
00177   typedef InT1 T1;
00178   typedef InT2 T2;
00179   typedef InT3 T3;
00180 };
00181 
00183 struct EmptyType {};
00184 
00186 typedef TypeTuple4<EmptyType, EmptyType, EmptyType, EmptyType> EmptyTypeTuple4;
00187 
00190 template <int position, typename T, typename Tuple>
00191 struct TypeTuple4Insert {};
00192 
00193 // Specializations of TypeTuple4Insert for 4 positions...
00194 template <typename T, typename Tuple>
00195 struct TypeTuple4Insert<0, T, Tuple> {
00196   typedef TypeTuple4<T, T, T, T> Type;
00197 };
00198 template <typename T, typename Tuple>
00199 struct TypeTuple4Insert<1, T, Tuple> {
00200   typedef TypeTuple4<typename Tuple::T0, T, T, T> Type;
00201 };
00202 template <typename T, typename Tuple>
00203 struct TypeTuple4Insert<2, T, Tuple> {
00204   typedef TypeTuple4<typename Tuple::T0, typename Tuple::T1, T, T> Type;
00205 };
00206 template <typename T, typename Tuple>
00207 struct TypeTuple4Insert<3, T, Tuple> {
00208   typedef TypeTuple4<typename Tuple::T0, typename Tuple::T1, typename Tuple::T2, T> Type;
00209 };
00210 
00211 #endif // of DOXYGEN_SHOULD_SKIP_THIS
00212   
00213 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00214   
00217 MLEXPORT void setupKnownPagedImgProperties(PagedImage* outImg, int templateNumImages, int outputType, const int inputTypes[10], const int inputReadOnly[10], int numVariableTypes, const int variableTypes[4]);
00218 
00221 MLEXPORT void verifyPagedImgProperties(PagedImage* outImg, int templateNumImages, int outputType, const int inputTypes[10], const int inputReadOnly[10], int numVariableTypes, const int variableTypes[4], int resultDataTypes[4]);
00222 
00223 #endif // of DOXYGEN_SHOULD_SKIP_THIS
00224 
00225 //-----------------------------------------------------------------------------------------------------
00226 
00228 
00232 template<class BaseClass, class Derived, int NumberOfInputImages>
00233 class TypedHandlerBase : public BaseClass {
00234 
00235 public:
00236   // Defines the preconfigured static selection of types and their properties.
00237   enum {
00238     // Enums to be overwritten by user
00239     OutputSubImage_Type = MLVariableType0, 
00240     InputSubImage0_Type = MLVariableType1, 
00241     InputSubImage1_Type = MLVariableType2, 
00242     InputSubImage2_Type = MLVariableType3, 
00243     InputSubImage3_Type = MLVariableType3, 
00244     InputSubImage4_Type = MLVariableType3, 
00245     InputSubImage5_Type = MLVariableType3, 
00246     InputSubImage6_Type = MLVariableType3, 
00247     InputSubImage7_Type = MLVariableType3, 
00248     InputSubImage8_Type = MLVariableType3, 
00249     InputSubImage9_Type = MLVariableType3, 
00250     
00251     InputSubImage0_ReadOnly = true, 
00252     InputSubImage1_ReadOnly = true, 
00253     InputSubImage2_ReadOnly = true, 
00254     InputSubImage3_ReadOnly = true, 
00255     InputSubImage4_ReadOnly = true, 
00256     InputSubImage5_ReadOnly = true, 
00257     InputSubImage6_ReadOnly = true, 
00258     InputSubImage7_ReadOnly = true, 
00259     InputSubImage8_ReadOnly = true, 
00260     InputSubImage9_ReadOnly = true, 
00261   };
00262 
00263   TypedHandlerBase() {
00264     setupVariableTypes(_variableTypeIndex);
00265   }
00266 
00267 private:
00269   int _variableTypeIndex[4];
00270 
00272   static void setupVariableTypes(int variableTypeIndex[4]) {
00273     const int inputTypes[10] = {
00274       Derived::InputSubImage0_Type, Derived::InputSubImage1_Type, Derived::InputSubImage2_Type, Derived::InputSubImage3_Type, Derived::InputSubImage4_Type,
00275       Derived::InputSubImage5_Type, Derived::InputSubImage6_Type, Derived::InputSubImage7_Type, Derived::InputSubImage8_Type, Derived::InputSubImage9_Type };
00276     for (int i=0;i<Derived::getNumVariableTypes();i++) {
00277       // use output image as default
00278       variableTypeIndex[i] = _ML_OUTPUTINDEX;
00279       // find the first image that uses variable type i, either the output or one of the inputs
00280       if (Derived::OutputSubImage_Type == MLVariableType0 + i) {
00281         variableTypeIndex[i] = _ML_OUTPUTINDEX;
00282       } else {
00283         // for the purpose of the below loop, treat ML_N_INPUTS as 1
00284         const int numInputs = (NumberOfInputImages==ML_N_INPUTS)?1:NumberOfInputImages;
00285         for (int j=0;j<numInputs;j++) {
00286           if (inputTypes[j] == MLVariableType0 + i) {
00287             variableTypeIndex[i] = j;
00288             break;
00289           }
00290         }
00291       }
00292     }
00293   }
00294 
00295 public:
00296 
00298   virtual void calculateOutputSubImage(SubImage* outImg, SubImage* inImgs, UserThreadData* userThreadData) {
00299     // Put arguments in struct to facilitate passing them thru.
00300     CalculateOutputSubImageArguments args(outImg, inImgs, userThreadData);
00301 
00302     // Detect the correct datatype for up to 4 variable types (loop length is compile time!)
00303     for (int i=0; i<Derived::getNumVariableTypes(); i++) {
00304       args.variableDataType[i] = (_variableTypeIndex[i] == _ML_OUTPUTINDEX) ?
00305         args.outImg->getDataType() : args.inImgs[_variableTypeIndex[i]].getDataType();
00306     }
00307 
00308     // Start the switching, which will call back to helperCalculateOutputSubImage below when all types are switched.
00309     static_cast<Derived*>(this)->doSwitching(args);
00310   }
00311 
00312 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00313 
00314   template<typename Types>
00315   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args) {
00316     // we collected up to 4 types in Types, now delegate to specific method for NumberOfInputImages
00317     helperCalculateOutputSubImage<Types>(args, static_cast<InputImagesCount<NumberOfInputImages>*>(0));
00318   }
00319 
00320   template<typename Types>
00321   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<ML_N_INPUTS>*) {
00322     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::Type OUTTYPE;
00323     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::Type INTYPE0;
00324     TSubImage<OUTTYPE> outTSubImg(*args.outImg);
00325     typedef typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, TSubImage<INTYPE0> >::Type INTSUBIMG0;
00326     // Cast inImgs to TSubImage!
00327     INTSUBIMG0* inTSubImgs = tsubimage_cast<INTYPE0>(args.inImgs);
00328     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImgs, args.userThreadData);
00329   }
00330 
00331   template<typename Types>
00332   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<0>*) {
00333     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00334     OUTIMAGETYPE outTSubImg(*args.outImg);
00335     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, args.userThreadData);
00336   }
00337 
00338   template<typename Types>
00339   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<1>*) {
00340     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00341     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00342     OUTIMAGETYPE outTSubImg(*args.outImg);
00343     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00344     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, args.userThreadData);
00345   }
00346 
00347   template<typename Types>
00348   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<2>*) {
00349     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00350     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00351     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00352     OUTIMAGETYPE outTSubImg(*args.outImg);
00353     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00354     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00355     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, args.userThreadData);
00356   }
00357 
00358   template<typename Types>
00359   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<3>*) {
00360     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00361     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00362     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00363     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
00364     OUTIMAGETYPE outTSubImg(*args.outImg);
00365     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00366     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00367     typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
00368     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, args.userThreadData);
00369   }
00370 
00371   template<typename Types>
00372   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<4>*) {
00373     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00374     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00375     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00376     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
00377     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
00378     OUTIMAGETYPE outTSubImg(*args.outImg);
00379     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00380     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00381     typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
00382     typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
00383     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, args.userThreadData);
00384   }
00385 
00386   template<typename Types>
00387   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<5>*) {
00388     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00389     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00390     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00391     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
00392     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
00393     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
00394     OUTIMAGETYPE outTSubImg(*args.outImg);
00395     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00396     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00397     typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
00398     typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
00399     typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
00400     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, args.userThreadData);
00401   }
00402 
00403   template<typename Types>
00404   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<6>*) {
00405     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00406     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00407     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00408     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
00409     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
00410     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
00411     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
00412     OUTIMAGETYPE outTSubImg(*args.outImg);
00413     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00414     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00415     typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
00416     typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
00417     typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
00418     typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
00419     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, args.userThreadData);
00420   }
00421 
00422   template<typename Types>
00423   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<7>*) {
00424     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00425     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00426     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00427     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
00428     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
00429     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
00430     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
00431     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage6_Type, Types>::SubImageType INIMAGETYPE6;
00432     OUTIMAGETYPE outTSubImg(*args.outImg);
00433     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00434     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00435     typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
00436     typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
00437     typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
00438     typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
00439     typename ConstTypeSelector<Derived::InputSubImage6_ReadOnly, INIMAGETYPE6>::Type inTSubImg6(args.inImgs[6]);
00440     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, inTSubImg6, args.userThreadData);
00441   }
00442 
00443   template<typename Types>
00444   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<8>*) {
00445     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00446     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00447     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00448     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
00449     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
00450     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
00451     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
00452     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage6_Type, Types>::SubImageType INIMAGETYPE6;
00453     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage7_Type, Types>::SubImageType INIMAGETYPE7;
00454     OUTIMAGETYPE outTSubImg(*args.outImg);
00455     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00456     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00457     typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
00458     typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
00459     typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
00460     typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
00461     typename ConstTypeSelector<Derived::InputSubImage6_ReadOnly, INIMAGETYPE6>::Type inTSubImg6(args.inImgs[6]);
00462     typename ConstTypeSelector<Derived::InputSubImage7_ReadOnly, INIMAGETYPE7>::Type inTSubImg7(args.inImgs[7]);
00463     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, inTSubImg6, inTSubImg7, args.userThreadData);
00464   }
00465 
00466   template<typename Types>
00467   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<9>*) {
00468     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00469     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00470     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00471     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
00472     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
00473     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
00474     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
00475     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage6_Type, Types>::SubImageType INIMAGETYPE6;
00476     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage7_Type, Types>::SubImageType INIMAGETYPE7;
00477     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage8_Type, Types>::SubImageType INIMAGETYPE8;
00478     OUTIMAGETYPE outTSubImg(*args.outImg);
00479     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00480     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00481     typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
00482     typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
00483     typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
00484     typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
00485     typename ConstTypeSelector<Derived::InputSubImage6_ReadOnly, INIMAGETYPE6>::Type inTSubImg6(args.inImgs[6]);
00486     typename ConstTypeSelector<Derived::InputSubImage7_ReadOnly, INIMAGETYPE7>::Type inTSubImg7(args.inImgs[7]);
00487     typename ConstTypeSelector<Derived::InputSubImage8_ReadOnly, INIMAGETYPE8>::Type inTSubImg8(args.inImgs[8]);
00488     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, inTSubImg6, inTSubImg7, inTSubImg8, args.userThreadData);
00489   }
00490 
00491   template<typename Types>
00492   void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<10>*) {
00493     typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
00494     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
00495     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
00496     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
00497     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
00498     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
00499     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
00500     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage6_Type, Types>::SubImageType INIMAGETYPE6;
00501     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage7_Type, Types>::SubImageType INIMAGETYPE7;
00502     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage8_Type, Types>::SubImageType INIMAGETYPE8;
00503     typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage9_Type, Types>::SubImageType INIMAGETYPE9;
00504     OUTIMAGETYPE outTSubImg(*args.outImg);
00505     typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
00506     typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
00507     typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
00508     typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
00509     typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
00510     typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
00511     typename ConstTypeSelector<Derived::InputSubImage6_ReadOnly, INIMAGETYPE6>::Type inTSubImg6(args.inImgs[6]);
00512     typename ConstTypeSelector<Derived::InputSubImage7_ReadOnly, INIMAGETYPE7>::Type inTSubImg7(args.inImgs[7]);
00513     typename ConstTypeSelector<Derived::InputSubImage8_ReadOnly, INIMAGETYPE8>::Type inTSubImg8(args.inImgs[8]);
00514     typename ConstTypeSelector<Derived::InputSubImage9_ReadOnly, INIMAGETYPE9>::Type inTSubImg9(args.inImgs[9]);
00515     static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, inTSubImg6, inTSubImg7, inTSubImg8, inTSubImg9, args.userThreadData);
00516   }
00517 
00518 #endif // of DOXYGEN_SHOULD_SKIP_THIS
00519 
00520   // Helper macro that collects compile time enum information of "Derived" class.
00521   #define _ML_COLLECT_ENUMS \
00522   const int inputTypes[10] = {                                                                                                     \
00523     Derived::InputSubImage0_Type, Derived::InputSubImage1_Type, Derived::InputSubImage2_Type, Derived::InputSubImage3_Type, Derived::InputSubImage4_Type,                       \
00524     Derived::InputSubImage5_Type, Derived::InputSubImage6_Type, Derived::InputSubImage7_Type, Derived::InputSubImage8_Type, Derived::InputSubImage9_Type };                     \
00525   const int inputReadOnly[10] = {                                                                                                  \
00526     Derived::InputSubImage0_ReadOnly, Derived::InputSubImage1_ReadOnly, Derived::InputSubImage2_ReadOnly, Derived::InputSubImage3_ReadOnly, Derived::InputSubImage4_ReadOnly,   \
00527     Derived::InputSubImage5_ReadOnly, Derived::InputSubImage6_ReadOnly, Derived::InputSubImage7_ReadOnly, Derived::InputSubImage8_ReadOnly, Derived::InputSubImage9_ReadOnly }; \
00528   int variableTypes[4]; \
00529   setupVariableTypes(variableTypes);
00530 
00533   static void setupKnownProperties(PagedImage* outImg) {
00534     // collect static information
00535     _ML_COLLECT_ENUMS
00536     setupKnownPagedImgProperties(outImg, NumberOfInputImages, Derived::OutputSubImage_Type, inputTypes, inputReadOnly, Derived::getNumVariableTypes(), variableTypes);
00537   }
00538 
00542   static bool verifyProperties(PagedImage* outImg) {
00543     // collect static information
00544     _ML_COLLECT_ENUMS
00545     int resultDataTypes[4];
00546     verifyPagedImgProperties(outImg, NumberOfInputImages, Derived::OutputSubImage_Type, inputTypes, inputReadOnly, Derived::getNumVariableTypes(), variableTypes, resultDataTypes);
00547     if (outImg->isValid()) {
00548       std::ostringstream errorMessages;
00549       for (int i = 0; i < Derived::getNumVariableTypes(); i++) {
00550         if (!Derived::doesVariableTypeSupportDataType(i, resultDataTypes[i])) {
00551           if (variableTypes[i]!=_ML_OUTPUTINDEX) {
00552             errorMessages << "Unsupported datatype '" << MLNameFromDataType(resultDataTypes[i]) << "' at input" << variableTypes[i] << " using variable type " << Derived::variableTypeName(i) << std::endl;
00553           } else {
00554             errorMessages << "Unsupported datatype '" << MLNameFromDataType(resultDataTypes[i]) << "' at output using variable type " << Derived::variableTypeName(i) << std::endl;
00555           }
00556         }
00557       }
00558       if (errorMessages.str().size()) {
00559         outImg->setInvalid();
00560         outImg->setStateInfo(errorMessages.str(), ML_BAD_DATA_TYPE);
00561       }
00562     }
00563     return outImg->isValid();
00564   }
00565 
00566   #undef _ML_COLLECT_ENUMS
00567 };
00568 
00569 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00570 
00573 template<class Derived, int Step, class Args >
00574 class NoTypes : public VariableType {
00575 public:
00576   enum {
00577     IsEmpty = true
00578   };
00579 
00580   static const char* name() { return "NoTypes"; }
00581 
00582   // Empty switching code that returns true.
00583   template<typename PrevTypes, typename TargetLabelType>
00584   bool doSwitchingCode(int /*switchCode*/, const Args& /*args*/, bool /*printError*/ = true) { return true; }
00585 };
00586 
00587 //------------------------------------------------------------------------------------------
00590 struct DispatchVariableType1Label {};
00591 struct DispatchVariableType2Label {};
00592 struct DispatchVariableType3Label {};
00593 struct DispatchDoneLabel {};
00594 struct DispatchDoNothingLabel {};
00595 
00598 typedef TypeTuple4<DispatchDoneLabel,       DispatchDoneLabel,      DispatchDoneLabel,       DispatchDoneLabel> JumpTable1;
00601 typedef TypeTuple4<DispatchVariableType1Label, DispatchDoneLabel,      DispatchDoneLabel,       DispatchDoneLabel> JumpTable2;
00604 typedef TypeTuple4<DispatchVariableType1Label, DispatchVariableType2Label, DispatchDoneLabel,       DispatchDoneLabel> JumpTable3;
00607 typedef TypeTuple4<DispatchVariableType1Label, DispatchVariableType2Label, DispatchVariableType3Label, DispatchDoneLabel> JumpTable4;
00608 
00609 
00611 template<class Derived>
00612 class EmptyVariableTypeDispatcher
00613 {
00614 public:
00615   static int getNumVariableTypes() { return 0; }
00616   static bool doesVariableTypeSupportDataType(int /*variableType*/, int /*switchCode*/) { return false; }
00617   static const char* variableTypeName(int /*variableType*/) { return "NoTypes"; }
00618 
00619   void doSwitching(const CalculateOutputSubImageArguments& args) {
00620     // call back directly to caller, we have no variable types
00621     static_cast<Derived*>(this)->template helperCalculateOutputSubImage<EmptyTypeTuple4>(args);
00622   }
00623 
00624 };
00625 
00628 template<class Derived, class JumpTable, class VariableType0, class VariableType1, class VariableType2, class VariableType3>
00629 class VariableTypeDispatcher : public VariableType0, public VariableType1, public VariableType2, public VariableType3 {
00630 public:
00631 
00633   static int getNumVariableTypes() {
00634     return (VariableType0::IsEmpty?0:1) + (VariableType1::IsEmpty?0:1) +
00635            (VariableType2::IsEmpty?0:1) + (VariableType3::IsEmpty?0:1);
00636   }
00637 
00638   static bool doesVariableTypeSupportDataType(int variableType, int switchCode) {
00639     VariableTypeDispatcher<Derived, JumpTable, VariableType0, VariableType1, VariableType2, VariableType3> self;
00640     CalculateOutputSubImageArguments args;
00641     if (variableType == 0) {
00642       return static_cast<VariableType0*>(&self)->template doSwitchingCode<EmptyTypeTuple4, DispatchDoNothingLabel>(switchCode, args, false /* no error printing*/ );
00643     } else if (variableType == 1) {
00644       return static_cast<VariableType1*>(&self)->template doSwitchingCode<EmptyTypeTuple4, DispatchDoNothingLabel>(switchCode, args, false /* no error printing*/ );
00645     } else if (variableType == 2) {
00646       return static_cast<VariableType2*>(&self)->template doSwitchingCode<EmptyTypeTuple4, DispatchDoNothingLabel>(switchCode, args, false /* no error printing*/ );
00647     } else if (variableType == 3) {
00648       return static_cast<VariableType3*>(&self)->template doSwitchingCode<EmptyTypeTuple4, DispatchDoNothingLabel>(switchCode, args, false /* no error printing*/ );
00649     }
00650     return false;
00651   }
00652 
00653   static const char* variableTypeName(int variableType) {
00654     if (variableType == 0) {
00655       return VariableType0::name();
00656     } else if (variableType == 1) {
00657       return VariableType1::name();
00658     } else if (variableType == 2) {
00659       return VariableType2::name();
00660     } else if (variableType == 3) {
00661       return VariableType3::name();
00662     }
00663     return "";
00664   }
00665 
00666   void doSwitching(const CalculateOutputSubImageArguments& args) {
00667     MLDataType dt = args.variableDataType[0];
00668     static_cast<VariableType0*>(this)->template doSwitchingCode<EmptyTypeTuple4, typename JumpTable::T0>(dt, args);
00669   }
00670 
00671   template<typename Types>
00672   void doSwitchingWithLabel(const CalculateOutputSubImageArguments& args, DispatchVariableType1Label*) {
00673     MLDataType dt = args.variableDataType[1];
00674     static_cast<VariableType1*>(this)->template doSwitchingCode<Types, typename JumpTable::T1>(dt, args);
00675   }
00676 
00677   template<typename Types>
00678   void doSwitchingWithLabel(const CalculateOutputSubImageArguments& args, DispatchVariableType2Label*) {
00679     MLDataType dt = args.variableDataType[2];
00680     static_cast<VariableType2*>(this)->template doSwitchingCode<Types, typename JumpTable::T2>(dt, args);
00681   }
00682 
00683   template<typename Types>
00684   void doSwitchingWithLabel(const CalculateOutputSubImageArguments& args, DispatchVariableType3Label*) {
00685     MLDataType dt = args.variableDataType[3];
00686     static_cast<VariableType3*>(this)->template doSwitchingCode<Types, typename JumpTable::T3>(dt, args);
00687   }
00688 
00689   template<typename Types>
00690   void doSwitchingWithLabel(const CalculateOutputSubImageArguments& args, DispatchDoneLabel*) {
00691     static_cast<Derived*>(this)->template helperCalculateOutputSubImage<Types>(args);
00692   }
00693 
00694   template<typename Types>
00695   void doSwitchingWithLabel(const CalculateOutputSubImageArguments&, DispatchDoNothingLabel*) {
00696   }
00697 };
00698 
00699 #endif // of DOXYGEN_SHOULD_SKIP_THIS
00700 
00701 } // end namespace internal
00702 
00703 
00704 //----------------------------------------------------------------------------------------------------
00705 
00710 template <typename Derived, int NumberOfInputImages,
00711   template <typename, int, typename>class VariableType0 = internal::NoTypes,
00712   template <typename, int, typename>class VariableType1 = internal::NoTypes,
00713   template <typename, int, typename>class VariableType2 = internal::NoTypes,
00714   template <typename, int, typename>class VariableType3 = internal::NoTypes >
00715 class TypedProcessAllPagesHandler : public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
00716   public internal::VariableTypeDispatcher<Derived, internal::JumpTable4, VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
00717                                      VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
00718                                      VariableType2<Derived, 2, internal::CalculateOutputSubImageArguments >,
00719                                      VariableType3<Derived, 3, internal::CalculateOutputSubImageArguments > >
00720 {
00721 };
00722 
00723 
00724 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00725 
00726 // Specialization with 3 variable types
00727 template <typename Derived, int NumberOfInputImages,
00728 template <typename, int, typename>class VariableType0,
00729 template <typename, int, typename>class VariableType1,
00730 template <typename, int, typename>class VariableType2>
00731 class TypedProcessAllPagesHandler<Derived, NumberOfInputImages, VariableType0, VariableType1, VariableType2, internal::NoTypes> :
00732   public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
00733   public internal::VariableTypeDispatcher<Derived, internal::JumpTable3,
00734     VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
00735     VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
00736     VariableType2<Derived, 2, internal::CalculateOutputSubImageArguments >,
00737     internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
00738 {
00739 };
00740 
00741 // Specialization with 2 variable types
00742 template <typename Derived, int NumberOfInputImages,
00743 template <typename, int, typename>class VariableType0,
00744 template <typename, int, typename>class VariableType1>
00745 class TypedProcessAllPagesHandler<Derived, NumberOfInputImages, VariableType0, VariableType1, internal::NoTypes, internal::NoTypes> :
00746   public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
00747   public internal::VariableTypeDispatcher<Derived, internal::JumpTable2,
00748     VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
00749     VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
00750     internal::NoTypes<Derived, 2, internal::CalculateOutputSubImageArguments >,
00751     internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
00752 {
00753 };
00754 
00755 // Specialization with 1 variable type
00756 template <typename Derived, int NumberOfInputImages,
00757 template <typename, int, typename>class VariableType0>
00758 class TypedProcessAllPagesHandler<Derived, NumberOfInputImages, VariableType0, internal::NoTypes, internal::NoTypes, internal::NoTypes> :
00759   public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
00760   public internal::VariableTypeDispatcher<Derived, internal::JumpTable1,
00761     VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
00762     internal::NoTypes<Derived, 1, internal::CalculateOutputSubImageArguments >,
00763     internal::NoTypes<Derived, 2, internal::CalculateOutputSubImageArguments >,
00764     internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
00765 {
00766 };
00767 
00768 // Specialization with 0 variable types
00769 template <typename Derived, int NumberOfInputImages>
00770 class TypedProcessAllPagesHandler<Derived, NumberOfInputImages, internal::NoTypes, internal::NoTypes, internal::NoTypes, internal::NoTypes> :
00771   public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
00772   public internal::EmptyVariableTypeDispatcher<Derived>
00773 {
00774 };
00775 
00776 #endif // of DOXYGEN_SHOULD_SKIP_THIS
00777 
00778 //----------------------------------------------------------------------------------------------------
00779 
00785 
00812 
00824 
00845 
00852 
00877 
00885 
00904 
00915 
00927 template <typename Derived, int NumberOfInputImages,
00928 template <typename, int, typename>class VariableType0 = internal::NoTypes,
00929 template <typename, int, typename>class VariableType1 = internal::NoTypes,
00930 template <typename, int, typename>class VariableType2 = internal::NoTypes,
00931 template <typename, int, typename>class VariableType3 = internal::NoTypes >
00932 class TypedCalculateOutputImageHandler : public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
00933   public internal::VariableTypeDispatcher<Derived, internal::JumpTable4,
00934     VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
00935     VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
00936     VariableType2<Derived, 2, internal::CalculateOutputSubImageArguments >,
00937     VariableType3<Derived, 3, internal::CalculateOutputSubImageArguments > >
00938 {
00939 };
00940 
00941 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00942 
00943 // Specialization with 3 variable types
00944 template <typename Derived, int NumberOfInputImages,
00945 template <typename, int, typename>class VariableType0,
00946 template <typename, int, typename>class VariableType1,
00947 template <typename, int, typename>class VariableType2>
00948 class TypedCalculateOutputImageHandler<Derived, NumberOfInputImages, VariableType0, VariableType1, VariableType2, internal::NoTypes> :
00949   public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
00950   public internal::VariableTypeDispatcher<Derived, internal::JumpTable3,
00951     VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
00952     VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
00953     VariableType2<Derived, 2, internal::CalculateOutputSubImageArguments >,
00954     internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
00955 {
00956 };
00957 
00958 // Specialization with 2 variable types
00959 template <typename Derived, int NumberOfInputImages,
00960 template <typename, int, typename>class VariableType0,
00961 template <typename, int, typename>class VariableType1>
00962 class TypedCalculateOutputImageHandler<Derived, NumberOfInputImages, VariableType0, VariableType1, internal::NoTypes, internal::NoTypes> :
00963   public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
00964   public internal::VariableTypeDispatcher<Derived, internal::JumpTable2,
00965     VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
00966     VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
00967     internal::NoTypes<Derived, 2, internal::CalculateOutputSubImageArguments >,
00968     internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
00969 {
00970 };
00971 
00972 // Specialization with 1 variable type
00973 template <typename Derived, int NumberOfInputImages,
00974 template <typename, int, typename>class VariableType0>
00975 class TypedCalculateOutputImageHandler<Derived, NumberOfInputImages, VariableType0, internal::NoTypes, internal::NoTypes, internal::NoTypes> :
00976   public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
00977   public internal::VariableTypeDispatcher<Derived, internal::JumpTable1,
00978     VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
00979     internal::NoTypes<Derived, 1, internal::CalculateOutputSubImageArguments >,
00980     internal::NoTypes<Derived, 2, internal::CalculateOutputSubImageArguments >,
00981     internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
00982 {
00983 };
00984 
00985 // Specialization with 0 variable types
00986 template <typename Derived, int NumberOfInputImages>
00987 class TypedCalculateOutputImageHandler<Derived, NumberOfInputImages, internal::NoTypes, internal::NoTypes, internal::NoTypes, internal::NoTypes> :
00988   public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
00989   public internal::EmptyVariableTypeDispatcher<Derived>
00990 {
00991 };
00992 
00993 #endif // of DOXYGEN_SHOULD_SKIP_THIS
00994 
00995 //----------------------------------------------------------------------------------------------------
00996 
00997 //---------------------------------------------------------------------------
00999 
01000 //---------------------------------------------------------------------------
01001 
01005 
01019 #define ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(NAME) \
01020   template<class Derived, int Step, class Args = ML_NAMESPACE::internal::CalculateOutputSubImageArguments>   \
01021 class NAME : public VariableType {                                                                        \
01022 public:                                                                             \
01023   enum { IsEmpty = false };                             \
01024                                                                                     \
01025   static const char* name() { return #NAME; }                                       \
01026                                                                                     \
01027   template<typename PrevTypes, typename TargetLabelType>                            \
01028   bool doSwitchingCode(int switchCode, const Args& args, bool printError = true) {  \
01029   static const char* switcherName = #NAME;                                          \
01030   bool result = true;                                                               \
01031   switch (switchCode) {
01032 
01035 #define ML_IMPLEMENT_VARIABLE_TYPE_END \
01036     default: {                                                                    \
01037     result = false;                                                               \
01038     if (printError) {                                                             \
01039     char buf[512]="";                                                             \
01040     sprintf(buf, "No switch case for physical data type %d.", switchCode);        \
01041     ML_PRINT_FATAL_ERROR(switcherName, ML_BAD_DATA_TYPE, buf); }                  \
01042     }                                                                             \
01043   break;                                                                          \
01044 }                                                                                 \
01045   return result;                                                                  \
01046 }                                                                                 \
01047 };
01048 
01051 #define ML_IMPLEMENT_VARIABLE_TYPE_CASE(TYPE) \
01052  case TypeTraits<TYPE>::dataType: \
01053  static_cast<Derived*>(this)->template doSwitchingWithLabel<typename ML_NAMESPACE::internal::TypeTuple4Insert<Step, TYPE, PrevTypes>::Type>(args, static_cast<TargetLabelType*>(0)); \
01054  break;
01055 
01056 #define ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(DATATYPE, TYPE) \
01057  case DATATYPE: \
01058  static_cast<Derived*>(this)->template doSwitchingWithLabel<typename ML_NAMESPACE::internal::TypeTuple4Insert<Step, TYPE, PrevTypes>::Type>(args, static_cast<TargetLabelType*>(0)); \
01059  break;
01060 
01063 #define ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT \
01064   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLfloat)  \
01065   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLdouble)
01066 
01069 #define ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER \
01070   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLuint8)  \
01071   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLint8)   \
01072   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLuint16) \
01073   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLint16)  \
01074   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLuint32) \
01075   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLint32)  \
01076   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLuint64) \
01077   ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLint64)
01078 
01079 #define ML_IMPLEMENT_VARIABLE_TYPE_CASES_COMPLEX \
01080   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLComplexfType, std::complex<MLfloat>)  \
01081   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLComplexdType, std::complex<MLdouble>)
01082 
01083 #define ML_IMPLEMENT_VARIABLE_TYPE_CASES_DEFAULT_EXTENDED \
01084   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLComplexfType, std::complex<MLfloat>)  \
01085   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLComplexdType, std::complex<MLdouble>) \
01086   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector2fType, Vector2f)  \
01087   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector2dType, Vector2d)  \
01088   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector3fType, Vector3f)  \
01089   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector3dType, Vector3d)  \
01090   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector6fType, Vector6f)  \
01091   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector6dType, Vector6d)  \
01092   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLMatrix2fType, Matrix2f)  \
01093   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLMatrix2dType, Matrix2d)  \
01094   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLMatrix3fType, Matrix3f)  \
01095   ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLMatrix3dType, Matrix3d)
01096 
01100 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(FloatTypes)
01101   ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT
01102 ML_IMPLEMENT_VARIABLE_TYPE_END
01103 
01107 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(IntegerTypes)
01108   ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER
01109 ML_IMPLEMENT_VARIABLE_TYPE_END
01110 
01114 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(ScalarTypes)
01115   ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER
01116   ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT
01117 ML_IMPLEMENT_VARIABLE_TYPE_END
01118 
01121 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(StandardTypes)
01122   ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER
01123   ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT
01124 ML_IMPLEMENT_VARIABLE_TYPE_END
01125 
01129 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(DefaultTypes)
01130   ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER
01131   ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT
01132   ML_IMPLEMENT_VARIABLE_TYPE_CASES_DEFAULT_EXTENDED
01133 ML_IMPLEMENT_VARIABLE_TYPE_END
01134 
01137 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(AllTypes)
01138   ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER
01139   ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT
01140   ML_IMPLEMENT_VARIABLE_TYPE_CASES_DEFAULT_EXTENDED
01141 ML_IMPLEMENT_VARIABLE_TYPE_END
01142 
01146 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(DefaultExtendedTypes)
01147   ML_IMPLEMENT_VARIABLE_TYPE_CASES_DEFAULT_EXTENDED
01148 ML_IMPLEMENT_VARIABLE_TYPE_END
01149 
01153 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(ComplexTypes)
01154   ML_IMPLEMENT_VARIABLE_TYPE_CASES_COMPLEX
01155 ML_IMPLEMENT_VARIABLE_TYPE_END
01156 
01160 ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(ScalarAndComplexTypes)
01161   ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER
01162   ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT
01163   ML_IMPLEMENT_VARIABLE_TYPE_CASES_COMPLEX
01164 ML_IMPLEMENT_VARIABLE_TYPE_END
01165 
01167 
01168 ML_END_NAMESPACE
01169 
01170 #endif // of __mlTypedHandlers_H
01171