fork(1) download
  1. /*!
  2.  * @file GenericImage_typeDispatch.cpp
  3.  * @brief
  4.  * @author vectra
  5.  * @date 16/05/19
  6.  */
  7.  
  8. #include <iostream>
  9. #include <vector>
  10. #include <exception>
  11. #include <array>
  12.  
  13.  
  14. using namespace std;
  15.  
  16.  
  17. // =============================================================================
  18. // type helpers
  19. // =============================================================================
  20.  
  21.  
  22. template < typename T >
  23. void showType(T var)
  24. { throw; }
  25.  
  26. template <>
  27. void showType(double var)
  28. { cout << "double"; }
  29.  
  30. template <>
  31. void showType(int var)
  32. { cout << "int"; }
  33.  
  34. template <>
  35. void showType(float var)
  36. { cout << "float"; }
  37.  
  38.  
  39.  
  40. // =============================================================================
  41. // dummy typed image class (implemented likewise by many real image libs)
  42. // =============================================================================
  43.  
  44.  
  45. class Image
  46. {
  47. public:
  48.  
  49. enum class Type
  50. {
  51. Float64,
  52. Float32,
  53. Int32,
  54. } type_;
  55.  
  56. std::size_t voxel_count_;
  57. void *data_ptr_ = nullptr;
  58.  
  59. Image()
  60. {}
  61.  
  62. void
  63. allocate(Image::Type t, size_t voxel_count)
  64. {
  65. type_ = t;
  66. voxel_count_ = voxel_count;
  67.  
  68. switch (t)
  69. {
  70. case Image::Type::Float64:
  71. data_ptr_ = static_cast<void *>(new double[voxel_count]);
  72. break;
  73. case Image::Type::Int32:
  74. data_ptr_ = static_cast<void *>(new int[voxel_count]);
  75. break;
  76. default:
  77. throw;
  78. }
  79. }
  80.  
  81. void
  82. set_data(Image::Type t, void *data)
  83. {
  84. if ( data_ptr_ != nullptr ) throw;
  85. type_ = t;
  86. data_ptr_ = data;
  87. }
  88. };
  89.  
  90.  
  91. // =============================================================================
  92. // Dispatcher mother, where all ropes are hidden from the user
  93. // =============================================================================
  94.  
  95.  
  96. template < class Derived >
  97. class ExecutorMother
  98. {
  99. public:
  100. Image *img_ = nullptr;
  101.  
  102. ExecutorMother(Image *img) : img_(img)
  103. {}
  104.  
  105.  
  106. // This code compiles but does not work as expected (int filter function always called)
  107. template < class ... ArgsType >
  108. void
  109. operator()(ArgsType ... arguments)
  110. {
  111. if ( ExecutorMother::img_ -> data_ptr_ == nullptr ) throw;
  112. Derived &derived = static_cast<Derived &>(*this);
  113.  
  114. switch (ExecutorMother::img_ -> type_)
  115. {
  116. case Image::Type::Float64:
  117. {
  118. derived . filter_function(arguments ...);
  119. //derived . filter_function<double>(arguments ...); // auugh! why!!
  120. break;
  121. }
  122. case Image::Type::Float32:
  123. {
  124. derived . filter_function(arguments ...);
  125. //derived . filter_function<float>(arguments ...); // auugh! why!!
  126. break;
  127. }
  128. case Image::Type::Int32:
  129. {
  130. derived . filter_function(arguments ...);
  131. //derived . filter_function<int>(arguments ...); // auugh! why!!
  132. break;
  133. }
  134. default:
  135. throw;// std::bad_exception;
  136. }
  137. }
  138.  
  139.  
  140. };
  141.  
  142.  
  143. // =============================================================================
  144. // Dispatcher mother, where all ropes are hidden from the user
  145. // =============================================================================
  146.  
  147.  
  148. class CustomDispatcher : public ExecutorMother<CustomDispatcher>
  149. {
  150. public:
  151.  
  152. CustomDispatcher(Image *img) : ExecutorMother(img)
  153. {}
  154.  
  155.  
  156. template < typename ImgDataType >
  157. void
  158. filter_function(ImgDataType trigger_val, int iters, float dummy)
  159. {
  160. ImgDataType *data = static_cast<ImgDataType *>(ExecutorMother::img_ -> data_ptr_);
  161.  
  162. cout << endl << "Types for filter: ";
  163. showType(data[0]);
  164. cout << " / arg1: ";
  165. showType(trigger_val);
  166. cout << " / arg2: ";
  167. showType(iters);
  168. cout << " / arg3: ";
  169. showType(dummy);
  170.  
  171.  
  172. for (size_t i = 0; i < ExecutorMother::img_ -> voxel_count_; i ++)
  173. {
  174. if ( data[i] == trigger_val )
  175. data[i] = data[i] + iters;
  176. }
  177. }
  178.  
  179.  
  180. /*
  181.   * @brief this code works 100% fine; but would like it hidden in motherclass
  182.   */
  183. /*
  184.   template < class ... ArgsType >
  185.   void
  186.   operator()(ArgsType ... arguments)
  187.   {
  188.   if ( ExecutorMother::img_ -> data_ptr_ == nullptr ) throw;
  189.  
  190.   switch (ExecutorMother::img_ -> type_)
  191.   {
  192.   case Image::Type::Float64:
  193.   {
  194.   filter_function<double>(arguments ...);
  195.   break;
  196.   }
  197.   case Image::Type::Float32:
  198.   {
  199.   filter_function<float>(arguments ...);
  200.   break;
  201.   }
  202.   case Image::Type::Int32:
  203.   {
  204.   \
  205.   filter_function<int>(arguments ...);
  206.   break;
  207.   }
  208.   default:
  209.   throw;// std::bad_exception;
  210.   }
  211.   }
  212.   */
  213.  
  214. };
  215.  
  216.  
  217. int main()
  218. {
  219. std::array<int, 8> data = {1, 2, 3, - 32768, 5, 6, 7, 8};
  220.  
  221. Image imgd;
  222. imgd . allocate(Image::Type::Float64, 2 * 4);
  223. Image imgi;
  224. imgi . allocate(Image::Type::Int32, 2 * 4);
  225.  
  226.  
  227. CustomDispatcher execd(&imgd);
  228. execd(- 32768, 32000, 3.14);
  229. cout << endl << "double attendu pour type filtre";
  230. CustomDispatcher execi(&imgi);
  231. execi(- 32768, 32000, 3.14);
  232. cout << endl << "int attendu pour type filtre";
  233.  
  234.  
  235. return 0;
  236. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Types for filter: int / arg1: int / arg2: int / arg3: float
double attendu pour type filtre
Types for filter: int / arg1: int / arg2: int / arg3: float
int attendu pour type filtre