MeVisLab Toolbox Reference
mlWrapperMacros.h File Reference

Go to the source code of this file.

Macros

#define ML_EMPTY_SPACE
 In this header some macros are defined which implement some c-wrapper stuff to address member functions via a pointer. More...
 
#define IMPLEMENT_DIM_DISPATCHER_P0(FUNC_NAME, CLASS_NAME, RET_TYPE, RET_COMMAND)
 This macro defines a function type and six static functions of this type. More...
 
#define IMPLEMENT_DIM_DISPATCHER_P1(FUNC_NAME, CLASS_NAME, RET_TYPE, RET_COMMAND, P_TYPE)
 For documentation see IMPLEMENT_DIM_DISPATCHER_P0. More...
 
#define IMPLEMENT_EXC_DISPATCHER_P0(FUNC_NAME, CLASS_NAME, RET_TYPE, RET_COMMAND)
 This macro defines a function type and 12 static functions of this type. More...
 

Macro Definition Documentation

◆ IMPLEMENT_DIM_DISPATCHER_P0

#define IMPLEMENT_DIM_DISPATCHER_P0 (   FUNC_NAME,
  CLASS_NAME,
  RET_TYPE,
  RET_COMMAND 
)
Value:
/* Create function type.*/ \
typedef RET_TYPE(*FUNC_NAME##TYPE)(CLASS_NAME *obj); \
\
/* Implement a member used to call the selected function. */ \
FUNC_NAME##TYPE FUNC_NAME; \
\
/* Implement 6 static functions where one is really selected by calling FUNC_NAME. */ \
static inline RET_TYPE FUNC_NAME##1DCB(CLASS_NAME *obj){ RET_COMMAND obj->FUNC_NAME##1D(); } \
static inline RET_TYPE FUNC_NAME##2DCB(CLASS_NAME *obj){ RET_COMMAND obj->FUNC_NAME##2D(); } \
static inline RET_TYPE FUNC_NAME##3DCB(CLASS_NAME *obj){ RET_COMMAND obj->FUNC_NAME##3D(); } \
static inline RET_TYPE FUNC_NAME##4DCB(CLASS_NAME *obj){ RET_COMMAND obj->FUNC_NAME##4D(); } \
static inline RET_TYPE FUNC_NAME##5DCB(CLASS_NAME *obj){ RET_COMMAND obj->FUNC_NAME##5D(); } \
static inline RET_TYPE FUNC_NAME##6DCB(CLASS_NAME *obj){ RET_COMMAND obj->FUNC_NAME##6D(); } \
\
/* Implement a switch to set the correct function for the correct dimension extent. */ \
void _init##FUNC_NAME##TYPE(MLint dim){ \
switch (dim){ \
case 1: FUNC_NAME = FUNC_NAME##1DCB; break; \
case 2: FUNC_NAME = FUNC_NAME##2DCB; break; \
case 3: FUNC_NAME = FUNC_NAME##3DCB; break; \
case 4: FUNC_NAME = FUNC_NAME##4DCB; break; \
case 5: FUNC_NAME = FUNC_NAME##5DCB; break; \
case 6: FUNC_NAME = FUNC_NAME##6DCB; break; \
default: ML_PRINT_FATAL_ERROR("IMPLEMENT_DIM_DISPATCHER_P0", ML_PROGRAMMING_ERROR, \
"Using 6d implementation."); \
} \
}
@ D
Definition: SoKeyGrabber.h:55
#define ML_PROGRAMMING_ERROR
A case occurred which should not appear and here are a variety of reasons, typically it is a programm...
Definition: mlTypeDefs.h:890
#define ML_PRINT_FATAL_ERROR(FUNC_NAME, REASON, HANDLING)
Like ML_PRINT_FATAL_ERROR_DUMP(FUNC_NAME, REASON, HANDLING, RT_OBJ) without a runtime object to be du...
MLint64 MLint
A signed ML integer type with at least 64 bits used for index calculations on very large images even ...
Definition: mlTypeDefs.h:578

This macro defines a function type and six static functions of this type.

The function type is given from FUNC_NAME + "TYPE". The six functions are named FUNC_NAME + "1DCB", ..., FUNC_NAME + "6DCB" for callback versions from 1D to 6D. These 6 static functions call the corresponding functions named FUNC_NAME + "1D", ..., FUNC_NAME + "6D" which must be implemented as members of the object passed as obj which is of the type given by CLASS_NAME.

The return type of the callback function is passed by RET_TYPE. Pass 'void' for no return value. The return command (usually 'return') is passed as RET_COMMAND. Use ML_EMPTY_SPACE for no return command.

Moreover a member of the function type is created with name FUNC_NAME. Also an initialization function with name "_init" + FUNC_NAME + "TYPE" is implemented which sets the member to address of the n-dth function if n is passed as parameter. So the function for dimension can be called by simply calling the member and passing the this-pointer of the object.

Usually the dimension of an image is calculated and the member is set to the optimized implementation for that dimension by calling the init function. So the code is always adapted to the current image dimension.

Definition at line 79 of file mlWrapperMacros.h.

◆ IMPLEMENT_DIM_DISPATCHER_P1

