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