functional.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. // ------------------------------------------------------------------------------
  2. // Copyright (c) 2000 Cadenza New Zealand Ltd
  3. // Distributed under the Boost Software License, Version 1.0. (See accompany-
  4. // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. // ------------------------------------------------------------------------------
  6. // Boost functional.hpp header file
  7. // See http://www.boost.org/libs/functional for documentation.
  8. // ------------------------------------------------------------------------------
  9. // $Id$
  10. // ------------------------------------------------------------------------------
  11. #ifndef BOOST_FUNCTIONAL_HPP
  12. #define BOOST_FUNCTIONAL_HPP
  13. #include <boost/config.hpp>
  14. #include <boost/call_traits.hpp>
  15. #include <functional>
  16. namespace boost
  17. {
  18. namespace functional
  19. {
  20. namespace detail {
  21. // std::unary_function and std::binary_function were both removed
  22. // in C++17.
  23. template <typename Arg1, typename Result>
  24. struct unary_function
  25. {
  26. typedef Arg1 argument_type;
  27. typedef Result result_type;
  28. };
  29. template <typename Arg1, typename Arg2, typename Result>
  30. struct binary_function
  31. {
  32. typedef Arg1 first_argument_type;
  33. typedef Arg2 second_argument_type;
  34. typedef Result result_type;
  35. };
  36. }
  37. }
  38. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  39. // --------------------------------------------------------------------------
  40. // The following traits classes allow us to avoid the need for ptr_fun
  41. // because the types of arguments and the result of a function can be
  42. // deduced.
  43. //
  44. // In addition to the standard types defined in unary_function and
  45. // binary_function, we add
  46. //
  47. // - function_type, the type of the function or function object itself.
  48. //
  49. // - param_type, the type that should be used for passing the function or
  50. // function object as an argument.
  51. // --------------------------------------------------------------------------
  52. namespace detail
  53. {
  54. template <class Operation>
  55. struct unary_traits_imp;
  56. template <class Operation>
  57. struct unary_traits_imp<Operation*>
  58. {
  59. typedef Operation function_type;
  60. typedef const function_type & param_type;
  61. typedef typename Operation::result_type result_type;
  62. typedef typename Operation::argument_type argument_type;
  63. };
  64. template <class R, class A>
  65. struct unary_traits_imp<R(*)(A)>
  66. {
  67. typedef R (*function_type)(A);
  68. typedef R (*param_type)(A);
  69. typedef R result_type;
  70. typedef A argument_type;
  71. };
  72. template <class Operation>
  73. struct binary_traits_imp;
  74. template <class Operation>
  75. struct binary_traits_imp<Operation*>
  76. {
  77. typedef Operation function_type;
  78. typedef const function_type & param_type;
  79. typedef typename Operation::result_type result_type;
  80. typedef typename Operation::first_argument_type first_argument_type;
  81. typedef typename Operation::second_argument_type second_argument_type;
  82. };
  83. template <class R, class A1, class A2>
  84. struct binary_traits_imp<R(*)(A1,A2)>
  85. {
  86. typedef R (*function_type)(A1,A2);
  87. typedef R (*param_type)(A1,A2);
  88. typedef R result_type;
  89. typedef A1 first_argument_type;
  90. typedef A2 second_argument_type;
  91. };
  92. } // namespace detail
  93. template <class Operation>
  94. struct unary_traits
  95. {
  96. typedef typename detail::unary_traits_imp<Operation*>::function_type function_type;
  97. typedef typename detail::unary_traits_imp<Operation*>::param_type param_type;
  98. typedef typename detail::unary_traits_imp<Operation*>::result_type result_type;
  99. typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type;
  100. };
  101. template <class R, class A>
  102. struct unary_traits<R(*)(A)>
  103. {
  104. typedef R (*function_type)(A);
  105. typedef R (*param_type)(A);
  106. typedef R result_type;
  107. typedef A argument_type;
  108. };
  109. template <class Operation>
  110. struct binary_traits
  111. {
  112. typedef typename detail::binary_traits_imp<Operation*>::function_type function_type;
  113. typedef typename detail::binary_traits_imp<Operation*>::param_type param_type;
  114. typedef typename detail::binary_traits_imp<Operation*>::result_type result_type;
  115. typedef typename detail::binary_traits_imp<Operation*>::first_argument_type first_argument_type;
  116. typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type;
  117. };
  118. template <class R, class A1, class A2>
  119. struct binary_traits<R(*)(A1,A2)>
  120. {
  121. typedef R (*function_type)(A1,A2);
  122. typedef R (*param_type)(A1,A2);
  123. typedef R result_type;
  124. typedef A1 first_argument_type;
  125. typedef A2 second_argument_type;
  126. };
  127. #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  128. // --------------------------------------------------------------------------
  129. // If we have no partial specialisation available, decay to a situation
  130. // that is no worse than in the Standard, i.e., ptr_fun will be required.
  131. // --------------------------------------------------------------------------
  132. template <class Operation>
  133. struct unary_traits
  134. {
  135. typedef Operation function_type;
  136. typedef const Operation& param_type;
  137. typedef typename Operation::result_type result_type;
  138. typedef typename Operation::argument_type argument_type;
  139. };
  140. template <class Operation>
  141. struct binary_traits
  142. {
  143. typedef Operation function_type;
  144. typedef const Operation & param_type;
  145. typedef typename Operation::result_type result_type;
  146. typedef typename Operation::first_argument_type first_argument_type;
  147. typedef typename Operation::second_argument_type second_argument_type;
  148. };
  149. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  150. // --------------------------------------------------------------------------
  151. // unary_negate, not1
  152. // --------------------------------------------------------------------------
  153. template <class Predicate>
  154. class unary_negate
  155. : public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool>
  156. {
  157. public:
  158. explicit unary_negate(typename unary_traits<Predicate>::param_type x)
  159. :
  160. pred(x)
  161. {}
  162. bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const
  163. {
  164. return !pred(x);
  165. }
  166. private:
  167. typename unary_traits<Predicate>::function_type pred;
  168. };
  169. template <class Predicate>
  170. unary_negate<Predicate> not1(const Predicate &pred)
  171. {
  172. // The cast is to placate Borland C++Builder in certain circumstances.
  173. // I don't think it should be necessary.
  174. return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred);
  175. }
  176. template <class Predicate>
  177. unary_negate<Predicate> not1(Predicate &pred)
  178. {
  179. return unary_negate<Predicate>(pred);
  180. }
  181. // --------------------------------------------------------------------------
  182. // binary_negate, not2
  183. // --------------------------------------------------------------------------
  184. template <class Predicate>
  185. class binary_negate
  186. : public boost::functional::detail::binary_function<
  187. typename binary_traits<Predicate>::first_argument_type,
  188. typename binary_traits<Predicate>::second_argument_type,
  189. bool>
  190. {
  191. public:
  192. explicit binary_negate(typename binary_traits<Predicate>::param_type x)
  193. :
  194. pred(x)
  195. {}
  196. bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x,
  197. typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const
  198. {
  199. return !pred(x,y);
  200. }
  201. private:
  202. typename binary_traits<Predicate>::function_type pred;
  203. };
  204. template <class Predicate>
  205. binary_negate<Predicate> not2(const Predicate &pred)
  206. {
  207. // The cast is to placate Borland C++Builder in certain circumstances.
  208. // I don't think it should be necessary.
  209. return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred);
  210. }
  211. template <class Predicate>
  212. binary_negate<Predicate> not2(Predicate &pred)
  213. {
  214. return binary_negate<Predicate>(pred);
  215. }
  216. // --------------------------------------------------------------------------
  217. // binder1st, bind1st
  218. // --------------------------------------------------------------------------
  219. template <class Operation>
  220. class binder1st
  221. : public boost::functional::detail::unary_function<
  222. typename binary_traits<Operation>::second_argument_type,
  223. typename binary_traits<Operation>::result_type>
  224. {
  225. public:
  226. binder1st(typename binary_traits<Operation>::param_type x,
  227. typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)
  228. :
  229. op(x), value(y)
  230. {}
  231. typename binary_traits<Operation>::result_type
  232. operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const
  233. {
  234. return op(value, x);
  235. }
  236. protected:
  237. typename binary_traits<Operation>::function_type op;
  238. typename binary_traits<Operation>::first_argument_type value;
  239. };
  240. template <class Operation>
  241. inline binder1st<Operation> bind1st(const Operation &op,
  242. typename call_traits<
  243. typename binary_traits<Operation>::first_argument_type
  244. >::param_type x)
  245. {
  246. // The cast is to placate Borland C++Builder in certain circumstances.
  247. // I don't think it should be necessary.
  248. return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x);
  249. }
  250. template <class Operation>
  251. inline binder1st<Operation> bind1st(Operation &op,
  252. typename call_traits<
  253. typename binary_traits<Operation>::first_argument_type
  254. >::param_type x)
  255. {
  256. return binder1st<Operation>(op, x);
  257. }
  258. // --------------------------------------------------------------------------
  259. // binder2nd, bind2nd
  260. // --------------------------------------------------------------------------
  261. template <class Operation>
  262. class binder2nd
  263. : public boost::functional::detail::unary_function<
  264. typename binary_traits<Operation>::first_argument_type,
  265. typename binary_traits<Operation>::result_type>
  266. {
  267. public:
  268. binder2nd(typename binary_traits<Operation>::param_type x,
  269. typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)
  270. :
  271. op(x), value(y)
  272. {}
  273. typename binary_traits<Operation>::result_type
  274. operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const
  275. {
  276. return op(x, value);
  277. }
  278. protected:
  279. typename binary_traits<Operation>::function_type op;
  280. typename binary_traits<Operation>::second_argument_type value;
  281. };
  282. template <class Operation>
  283. inline binder2nd<Operation> bind2nd(const Operation &op,
  284. typename call_traits<
  285. typename binary_traits<Operation>::second_argument_type
  286. >::param_type x)
  287. {
  288. // The cast is to placate Borland C++Builder in certain circumstances.
  289. // I don't think it should be necessary.
  290. return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x);
  291. }
  292. template <class Operation>
  293. inline binder2nd<Operation> bind2nd(Operation &op,
  294. typename call_traits<
  295. typename binary_traits<Operation>::second_argument_type
  296. >::param_type x)
  297. {
  298. return binder2nd<Operation>(op, x);
  299. }
  300. // --------------------------------------------------------------------------
  301. // mem_fun, etc
  302. // --------------------------------------------------------------------------
  303. template <class S, class T>
  304. class mem_fun_t : public boost::functional::detail::unary_function<T*, S>
  305. {
  306. public:
  307. explicit mem_fun_t(S (T::*p)())
  308. :
  309. ptr(p)
  310. {}
  311. S operator()(T* p) const
  312. {
  313. return (p->*ptr)();
  314. }
  315. private:
  316. S (T::*ptr)();
  317. };
  318. template <class S, class T, class A>
  319. class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S>
  320. {
  321. public:
  322. explicit mem_fun1_t(S (T::*p)(A))
  323. :
  324. ptr(p)
  325. {}
  326. S operator()(T* p, typename call_traits<A>::param_type x) const
  327. {
  328. return (p->*ptr)(x);
  329. }
  330. private:
  331. S (T::*ptr)(A);
  332. };
  333. template <class S, class T>
  334. class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S>
  335. {
  336. public:
  337. explicit const_mem_fun_t(S (T::*p)() const)
  338. :
  339. ptr(p)
  340. {}
  341. S operator()(const T* p) const
  342. {
  343. return (p->*ptr)();
  344. }
  345. private:
  346. S (T::*ptr)() const;
  347. };
  348. template <class S, class T, class A>
  349. class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S>
  350. {
  351. public:
  352. explicit const_mem_fun1_t(S (T::*p)(A) const)
  353. :
  354. ptr(p)
  355. {}
  356. S operator()(const T* p, typename call_traits<A>::param_type x) const
  357. {
  358. return (p->*ptr)(x);
  359. }
  360. private:
  361. S (T::*ptr)(A) const;
  362. };
  363. template<class S, class T>
  364. inline mem_fun_t<S,T> mem_fun(S (T::*f)())
  365. {
  366. return mem_fun_t<S,T>(f);
  367. }
  368. template<class S, class T, class A>
  369. inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A))
  370. {
  371. return mem_fun1_t<S,T,A>(f);
  372. }
  373. #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
  374. template<class S, class T>
  375. inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const)
  376. {
  377. return const_mem_fun_t<S,T>(f);
  378. }
  379. template<class S, class T, class A>
  380. inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const)
  381. {
  382. return const_mem_fun1_t<S,T,A>(f);
  383. }
  384. #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
  385. // --------------------------------------------------------------------------
  386. // mem_fun_ref, etc
  387. // --------------------------------------------------------------------------
  388. template <class S, class T>
  389. class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S>
  390. {
  391. public:
  392. explicit mem_fun_ref_t(S (T::*p)())
  393. :
  394. ptr(p)
  395. {}
  396. S operator()(T& p) const
  397. {
  398. return (p.*ptr)();
  399. }
  400. private:
  401. S (T::*ptr)();
  402. };
  403. template <class S, class T, class A>
  404. class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S>
  405. {
  406. public:
  407. explicit mem_fun1_ref_t(S (T::*p)(A))
  408. :
  409. ptr(p)
  410. {}
  411. S operator()(T& p, typename call_traits<A>::param_type x) const
  412. {
  413. return (p.*ptr)(x);
  414. }
  415. private:
  416. S (T::*ptr)(A);
  417. };
  418. template <class S, class T>
  419. class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S>
  420. {
  421. public:
  422. explicit const_mem_fun_ref_t(S (T::*p)() const)
  423. :
  424. ptr(p)
  425. {}
  426. S operator()(const T &p) const
  427. {
  428. return (p.*ptr)();
  429. }
  430. private:
  431. S (T::*ptr)() const;
  432. };
  433. template <class S, class T, class A>
  434. class const_mem_fun1_ref_t : public boost::functional::detail::binary_function<const T&, A, S>
  435. {
  436. public:
  437. explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
  438. :
  439. ptr(p)
  440. {}
  441. S operator()(const T& p, typename call_traits<A>::param_type x) const
  442. {
  443. return (p.*ptr)(x);
  444. }
  445. private:
  446. S (T::*ptr)(A) const;
  447. };
  448. template<class S, class T>
  449. inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)())
  450. {
  451. return mem_fun_ref_t<S,T>(f);
  452. }
  453. template<class S, class T, class A>
  454. inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A))
  455. {
  456. return mem_fun1_ref_t<S,T,A>(f);
  457. }
  458. #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
  459. template<class S, class T>
  460. inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const)
  461. {
  462. return const_mem_fun_ref_t<S,T>(f);
  463. }
  464. template<class S, class T, class A>
  465. inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const)
  466. {
  467. return const_mem_fun1_ref_t<S,T,A>(f);
  468. }
  469. #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
  470. // --------------------------------------------------------------------------
  471. // ptr_fun
  472. // --------------------------------------------------------------------------
  473. template <class Arg, class Result>
  474. class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result>
  475. {
  476. public:
  477. explicit pointer_to_unary_function(Result (*f)(Arg))
  478. :
  479. func(f)
  480. {}
  481. Result operator()(typename call_traits<Arg>::param_type x) const
  482. {
  483. return func(x);
  484. }
  485. private:
  486. Result (*func)(Arg);
  487. };
  488. template <class Arg, class Result>
  489. inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg))
  490. {
  491. return pointer_to_unary_function<Arg,Result>(f);
  492. }
  493. template <class Arg1, class Arg2, class Result>
  494. class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result>
  495. {
  496. public:
  497. explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
  498. :
  499. func(f)
  500. {}
  501. Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const
  502. {
  503. return func(x,y);
  504. }
  505. private:
  506. Result (*func)(Arg1, Arg2);
  507. };
  508. template <class Arg1, class Arg2, class Result>
  509. inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2))
  510. {
  511. return pointer_to_binary_function<Arg1,Arg2,Result>(f);
  512. }
  513. } // namespace boost
  514. #endif