functional 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. // Functional extensions -*- C++ -*-
  2. // Copyright (C) 2002-2015 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /*
  21. *
  22. * Copyright (c) 1994
  23. * Hewlett-Packard Company
  24. *
  25. * Permission to use, copy, modify, distribute and sell this software
  26. * and its documentation for any purpose is hereby granted without fee,
  27. * provided that the above copyright notice appear in all copies and
  28. * that both that copyright notice and this permission notice appear
  29. * in supporting documentation. Hewlett-Packard Company makes no
  30. * representations about the suitability of this software for any
  31. * purpose. It is provided "as is" without express or implied warranty.
  32. *
  33. *
  34. * Copyright (c) 1996
  35. * Silicon Graphics Computer Systems, Inc.
  36. *
  37. * Permission to use, copy, modify, distribute and sell this software
  38. * and its documentation for any purpose is hereby granted without fee,
  39. * provided that the above copyright notice appear in all copies and
  40. * that both that copyright notice and this permission notice appear
  41. * in supporting documentation. Silicon Graphics makes no
  42. * representations about the suitability of this software for any
  43. * purpose. It is provided "as is" without express or implied warranty.
  44. */
  45. /** @file ext/functional
  46. * This file is a GNU extension to the Standard C++ Library (possibly
  47. * containing extensions from the HP/SGI STL subset).
  48. */
  49. #ifndef _EXT_FUNCTIONAL
  50. #define _EXT_FUNCTIONAL 1
  51. #pragma GCC system_header
  52. #include <functional>
  53. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  54. {
  55. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  56. using std::size_t;
  57. using std::unary_function;
  58. using std::binary_function;
  59. using std::mem_fun1_t;
  60. using std::const_mem_fun1_t;
  61. using std::mem_fun1_ref_t;
  62. using std::const_mem_fun1_ref_t;
  63. /** The @c identity_element functions are not part of the C++
  64. * standard; SGI provided them as an extension. Its argument is an
  65. * operation, and its return value is the identity element for that
  66. * operation. It is overloaded for addition and multiplication,
  67. * and you can overload it for your own nefarious operations.
  68. *
  69. * @addtogroup SGIextensions
  70. * @{
  71. */
  72. /// An \link SGIextensions SGI extension \endlink.
  73. template <class _Tp>
  74. inline _Tp
  75. identity_element(std::plus<_Tp>)
  76. { return _Tp(0); }
  77. /// An \link SGIextensions SGI extension \endlink.
  78. template <class _Tp>
  79. inline _Tp
  80. identity_element(std::multiplies<_Tp>)
  81. { return _Tp(1); }
  82. /** @} */
  83. /** As an extension to the binders, SGI provided composition functors and
  84. * wrapper functions to aid in their creation. The @c unary_compose
  85. * functor is constructed from two functions/functors, @c f and @c g.
  86. * Calling @c operator() with a single argument @c x returns @c f(g(x)).
  87. * The function @c compose1 takes the two functions and constructs a
  88. * @c unary_compose variable for you.
  89. *
  90. * @c binary_compose is constructed from three functors, @c f, @c g1,
  91. * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function
  92. * compose2 takes f, g1, and g2, and constructs the @c binary_compose
  93. * instance for you. For example, if @c f returns an int, then
  94. * \code
  95. * int answer = (compose2(f,g1,g2))(x);
  96. * \endcode
  97. * is equivalent to
  98. * \code
  99. * int temp1 = g1(x);
  100. * int temp2 = g2(x);
  101. * int answer = f(temp1,temp2);
  102. * \endcode
  103. * But the first form is more compact, and can be passed around as a
  104. * functor to other algorithms.
  105. *
  106. * @addtogroup SGIextensions
  107. * @{
  108. */
  109. /// An \link SGIextensions SGI extension \endlink.
  110. template <class _Operation1, class _Operation2>
  111. class unary_compose
  112. : public unary_function<typename _Operation2::argument_type,
  113. typename _Operation1::result_type>
  114. {
  115. protected:
  116. _Operation1 _M_fn1;
  117. _Operation2 _M_fn2;
  118. public:
  119. unary_compose(const _Operation1& __x, const _Operation2& __y)
  120. : _M_fn1(__x), _M_fn2(__y) {}
  121. typename _Operation1::result_type
  122. operator()(const typename _Operation2::argument_type& __x) const
  123. { return _M_fn1(_M_fn2(__x)); }
  124. };
  125. /// An \link SGIextensions SGI extension \endlink.
  126. template <class _Operation1, class _Operation2>
  127. inline unary_compose<_Operation1, _Operation2>
  128. compose1(const _Operation1& __fn1, const _Operation2& __fn2)
  129. { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); }
  130. /// An \link SGIextensions SGI extension \endlink.
  131. template <class _Operation1, class _Operation2, class _Operation3>
  132. class binary_compose
  133. : public unary_function<typename _Operation2::argument_type,
  134. typename _Operation1::result_type>
  135. {
  136. protected:
  137. _Operation1 _M_fn1;
  138. _Operation2 _M_fn2;
  139. _Operation3 _M_fn3;
  140. public:
  141. binary_compose(const _Operation1& __x, const _Operation2& __y,
  142. const _Operation3& __z)
  143. : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { }
  144. typename _Operation1::result_type
  145. operator()(const typename _Operation2::argument_type& __x) const
  146. { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); }
  147. };
  148. /// An \link SGIextensions SGI extension \endlink.
  149. template <class _Operation1, class _Operation2, class _Operation3>
  150. inline binary_compose<_Operation1, _Operation2, _Operation3>
  151. compose2(const _Operation1& __fn1, const _Operation2& __fn2,
  152. const _Operation3& __fn3)
  153. { return binary_compose<_Operation1, _Operation2, _Operation3>
  154. (__fn1, __fn2, __fn3); }
  155. /** @} */
  156. /** As an extension, SGI provided a functor called @c identity. When a
  157. * functor is required but no operations are desired, this can be used as a
  158. * pass-through. Its @c operator() returns its argument unchanged.
  159. *
  160. * @addtogroup SGIextensions
  161. */
  162. template <class _Tp>
  163. struct identity
  164. : public std::_Identity<_Tp> {};
  165. /** @c select1st and @c select2nd are extensions provided by SGI. Their
  166. * @c operator()s
  167. * take a @c std::pair as an argument, and return either the first member
  168. * or the second member, respectively. They can be used (especially with
  169. * the composition functors) to @a strip data from a sequence before
  170. * performing the remainder of an algorithm.
  171. *
  172. * @addtogroup SGIextensions
  173. * @{
  174. */
  175. /// An \link SGIextensions SGI extension \endlink.
  176. template <class _Pair>
  177. struct select1st
  178. : public std::_Select1st<_Pair> {};
  179. /// An \link SGIextensions SGI extension \endlink.
  180. template <class _Pair>
  181. struct select2nd
  182. : public std::_Select2nd<_Pair> {};
  183. /** @} */
  184. // extension documented next
  185. template <class _Arg1, class _Arg2>
  186. struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1>
  187. {
  188. _Arg1
  189. operator()(const _Arg1& __x, const _Arg2&) const
  190. { return __x; }
  191. };
  192. template <class _Arg1, class _Arg2>
  193. struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2>
  194. {
  195. _Arg2
  196. operator()(const _Arg1&, const _Arg2& __y) const
  197. { return __y; }
  198. };
  199. /** The @c operator() of the @c project1st functor takes two arbitrary
  200. * arguments and returns the first one, while @c project2nd returns the
  201. * second one. They are extensions provided by SGI.
  202. *
  203. * @addtogroup SGIextensions
  204. * @{
  205. */
  206. /// An \link SGIextensions SGI extension \endlink.
  207. template <class _Arg1, class _Arg2>
  208. struct project1st : public _Project1st<_Arg1, _Arg2> {};
  209. /// An \link SGIextensions SGI extension \endlink.
  210. template <class _Arg1, class _Arg2>
  211. struct project2nd : public _Project2nd<_Arg1, _Arg2> {};
  212. /** @} */
  213. // extension documented next
  214. template <class _Result>
  215. struct _Constant_void_fun
  216. {
  217. typedef _Result result_type;
  218. result_type _M_val;
  219. _Constant_void_fun(const result_type& __v) : _M_val(__v) {}
  220. const result_type&
  221. operator()() const
  222. { return _M_val; }
  223. };
  224. template <class _Result, class _Argument>
  225. struct _Constant_unary_fun
  226. {
  227. typedef _Argument argument_type;
  228. typedef _Result result_type;
  229. result_type _M_val;
  230. _Constant_unary_fun(const result_type& __v) : _M_val(__v) {}
  231. const result_type&
  232. operator()(const _Argument&) const
  233. { return _M_val; }
  234. };
  235. template <class _Result, class _Arg1, class _Arg2>
  236. struct _Constant_binary_fun
  237. {
  238. typedef _Arg1 first_argument_type;
  239. typedef _Arg2 second_argument_type;
  240. typedef _Result result_type;
  241. _Result _M_val;
  242. _Constant_binary_fun(const _Result& __v) : _M_val(__v) {}
  243. const result_type&
  244. operator()(const _Arg1&, const _Arg2&) const
  245. { return _M_val; }
  246. };
  247. /** These three functors are each constructed from a single arbitrary
  248. * variable/value. Later, their @c operator()s completely ignore any
  249. * arguments passed, and return the stored value.
  250. * - @c constant_void_fun's @c operator() takes no arguments
  251. * - @c constant_unary_fun's @c operator() takes one argument (ignored)
  252. * - @c constant_binary_fun's @c operator() takes two arguments (ignored)
  253. *
  254. * The helper creator functions @c constant0, @c constant1, and
  255. * @c constant2 each take a @a result argument and construct variables of
  256. * the appropriate functor type.
  257. *
  258. * @addtogroup SGIextensions
  259. * @{
  260. */
  261. /// An \link SGIextensions SGI extension \endlink.
  262. template <class _Result>
  263. struct constant_void_fun
  264. : public _Constant_void_fun<_Result>
  265. {
  266. constant_void_fun(const _Result& __v)
  267. : _Constant_void_fun<_Result>(__v) {}
  268. };
  269. /// An \link SGIextensions SGI extension \endlink.
  270. template <class _Result, class _Argument = _Result>
  271. struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument>
  272. {
  273. constant_unary_fun(const _Result& __v)
  274. : _Constant_unary_fun<_Result, _Argument>(__v) {}
  275. };
  276. /// An \link SGIextensions SGI extension \endlink.
  277. template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1>
  278. struct constant_binary_fun
  279. : public _Constant_binary_fun<_Result, _Arg1, _Arg2>
  280. {
  281. constant_binary_fun(const _Result& __v)
  282. : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {}
  283. };
  284. /// An \link SGIextensions SGI extension \endlink.
  285. template <class _Result>
  286. inline constant_void_fun<_Result>
  287. constant0(const _Result& __val)
  288. { return constant_void_fun<_Result>(__val); }
  289. /// An \link SGIextensions SGI extension \endlink.
  290. template <class _Result>
  291. inline constant_unary_fun<_Result, _Result>
  292. constant1(const _Result& __val)
  293. { return constant_unary_fun<_Result, _Result>(__val); }
  294. /// An \link SGIextensions SGI extension \endlink.
  295. template <class _Result>
  296. inline constant_binary_fun<_Result,_Result,_Result>
  297. constant2(const _Result& __val)
  298. { return constant_binary_fun<_Result, _Result, _Result>(__val); }
  299. /** @} */
  300. /** The @c subtractive_rng class is documented on
  301. * <a href="http://www.sgi.com/tech/stl/">SGI's site</a>.
  302. * Note that this code assumes that @c int is 32 bits.
  303. *
  304. * @ingroup SGIextensions
  305. */
  306. class subtractive_rng
  307. : public unary_function<unsigned int, unsigned int>
  308. {
  309. private:
  310. unsigned int _M_table[55];
  311. size_t _M_index1;
  312. size_t _M_index2;
  313. public:
  314. /// Returns a number less than the argument.
  315. unsigned int
  316. operator()(unsigned int __limit)
  317. {
  318. _M_index1 = (_M_index1 + 1) % 55;
  319. _M_index2 = (_M_index2 + 1) % 55;
  320. _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2];
  321. return _M_table[_M_index1] % __limit;
  322. }
  323. void
  324. _M_initialize(unsigned int __seed)
  325. {
  326. unsigned int __k = 1;
  327. _M_table[54] = __seed;
  328. size_t __i;
  329. for (__i = 0; __i < 54; __i++)
  330. {
  331. size_t __ii = (21 * (__i + 1) % 55) - 1;
  332. _M_table[__ii] = __k;
  333. __k = __seed - __k;
  334. __seed = _M_table[__ii];
  335. }
  336. for (int __loop = 0; __loop < 4; __loop++)
  337. {
  338. for (__i = 0; __i < 55; __i++)
  339. _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];
  340. }
  341. _M_index1 = 0;
  342. _M_index2 = 31;
  343. }
  344. /// Ctor allowing you to initialize the seed.
  345. subtractive_rng(unsigned int __seed)
  346. { _M_initialize(__seed); }
  347. /// Default ctor; initializes its state with some number you don't see.
  348. subtractive_rng()
  349. { _M_initialize(161803398u); }
  350. };
  351. // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref,
  352. // provided for backward compatibility, they are no longer part of
  353. // the C++ standard.
  354. template <class _Ret, class _Tp, class _Arg>
  355. inline mem_fun1_t<_Ret, _Tp, _Arg>
  356. mem_fun1(_Ret (_Tp::*__f)(_Arg))
  357. { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
  358. template <class _Ret, class _Tp, class _Arg>
  359. inline const_mem_fun1_t<_Ret, _Tp, _Arg>
  360. mem_fun1(_Ret (_Tp::*__f)(_Arg) const)
  361. { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
  362. template <class _Ret, class _Tp, class _Arg>
  363. inline mem_fun1_ref_t<_Ret, _Tp, _Arg>
  364. mem_fun1_ref(_Ret (_Tp::*__f)(_Arg))
  365. { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
  366. template <class _Ret, class _Tp, class _Arg>
  367. inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg>
  368. mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const)
  369. { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
  370. _GLIBCXX_END_NAMESPACE_VERSION
  371. } // namespace
  372. #endif