fork(1) download
  1. #include <functional> //for std::is_placeholder<T>
  2.  
  3. /*#include <boost/bind/arg.hpp>
  4. // ************************************************************************************************
  5. namespace std {
  6. template <> struct is_placeholder<boost::arg<1>> : integral_constant<int, 1> {};
  7. template <> struct is_placeholder<boost::arg<2>> : integral_constant<int, 2> {};
  8. template <> struct is_placeholder<boost::arg<3>> : integral_constant<int, 3> {};
  9. template <> struct is_placeholder<boost::arg<4>> : integral_constant<int, 4> {};
  10. template <> struct is_placeholder<boost::arg<5>> : integral_constant<int, 5> {};
  11. template <> struct is_placeholder<boost::arg<6>> : integral_constant<int, 6> {};
  12. template <> struct is_placeholder<boost::arg<7>> : integral_constant<int, 7> {};
  13. template <> struct is_placeholder<boost::arg<8>> : integral_constant<int, 8> {};
  14. template <> struct is_placeholder<boost::arg<9>> : integral_constant<int, 9> {};
  15. }*/
  16.  
  17. namespace my {
  18.  
  19. struct ILL { ILL(int) {} typedef ILL first_type; };
  20.  
  21. //************************************************************************************************
  22. //placeholderなら実引数に変換
  23. template <typename P, typename A1, typename A2, typename A3, typename A4, typename A5>
  24. struct alt_type {
  25. typedef typename std::remove_cv<typename std::remove_reference<P>::type>::type naked_param_type;
  26. static const int N = std::is_placeholder<naked_param_type>::value;
  27. typedef typename std::conditional<N == 0, P,
  28. typename std::conditional<N == 1, A1,
  29. typename std::conditional<N == 2, A2,
  30. typename std::conditional<N == 3, A3,
  31. typename std::conditional<N == 4, A4,
  32. typename std::conditional<N == 5, A5,
  33. ILL>::type
  34. >::type>::type>::type>::type>::type
  35. type;
  36. };
  37. //************************************************************************************************
  38. //引数型と戻値型
  39. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5, int N>
  40. struct func_signature_base;
  41. //フリー関数/メンバ関数の区別と戻値型
  42. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5>
  43. struct func_signature_base0 {
  44. typedef F func_type;
  45. typedef P1 param1_type; typedef P2 param2_type; typedef P3 param3_type; typedef P4 param4_type; typedef P5 param5_type;
  46. static F getF();
  47. static P1 get1(); static P2 get2(); static P3 get3(); static P4 get4(); static P5 get5();
  48. //フリー関数は char, Obj.*mFは short, pObj->*mFはint (int********** の'*'の数は引数の数)
  49. template <typename V> static char
  50. test(V v, int*****, decltype( v (get1(), get2(), get3(), get4(), get5()), (int)0) = 0);
  51. template <typename V> static short
  52. test(V v, int*****, decltype( (get1().*v)(get2(), get3(), get4(), get5()), (int)0) = 0);
  53. template <typename V> static int
  54. test(V v, int*****, decltype((get1()->*v)(get2(), get3(), get4(), get5()), (int)0) = 0);
  55. template <typename V> static char
  56. test(V v, int****, decltype( v (get2(), get3(), get4(), get5()), (int)0) = 0);
  57. template <typename V> static short
  58. test(V v, int****, decltype( (get2().*v)(get3(), get4(), get5()), (int)0) = 0);
  59. template <typename V> static int
  60. test(V v, int****, decltype((get2()->*v)(get3(), get4(), get5()), (int)0) = 0);
  61. template <typename V> static char
  62. test(V v, int***, decltype( v (get3(), get4(), get5()), (int)0) = 0);
  63. template <typename V> static short
  64. test(V v, int***, decltype( (get3().*v)(get4(), get5()), (int)0) = 0);
  65. template <typename V> static int
  66. test(V v, int***, decltype((get3()->*v)(get4(), get5()), (int)0) = 0);
  67. template <typename V> static char
  68. test(V v, int**, decltype( v (get4(), get5()), (int)0) = 0);
  69. template <typename V> static short
  70. test(V v, int**, decltype( (get4().*v)(get5()), (int)0) = 0);
  71. template <typename V> static int
  72. test(V v, int**, decltype((get4()->*v)(get5()), (int)0) = 0);
  73. template <typename V> static char
  74. test(V v, int*, decltype( v (get5()), (int)0) = 0);
  75. template <typename V> static short
  76. test(V v, int*, decltype( (get5().*v)(), (int)0) = 0);
  77. template <typename V> static int
  78. test(V v, int*, decltype((get5()->*v)(), (int)0) = 0);
  79. template <typename V> static char
  80. test(V v, int, decltype(v(), (int)0) = 0);
  81. static long test(...);
  82. //フリー関数かメンバ関数かに応じた戻値型 (int********** の'*'の数は引数の数)
  83. template <typename V, typename FM> static auto // FMはフリー関数orメンバ関数の印
  84. return_t(V v, int*****, FM, typename std::enable_if<std::is_same<FM, char>::value, V>::type* = 0)
  85. ->decltype(v(get1(), get2(), get3(), get4(), get5()));
  86. template <typename V, typename FM> static auto
  87. return_t(V v, int*****, FM, typename std::enable_if<std::is_same<FM, short>::value, V>::type* = 0)
  88. ->decltype(((get1()).*v)(get2(), get3(), get4(), get5()));
  89. template <typename V, typename FM> static auto
  90. return_t(V v, int*****, FM, typename std::enable_if<std::is_same<FM, int>::value, V>::type* = 0)
  91. ->decltype(((get1())->*v)(get2(), get3(), get4(), get5()));
  92. template <typename V, typename FM> static auto
  93. return_t(V v, int****, FM, typename std::enable_if<std::is_same<FM, char>::value, V>::type* = 0)
  94. ->decltype( v(get2(), get3(), get4(), get5()));
  95. template <typename V, typename FM> static auto
  96. return_t(V v, int****, FM, typename std::enable_if<std::is_same<FM, short>::value, V>::type* = 0)
  97. ->decltype((( get2()).*v)(get3(), get4(), get5()));
  98. template <typename V, typename FM> static auto
  99. return_t(V v, int****, FM, typename std::enable_if<std::is_same<FM, int>::value, V>::type* = 0)
  100. ->decltype(((get2())->*v)(get3(), get4(), get5()));
  101. template <typename V, typename FM> static auto
  102. return_t(V v, int***, FM, typename std::enable_if<std::is_same<FM, char>::value, V>::type* = 0)
  103. ->decltype( v(get3(), get4(), get5()));
  104. template <typename V, typename FM> static auto
  105. return_t(V v, int***, FM, typename std::enable_if<std::is_same<FM, short>::value, V>::type* = 0)
  106. ->decltype((( get3()).*v)(get4(), get5()));
  107. template <typename V, typename FM> static auto
  108. return_t(V v, int***, FM, typename std::enable_if<std::is_same<FM, int>::value, V>::type* = 0)
  109. ->decltype(((get3())->*v)(get4(), get5()));
  110. template <typename V, typename FM> static auto
  111. return_t(V v, int**, FM, typename std::enable_if<std::is_same<FM, char>::value, V>::type* = 0)
  112. ->decltype( v(get4(), get5()));
  113. template <typename V, typename FM> static auto
  114. return_t(V v, int**, FM, typename std::enable_if<std::is_same<FM, short>::value, V>::type* = 0)
  115. ->decltype((( get4()).*v)(get5()));
  116. template <typename V, typename FM> static auto
  117. return_t(V v, int**, FM, typename std::enable_if<std::is_same<FM, int>::value, V>::type* = 0)
  118. ->decltype(((get4())->*v)(get5()));
  119. template <typename V, typename FM> static auto
  120. return_t(V v, int*, FM, typename std::enable_if<std::is_same<FM, char>::value, V>::type* = 0)
  121. ->decltype( v(get5()));
  122. template <typename V, typename FM> static auto
  123. return_t(V v, int*, FM, typename std::enable_if<std::is_same<FM, short>::value, V>::type* = 0)
  124. ->decltype((( get5()).*v)());
  125. template <typename V, typename FM> static auto
  126. return_t(V v, int*, FM, typename std::enable_if<std::is_same<FM, int>::value, V>::type* = 0)
  127. ->decltype(((get5())->*v)());
  128. template <typename V, typename FM> static auto
  129. return_t(V v, int, FM, typename std::enable_if<std::is_same<FM, char>::value, V>::type* = 0)
  130. ->decltype(v());
  131. static ILL return_t(...);
  132. };
  133. // 5 parameters
  134. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5>
  135. struct func_signature_base<F, P1, P2, P3, P4, P5, 5> : func_signature_base0<F, P1, P2, P3, P4, P5> {
  136. typedef func_signature_base0<F, P1, P2, P3, P4, P5> B;
  137. typedef decltype(B::test(B::getF(),(int*****)0)) fm_type;
  138. typedef decltype(B::return_t(B::getF(), (int*****)0, (fm_type)0)) return_type;
  139. };
  140. // 4 parameters
  141. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5>
  142. struct func_signature_base<F, P1, P2, P3, P4, P5, 4> : func_signature_base0<F, P1, P2, P3, P4, P5> {
  143. typedef func_signature_base0<F, P1, P2, P3, P4, P5> B;
  144. typedef decltype(B::test(B::getF(),(int****)0)) fm_type;
  145. typedef decltype(B::return_t(B::getF(), (int****)0, (fm_type)0)) return_type;
  146. };
  147. // 3 parameters
  148. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5>
  149. struct func_signature_base<F, P1, P2, P3, P4, P5, 3> : func_signature_base0<F, P1, P2, P3, P4, P5> {
  150. typedef func_signature_base0<F, P1, P2, P3, P4, P5> B;
  151. typedef decltype(B::test(B::getF(),(int***)0)) fm_type;
  152. typedef decltype(B::return_t(B::getF(), (int***)0, (fm_type)0)) return_type;
  153. };
  154. // 2 parameters
  155. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5>
  156. struct func_signature_base<F, P1, P2, P3, P4, P5, 2> : func_signature_base0<F, P1, P2, P3, P4, P5> {
  157. typedef func_signature_base0<F, P1, P2, P3, P4, P5> B;
  158. typedef decltype(B::test(B::getF(),(int**)0)) fm_type;
  159. typedef decltype(B::return_t(B::getF(), (int**)0, (fm_type)0)) return_type;
  160. };
  161. // 1 parameters
  162. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5>
  163. struct func_signature_base<F, P1, P2, P3, P4, P5, 1> : func_signature_base0<F, P1, P2, P3, P4, P5> {
  164. typedef func_signature_base0<F, P1, P2, P3, P4, P5> B;
  165. typedef decltype(B::test(B::getF(),(int*)0)) fm_type;
  166. typedef decltype(B::return_t(B::getF(), (int*)0, (fm_type)0)) return_type;
  167. };
  168. // 0 parameters
  169. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5>
  170. struct func_signature_base<F, P1, P2, P3, P4, P5, 0> : func_signature_base0<F, P1, P2, P3, P4, P5> {
  171. typedef func_signature_base0<F, P1, P2, P3, P4, P5> B;
  172. typedef decltype(B::test(B::getF(),(int)0)) fm_type;
  173. typedef decltype(B::return_t(B::getF(), (int)0, (fm_type)0)) return_type;
  174. };
  175. //------------------------------------------------------------------------------------------------
  176. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5,
  177. typename A1, typename A2, typename A3, typename A4, typename A5, int N>
  178. struct func_signature : func_signature_base<typename alt_type<F , A1, A2, A3, A4, A5>::type ,
  179. typename alt_type<P1, A1, A2, A3, A4, A5>::type ,
  180. typename alt_type<P2, A1, A2, A3, A4, A5>::type ,
  181. typename alt_type<P3, A1, A2, A3, A4, A5>::type ,
  182. typename alt_type<P4, A1, A2, A3, A4, A5>::type ,
  183. typename alt_type<P5, A1, A2, A3, A4, A5>::type ,
  184. N >
  185. { };
  186. //************************************************************************************************
  187. template <typename P>
  188. struct ParamOf {
  189. typedef P param_type;
  190. typedef typename std::remove_cv<typename std::remove_reference<P>::type>::type naked_param_type;
  191. static const size_t placeholder = std::is_placeholder<naked_param_type>::value;
  192. mutable P param;
  193. ParamOf(P p) : param(p) { }
  194. ParamOf(const ParamOf<P>& p) : param(p.param) { }
  195. };
  196. //------------------------------------------------------------------------------------------------
  197. //placeholderだったら実引数に変換する SFINAE
  198. template <typename P, typename A1, typename A2, typename A3, typename A4, typename A5>
  199. typename P::param_type
  200. pass(P* p, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, typename std::enable_if<P::placeholder==0>::type* = 0)
  201. { return p->param; }
  202. template <typename P, typename A1, typename A2, typename A3, typename A4, typename A5>
  203. A1&& pass(P* p, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, typename std::enable_if<P::placeholder==1>::type* = 0)
  204. { return std::forward<A1>(a1); }
  205. template <typename P, typename A1, typename A2, typename A3, typename A4, typename A5>
  206. A2&& pass(P* p, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, typename std::enable_if<P::placeholder==2>::type* = 0)
  207. { return std::forward<A2>(a2); }
  208. template <typename P, typename A1, typename A2, typename A3, typename A4, typename A5>
  209. A3&& pass(P* p, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, typename std::enable_if<P::placeholder==3>::type* = 0)
  210. { return std::forward<A3>(a3); }
  211. template <typename P, typename A1, typename A2, typename A3, typename A4, typename A5>
  212. A4&& pass(P* p, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, typename std::enable_if<P::placeholder==4>::type* = 0)
  213. { return std::forward<A4>(a4); }
  214. template <typename P, typename A1, typename A2, typename A3, typename A4, typename A5>
  215. A5&& pass(P* p, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, typename std::enable_if<P::placeholder==5>::type* = 0)
  216. { return std::forward<A5>(a5); }
  217. //************************************************************************************************
  218. template <int N, typename S, typename T = char> struct executer;
  219. //************************************************************************************************
  220. template <typename P, typename T = ILL, typename F = P, int N = 0>
  221. struct BindOf : ParamOf<P> {
  222. T target;
  223. static const int depth = N;
  224. typedef T target_type;
  225. typedef F func_type;
  226. typedef BindOf<P, T, F, N> MyT;
  227. typedef typename ParamOf<P>::param_type param_type;
  228. typedef typename std::conditional<N == 0, MyT, T>::type back_type;
  229. typedef typename std::conditional<N == 0, MyT, typename T::first_type>::type first_type;
  230. BindOf(const P& p) : ParamOf<P>(p), target(0) { } // bindOfで来る
  231. BindOf(const P p, T& t) : ParamOf<P>(p), target(t) { } // << で来る
  232. BindOf(P p, T&& t) : ParamOf<P>(p), target((T&&)t) { } // << で来る
  233. BindOf(MyT&& t) : ParamOf<P>(t), target((T&&)(t.target)) { }
  234. back_type* getTarget() const { return (depth == 0)? (back_type*)this: (back_type*)&target; }
  235. first_type* get0() const { return (depth == 0)? (first_type*)this: getTarget()->get0(); }
  236. //
  237. template <typename A1, typename A2, typename A3, typename A4, typename A5>
  238. struct mySignature {
  239. typedef typename my::func_signature<func_type,
  240. typename back_type::back_type::back_type::back_type::param_type,
  241. typename back_type::back_type::back_type::param_type,
  242. typename back_type::back_type::param_type,
  243. typename back_type::param_type,
  244. param_type,
  245. A1, A2, A3, A4, A5, depth>
  246. type;
  247. };
  248. //bindする変数を追加していく operator <<
  249. template <typename PN> BindOf<PN, MyT, func_type, depth + 1>
  250. operator <<(PN&& p)
  251. { return BindOf<PN, MyT, func_type, depth + 1>(std::forward<PN>(p), (MyT&&)*this); }
  252. // ファンクタとしての operator(a,b,c,d,e)
  253. template <typename A1, typename A2, typename A3, typename A4, typename A5>
  254. auto operator ()(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5) const
  255. ->typename mySignature<A1, A2, A3, A4, A5>::type::return_type
  256. {
  257. typedef typename mySignature<A1, A2, A3, A4, A5>::type signature;
  258. executer<depth, signature, typename signature::fm_type>
  259. theExecuter(pass(get0(), a1, a2, a3, a4, a5));
  260. return theExecuter
  261. (
  262. pass(getTarget()->getTarget()->getTarget()->getTarget(), a1, a2, a3, a4, a5),
  263. pass(getTarget()->getTarget()->getTarget(), a1, a2, a3, a4, a5),
  264. pass(getTarget()->getTarget(), a1, a2, a3, a4, a5),
  265. pass(getTarget(), a1, a2, a3, a4, a5),
  266. pass(this, a1, a2, a3, a4, a5)
  267. );
  268. }
  269. // ファンクタとしての operator(a,b,c,d)
  270. template <typename A1, typename A2, typename A3, typename A4>
  271. auto operator ()(A1&& a1, A2&& a2, A3&& a3, A4&& a4) const
  272. ->typename mySignature<A1, A2, A3, A4, ILL>::type::return_type
  273. { return (*this)((A1&&)a1, (A2&&)a2, (A3&&)a3, (A4&&)a4, ILL(0)); }
  274. // ファンクタとしての operator(a,b,c)
  275. template <typename A1, typename A2, typename A3>
  276. auto operator ()(A1&& a1, A2&& a2, A3&& a3) const
  277. ->typename mySignature<A1, A2, A3, ILL, ILL>::type::return_type
  278. { return (*this)((A1&&)a1, (A2&&)a2, (A3&&)a3, ILL(0), ILL(0)); }
  279. // ファンクタとしての operator(a,b)
  280. template <typename A1, typename A2>
  281. auto operator ()(A1&& a1, A2&& a2) const
  282. ->typename mySignature<A1, A2, ILL, ILL, ILL>::type::return_type
  283. { return (*this)((A1&&)a1, (A2&&)a2, ILL(0), ILL(0), ILL(0)); }
  284. // ファンクタとしての operator(a)
  285. template <typename A1>
  286. auto operator ()(A1&& a1) const
  287. ->typename mySignature<A1, ILL, ILL, ILL, ILL>::type::return_type
  288. { return (*this)((A1&&)a1, ILL(0), ILL(0), ILL(0), ILL(0)); }
  289. // ファンクタとしての operator(void)
  290. auto operator ()() const
  291. ->typename mySignature<ILL, ILL, ILL, ILL, ILL>::type::return_type
  292. { return (*this)(ILL(0), ILL(0), ILL(0), ILL(0), ILL(0)); }
  293. };
  294. //************************************************************************************************
  295. // execute with 5 parameters
  296. template <typename S>
  297. struct executer<5, S> {
  298. typedef typename S::func_type func_type;
  299. func_type org_function;
  300. executer(const func_type& f) : org_function(f) { }
  301. typename S::return_type operator ()(typename S::param1_type p1,
  302. typename S::param2_type p2,
  303. typename S::param3_type p3,
  304. typename S::param4_type p4,
  305. typename S::param5_type p5) const
  306. { return org_function(p1, p2, p3, p4, p5); }
  307. };
  308. template <typename S>
  309. struct executer<5, S, short> {
  310. typedef typename S::func_type func_type;
  311. func_type org_function;
  312. executer(const func_type& f) : org_function(f) { }
  313. typename S::return_type operator ()(typename S::param1_type Obj,
  314. typename S::param2_type p2,
  315. typename S::param3_type p3,
  316. typename S::param4_type p4,
  317. typename S::param5_type p5) const
  318. { return (Obj.*org_function)(p2, p3, p4, p5); }
  319. };
  320. template <typename S>
  321. struct executer<5, S, int> {
  322. typedef typename S::func_type func_type;
  323. func_type org_function;
  324. executer(const func_type& f) : org_function(f) { }
  325. typename S::return_type operator ()(typename S::param1_type pObj,
  326. typename S::param2_type p2,
  327. typename S::param3_type p3,
  328. typename S::param4_type p4,
  329. typename S::param5_type p5) const
  330. { return (pObj->*org_function)(p2, p3, p4, p5); }
  331. };
  332. // execute with 4 parameters
  333. template <typename S>
  334. struct executer<4, S> {
  335. typedef typename S::func_type func_type;
  336. func_type org_function;
  337. executer(const func_type& f) : org_function(f) { }
  338. typename S::return_type operator ()(typename S::param1_type p1,
  339. typename S::param2_type p2,
  340. typename S::param3_type p3,
  341. typename S::param4_type p4,
  342. typename S::param5_type p5) const
  343. { return org_function(p2, p3, p4, p5); }
  344. };
  345. template <typename S>
  346. struct executer<4, S, short> {
  347. typedef typename S::func_type func_type;
  348. func_type org_function;
  349. executer(const func_type& f) : org_function(f) { }
  350. typename S::return_type operator ()(typename S::param1_type p1,
  351. typename S::param2_type Obj,
  352. typename S::param3_type p3,
  353. typename S::param4_type p4,
  354. typename S::param5_type p5) const
  355. { return (Obj.*org_function)(p3, p4, p5); }
  356. };
  357. template <typename S>
  358. struct executer<4, S, int> {
  359. typedef typename S::func_type func_type;
  360. func_type org_function;
  361. executer(const func_type& f) : org_function(f) { }
  362. typename S::return_type operator ()(typename S::param1_type p1,
  363. typename S::param2_type pObj,
  364. typename S::param3_type p3,
  365. typename S::param4_type p4,
  366. typename S::param5_type p5) const
  367. { return (pObj->*org_function)(p3, p4, p5); }
  368. };
  369. // execute with 3 parameters
  370. template <typename S>
  371. struct executer<3, S> {
  372. typedef typename S::func_type func_type;
  373. func_type org_function;
  374. executer(const func_type& f) : org_function(f) { }
  375. typename S::return_type operator ()(typename S::param1_type p1,
  376. typename S::param2_type p2,
  377. typename S::param3_type p3,
  378. typename S::param4_type p4,
  379. typename S::param5_type p5) const
  380. { return org_function(p3, p4, p5); }
  381. };
  382. template <typename S>
  383. struct executer<3, S, short> {
  384. typedef typename S::func_type func_type;
  385. func_type org_function;
  386. executer(const func_type& f) : org_function(f) { }
  387. typename S::return_type operator ()(typename S::param1_type p1,
  388. typename S::param2_type p2,
  389. typename S::param3_type Obj,
  390. typename S::param4_type p4,
  391. typename S::param5_type p5) const
  392. { return (Obj.*org_function)(p4, p5); }
  393. };
  394. template <typename S>
  395. struct executer<3, S, int> {
  396. typedef typename S::func_type func_type;
  397. func_type org_function;
  398. executer(const func_type& f) : org_function(f) { }
  399. typename S::return_type operator ()(typename S::param1_type p1,
  400. typename S::param2_type p2,
  401. typename S::param3_type pObj,
  402. typename S::param4_type p4,
  403. typename S::param5_type p5) const
  404. { return (pObj->*org_function)(p4, p5); }
  405. };
  406. // execute with 2 parameters
  407. template <typename S>
  408. struct executer<2, S> {
  409. typedef typename S::func_type func_type;
  410. func_type org_function;
  411. executer(const func_type& f) : org_function(f) { }
  412. typename S::return_type operator ()(typename S::param1_type p1,
  413. typename S::param2_type p2,
  414. typename S::param3_type p3,
  415. typename S::param4_type p4,
  416. typename S::param5_type p5) const
  417. { return org_function(p4, p5); }
  418. };
  419. template <typename S>
  420. struct executer<2, S, short> {
  421. typedef typename S::func_type func_type;
  422. func_type org_function;
  423. executer(const func_type& f) : org_function(f) { }
  424. typename S::return_type operator ()(typename S::param1_type p1,
  425. typename S::param2_type p2,
  426. typename S::param3_type p3,
  427. typename S::param4_type Obj,
  428. typename S::param5_type p5) const
  429. { return (Obj.*org_function)(p5); }
  430. };
  431. template <typename S>
  432. struct executer<2, S, int> {
  433. typedef typename S::func_type func_type;
  434. func_type org_function;
  435. executer(const func_type& f) : org_function(f) { }
  436. typename S::return_type operator ()(typename S::param1_type p1,
  437. typename S::param2_type p2,
  438. typename S::param3_type p3,
  439. typename S::param4_type pObj,
  440. typename S::param5_type p5) const
  441. { return (pObj->*org_function)(p5); }
  442. };
  443. // execute with 1 parameters
  444. template <typename S>
  445. struct executer<1, S> {
  446. typedef typename S::func_type func_type;
  447. func_type org_function;
  448. executer(const func_type& f) : org_function(f) { }
  449. typename S::return_type operator ()(typename S::param1_type p1,
  450. typename S::param2_type p2,
  451. typename S::param3_type p3,
  452. typename S::param4_type p4,
  453. typename S::param5_type p5) const
  454. { return org_function(p5); }
  455. };
  456. template <typename S>
  457. struct executer<1, S, short> {
  458. typedef typename S::func_type func_type;
  459. func_type org_function;
  460. executer(const func_type& f) : org_function(f) { }
  461. typename S::return_type operator ()(typename S::param1_type p1,
  462. typename S::param2_type p2,
  463. typename S::param3_type p3,
  464. typename S::param4_type p4,
  465. typename S::param5_type Obj) const
  466. { return (Obj.*org_function)(); }
  467. };
  468. template <typename S>
  469. struct executer<1, S, int> {
  470. typedef typename S::func_type func_type;
  471. func_type org_function;
  472. executer(const func_type& f) : org_function(f) { }
  473. typename S::return_type operator ()(typename S::param1_type p1,
  474. typename S::param2_type p2,
  475. typename S::param3_type p3,
  476. typename S::param4_type p4,
  477. typename S::param5_type pObj) const
  478. { return (pObj->*org_function)(); }
  479. };
  480. // execute with 0 parameters
  481. template <typename S>
  482. struct executer<0, S> {
  483. typedef typename S::func_type func_type;
  484. func_type org_function;
  485. executer(const func_type& f) : org_function(f) { }
  486. typename S::return_type operator ()(typename S::param1_type p1,
  487. typename S::param2_type p2,
  488. typename S::param3_type p3,
  489. typename S::param4_type p4,
  490. typename S::param5_type p5) const
  491. { return org_function(); }
  492. };
  493.  
  494. //************************************************************************************************
  495. //関数ポインタ以外のオブジェクト
  496. template <typename F>
  497. BindOf<typename std::remove_reference<F>::type>
  498. bindOf(F&& f)
  499. { return BindOf<typename std::remove_reference<F>::type>(std::forward<F>(f)); }
  500.  
  501. //関数ポインタ
  502. template <typename F>
  503. BindOf<F*>
  504. bindOf(F* f)
  505. { return BindOf<F*>(f); }
  506. //************************************************************************************************
  507. //ユーザが使う bind関数
  508. template <typename F, typename P1>
  509. auto bind(F&& f, P1&& p1)->decltype(bindOf(std::forward<F>(f)) << std::forward<P1>(p1))
  510. { return bindOf(std::forward<F>(f)) << std::forward<P1>(p1); }
  511.  
  512. template <typename F, typename P1, typename P2>
  513. auto bind(F&& f, P1&& p1, P2&& p2)->decltype(bindOf(std::forward<F>(f)) << std::forward<P1>(p1) << std::forward<P2>(p2))
  514. { return bindOf(std::forward<F>(f)) << std::forward<P1>(p1) << std::forward<P2>(p2); }
  515.  
  516. template <typename F, typename P1, typename P2, typename P3>
  517. auto bind(F&& f, P1&& p1, P2&& p2, P3&& p3)->decltype(bindOf(std::forward<F>(f)) << std::forward<P1>(p1)
  518. << std::forward<P2>(p2) << std::forward<P3>(p3))
  519. { return bindOf(std::forward<F>(f)) << std::forward<P1>(p1) << std::forward<P2>(p2) << std::forward<P3>(p3); }
  520.  
  521. template <typename F, typename P1, typename P2, typename P3, typename P4>
  522. auto bind(F&& f, P1&& p1, P2&& p2, P3&& p3, P4&& p4)
  523. ->decltype(bindOf(std::forward<F>(f)) << std::forward<P1>(p1) << std::forward<P2>(p2) << std::forward<P3>(p3) << std::forward<P4>(p4))
  524. { return bindOf(std::forward<F>(f)) << std::forward<P1>(p1) << std::forward<P2>(p2) << std::forward<P3>(p3) << std::forward<P4>(p4); }
  525.  
  526. template <typename F, typename P1, typename P2, typename P3, typename P4, typename P5>
  527. auto bind(F&& f, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)
  528. ->decltype(bindOf(std::forward<F>(f)) << std::forward<P1>(p1) << std::forward<P2>(p2) << std::forward<P3>(p3)
  529. << std::forward<P4>(p4) << std::forward<P5>(p5))
  530. { return bindOf(std::forward<F>(f)) << std::forward<P1>(p1) << std::forward<P2>(p2) << std::forward<P3>(p3)
  531. << std::forward<P4>(p4) << std::forward<P5>(p5); }
  532.  
  533. } //namespace my
  534.  
  535.  
  536. //************************************************************************************************
  537. //
  538. //************************************************************************************************
  539.  
  540. int f1(int a) { return 1 + a; }
  541. int f2(int a, int& b) { return a + (b *= 10); }
  542. int f3(int a, int& b, int c) { return a + (b *= 20) + c; }
  543. int f4(int a, int& b, int c, int& d) { return a + (b *= 30) + c + (d += 30); }
  544. int f5(int a, int& b, int c, int& d, int e) { return a + (b *= 40) + c + (d += 40) + e; }
  545.  
  546. struct Func {
  547. int operator ()() const { return 1000; }
  548. int operator ()(int a) const { return 1000 + a; }
  549. int operator ()(int a, int& b) const { return a + (b *= 1000); }
  550. int operator ()(int a, int& b, int c) const { return a + (b *= 2000) + c; }
  551. int operator ()(int a, int& b, int c, int& d) const { return a + (b *= 3000) + c + (d += 3000); }
  552. int func0() const { return (*this)(); }
  553. int func1(int a) const { return (*this)(a); }
  554. int func2(int a, int& b) const { return (*this)(a, b); }
  555. int func3(int a, int& b, int c) const { return (*this)(a, b, c); }
  556. int func4(int a, int& b, int c, int& d) const { return (*this)(a, b, c, d); }
  557. };
  558.  
  559. #include <iostream>
  560.  
  561. int main() {
  562. using namespace std::placeholders;
  563. int b = 1;
  564. int d = 1;
  565. int result = 0;
  566.  
  567. std::cout << "フリー関数 1変数バインド" << std::endl;
  568. auto bf11 = my::bind(f1, 1);
  569. result = bf11();
  570. std::cout << " f1(1) = " << result << '\n';
  571. std::cout << "フリー関数 1変数バインドせず" << std::endl;
  572. auto bf12 = my::bind(f1, _1);
  573. result = bf12(2);
  574. std::cout << " f1(2) = " << result << '\n';
  575. std::cout << "フリー関数 5変数" << std::endl;
  576. std::cout << " b = " << b << ", d = " << d << " ";
  577. auto bf51 = my::bind(f5, 1, _1, 8, d, _2);
  578. result = bf51(b, 3);
  579. std::cout << "f5(1, b, 8, d, 3) = " << result << " b = " << b << ", d = " << d << std::endl;
  580. std::cout << "ファンクタ 4変数" << std::endl;
  581. b = d = 1;
  582. Func fn;
  583. std::cout << " b = " << b << ", d = " << d << " ";
  584. auto bfn4 = my::bind(fn, 1, _1, 2, _2);
  585. result = bfn4(b, d);
  586. std::cout << "fn(1, b, 2, d) = " << result << " b = " << b << ", d = " << d << std::endl;
  587. std::cout << "ファンクタ メンバポインタ" << std::endl;
  588. b = d = 1;
  589. std::cout << " b = " << b << ", d = " << d << " ";
  590. auto bfn4m = my::bind(&Func::func4, fn, 1, _1, 2, _2);
  591. result = bfn4m(b, d);
  592. std::cout << "fn.*mF(1, b, 2, d) = " << result << " b = " << b << ", d = " << d << std::endl;
  593. b = d = 1;
  594. std::cout << " b = " << b << ", d = " << d << " ";
  595. auto bfn4mp = my::bind(&Func::func4, &fn, 1, _1, 2, _2);
  596. result = bfn4mp(b, d);
  597. std::cout << "fn->*mF(1, b, 2, d) = " << result << " b = " << b << ", d = " << d << std::endl;
  598.  
  599. b = d = 1;
  600. std::cout << "第一引数もプレースホルダにできる" << std::endl;
  601. std::cout << " b = " << b << ", d = " << d << " ";
  602. auto bfn4b1 = my::bind(_1, &fn, 101, _2, 202, _3);
  603. result = bfn4b1(&Func::func4, b, d);
  604. std::cout << "fn->*mF(101, b, 202, d) = " << result << " b = " << b << ", d = " << d << std::endl;
  605.  
  606. b = d = 2;
  607. std::cout << "どこにでも置ける" << std::endl;
  608. std::cout << " b = " << b << ", d = " << d << " ";
  609. auto bfn5bF = my::bind(_3, fn, 81, _1, 92, _2);
  610. result = bfn5bF(b, d, &Func::func4);
  611. std::cout << "fn.*mF(81, b, 92, d) = " << result << " b = " << b << ", d = " << d << std::endl;
  612. return 0;
  613. }
  614.  
Success #stdin #stdout 0s 3300KB
stdin
Standard input is empty
stdout
フリー関数 1変数バインド
  f1(1) = 2
フリー関数 1変数バインドせず
  f1(2) = 3
フリー関数 5変数
  b = 1, d = 1      f5(1, b, 8, d, 3) = 93        b = 40, d = 41
ファンクタ 4変数
  b = 1, d = 1      fn(1, b, 2, d) = 6004        b = 3000, d = 3001
ファンクタ メンバポインタ
  b = 1, d = 1      fn.*mF(1, b, 2, d) = 6004        b = 3000, d = 3001
  b = 1, d = 1      fn->*mF(1, b, 2, d) = 6004        b = 3000, d = 3001
第一引数もプレースホルダにできる
  b = 1, d = 1      fn->*mF(101, b, 202, d) = 6304        b = 3000, d = 3001
どこにでも置ける
  b = 2, d = 2      fn.*mF(81, b, 92, d) = 9175        b = 6000, d = 3002