functional.hpp 18 KB

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