9
3

functional.hpp 20 KB

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