fork(2) 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. // would like this one here!
  106. /*
  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.   break;
  120.   }
  121.   case Image::Type::Float32:
  122.   {
  123.   derived . filter_function(arguments ...);
  124.   break;
  125.   }
  126.   case Image::Type::Int32:
  127.   {
  128.   derived . filter_function(arguments ...);
  129.   break;
  130.   }
  131.   default:
  132.   throw;// std::bad_exception;
  133.   }
  134.   }
  135.   */
  136.  
  137. };
  138.  
  139.  
  140. // =============================================================================
  141. // Dispatcher mother, where all ropes are hidden from the user
  142. // =============================================================================
  143.  
  144.  
  145. class CustomDispatcher : public ExecutorMother<CustomDispatcher>
  146. {
  147. public:
  148.  
  149. CustomDispatcher(Image *img) : ExecutorMother(img)
  150. {}
  151.  
  152.  
  153. template < typename ImgDataType >
  154. void
  155. filter_function(ImgDataType trigger_val, int iters, float dummy)
  156. {
  157. ImgDataType *data = static_cast<ImgDataType *>(ExecutorMother::img_ -> data_ptr_);
  158.  
  159. cout << endl << "Types for filter: ";
  160. showType(data[0]);
  161. cout << " / arg1: ";
  162. showType(trigger_val);
  163. cout << " / arg2: ";
  164. showType(iters);
  165. cout << " / arg3: ";
  166. showType(dummy);
  167.  
  168.  
  169. for (size_t i = 0; i < ExecutorMother::img_ -> voxel_count_; i ++)
  170. {
  171. if ( data[i] == trigger_val )
  172. data[i] = data[i] + iters;
  173. }
  174. }
  175.  
  176.  
  177. /*
  178.   * @brief would like this one hidden in motherclass
  179.   */
  180. template < class ... ArgsType >
  181. void
  182. operator()(ArgsType ... arguments)
  183. {
  184. if ( ExecutorMother::img_ -> data_ptr_ == nullptr ) throw;
  185.  
  186. switch (ExecutorMother::img_ -> type_)
  187. {
  188. case Image::Type::Float64:
  189. {
  190. filter_function<double>(arguments ...);
  191. break;
  192. }
  193. case Image::Type::Float32:
  194. {
  195. filter_function<float>(arguments ...);
  196. break;
  197. }
  198. case Image::Type::Int32:
  199. {
  200. \
  201. filter_function<int>(arguments ...);
  202. break;
  203. }
  204. default:
  205. throw;// std::bad_exception;
  206. }
  207. }
  208.  
  209.  
  210. };
  211.  
  212.  
  213. int main()
  214. {
  215. std::array<int, 8> data = {1, 2, 3, - 32768, 5, 6, 7, 8};
  216.  
  217. Image imgd;
  218. imgd . allocate(Image::Type::Float64, 2 * 4);
  219. Image imgi;
  220. imgi . allocate(Image::Type::Int32, 2 * 4);
  221.  
  222.  
  223. CustomDispatcher execd(&imgd);
  224. execd(- 32768, 32000, 3.14);
  225. CustomDispatcher execi(&imgi);
  226. execi(- 32768, 32000, 3.14);
  227.  
  228.  
  229. return 0;
  230. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Types for filter: double / arg1: double / arg2: int / arg3: float
Types for filter: int / arg1: int / arg2: int / arg3: float