#define IMPLEMENT_DIM_DISPATCHER_P1 (   FUNC_NAME,
  CLASS_NAME,
  RET_TYPE,
  RET_COMMAND,
  P_TYPE 
)
Value:
/* Create function type.*/ \
typedef RET_TYPE(*FUNC_NAME##TYPE)(CLASS_NAME *obj, P_TYPE p); \
\
/* Implement a member used to call the selected function. */ \
FUNC_NAME##TYPE FUNC_NAME; \
\
/* Implement 6 static functions where one is really selected by calling FUNC_NAME. */ \
static inline RET_TYPE FUNC_NAME##1DCB(CLASS_NAME *obj, P_TYPE p){RET_COMMAND obj->FUNC_NAME##1D(p);} \
static inline RET_TYPE FUNC_NAME##2DCB(CLASS_NAME *obj, P_TYPE p){RET_COMMAND obj->FUNC_NAME##2D(p);} \
static inline RET_TYPE FUNC_NAME##3DCB(CLASS_NAME *obj, P_TYPE p){RET_COMMAND obj->FUNC_NAME##3D(p);} \
static inline RET_TYPE FUNC_NAME##4DCB(CLASS_NAME *obj, P_TYPE p){RET_COMMAND obj->FUNC_NAME##4D(p);} \
static inline RET_TYPE FUNC_NAME##5DCB(CLASS_NAME *obj, P_TYPE p){RET_COMMAND obj->FUNC_NAME##5D(p);} \
static inline RET_TYPE FUNC_NAME##6DCB(CLASS_NAME *obj, P_TYPE p){RET_COMMAND obj->FUNC_NAME##6D(p);} \
\
/* Implement a switch to set the correct function for the correct dimension extent. */ \
void _init##FUNC_NAME##TYPE(MLint dim){ \
switch (dim){ \
case 1: FUNC_NAME = FUNC_NAME##1DCB; break; \
case 2: FUNC_NAME = FUNC_NAME##2DCB; break; \
case 3: FUNC_NAME = FUNC_NAME##3DCB; break; \
case 4: FUNC_NAME = FUNC_NAME##4DCB; break; \
case 5: FUNC_NAME = FUNC_NAME##5DCB; break; \
case 6: FUNC_NAME = FUNC_NAME##6DCB; break; \
default: ML_PRINT_FATAL_ERROR("IMPLEMENT_DIM_DISPATCHER_P1", ML_PROGRAMMING_ERROR, \
"Using 6d implementation."); \
} \
}

For documentation see IMPLEMENT_DIM_DISPATCHER_P0.

The difference is that here an additional parameter type P_TYPE must be specified which must be passed to calls the static function and so also to calls of the member variable.

Definition at line 112 of file mlWrapperMacros.h.

◆ IMPLEMENT_EXC_DISPATCHER_P0

#define IMPLEMENT_EXC_DISPATCHER_P0 (   FUNC_NAME,
  CLASS_NAME,
  RET_TYPE,
  RET_COMMAND 
)

This macro defines a function type and 12 static functions of this type.

The function type is given from FUNC_NAME + "TYPE". The 12 functions are named FUNC_NAME + "1DCBN", ..., FUNC_NAME + "6DCBN" and FUNC_NAME + "1DCBE", ..., FUNC_NAME + "6DCBE" for callback versions from 1D to 6D without exception handling and for versions from 1D to 6D with exception handling. These 12 static functions call the corresponding functions named FUNC_NAME + "1D", ..., FUNC_NAME + "6D" and FUNC_NAME + "1DE", ..., FUNC_NAME + "6DE" which must be implemented as members of the object passed as obj which is of the type given by CLASS_NAME.

The return type of the callback function is passed by RET_TYPE. Pass 'void' for no return value. The return command (usually 'return') is passed as RET_COMMAND. Use ML_EMPTY_SPACE for no return command.

Moreover six members of the function type are created with names FUNC_NAME + "1", ..., FUNC_NAME + "6". Also an initialization function with name "_init" + FUNC_NAME + "TYPE" is implemented which sets the 6 members to the addresses of the functions terminating with "CBE" if useException is passed as true. Otherwise they are set to the functions terminating with "CBN" for normal implementation. So always the code with/without exception handling is used dynamically by simply calling the member and passing the this-pointer of the object.

Definition at line 166 of file mlWrapperMacros.h.

◆ ML_EMPTY_SPACE

#define ML_EMPTY_SPACE

In this header some macros are defined which implement some c-wrapper stuff to address member functions via a pointer.

The problem to be solved is to implement a function or method in a class which is highly efficient, but the performance differs strongly, for example dependent on the dynamic image dimension. There are two cases:

  • Since many functions like setCursorPosition need 6 dimensional coordinates the 6 components need to be calculated which spends much time if e.g. only a 2d image is processed. So some classes in the ML implement functions like setCursorPosition 6 times - the fastest version only for one dimensional images up to the slowest version for 6 dimensional images. To avoid that the setCursorPosition method needs to select the correct version on each call (too slow) the according function is called via a pointer which is initialized to the correct function when the image extents are defined. So always the most efficient code is used for each image extent.
  • The second case is to select an exception handling and normal version of code. To select this dynamically the same strategy is used. Often only the common code is desired since no range checks are performed and no exception throwing/handling is implemented, which then is usually faster.

Since c++ does not permit function pointers to member functions this needs to be done with static c functions which then call the member function. These macros are specialized to implement these static functions and an initialization method which sets the correct function dependent on the image dimension. A simple macro containing nothing to be passed as macro parameter which has no content.

Definition at line 52 of file mlWrapperMacros.h.