functional 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. // Functional extensions -*- C++ -*-
  2. // Copyright (C) 2002-2022 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. #pragma GCC diagnostic push
  57. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  58. /** The @c identity_element functions are not part of the C++
  59. * standard; SGI provided them as an extension. Its argument is an
  60. * operation, and its return value is the identity element for that
  61. * operation. It is overloaded for addition and multiplication,
  62. * and you can overload it for your own nefarious operations.
  63. *
  64. * @addtogroup SGIextensions
  65. * @{
  66. */
  67. /// An \link SGIextensions SGI extension \endlink.
  68. template <class _Tp>
  69. inline _Tp
  70. identity_element(std::plus<_Tp>)
  71. { return _Tp(0); }
  72. /// An \link SGIextensions SGI extension \endlink.
  73. template <class _Tp>
  74. inline _Tp
  75. identity_element(std::multiplies<_Tp>)
  76. { return _Tp(1); }
  77. /** @} */
  78. /** As an extension to the binders, SGI provided composition functors and
  79. * wrapper functions to aid in their creation. The @c unary_compose
  80. * functor is constructed from two functions/functors, @c f and @c g.
  81. * Calling @c operator() with a single argument @c x returns @c f(g(x)).
  82. * The function @c compose1 takes the two functions and constructs a
  83. * @c unary_compose variable for you.
  84. *
  85. * @c binary_compose is constructed from three functors, @c f, @c g1,
  86. * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function
  87. * compose2 takes f, g1, and g2, and constructs the @c binary_compose
  88. * instance for you. For example, if @c f returns an int, then
  89. * \code
  90. * int answer = (compose2(f,g1,g2))(x);
  91. * \endcode
  92. * is equivalent to
  93. * \code
  94. * int temp1 = g1(x);
  95. * int temp2 = g2(x);
  96. * int answer = f(temp1,temp2);
  97. * \endcode
  98. * But the first form is more compact, and can be passed around as a
  99. * functor to other algorithms.
  100. *
  101. * @addtogroup SGIextensions
  102. * @{
  103. */
  104. /// An \link SGIextensions SGI extension \endlink.
  105. template <class _Operation1, class _Operation2>
  106. class unary_compose
  107. : public std::unary_function<typename _Operation2::argument_type,
  108. typename _Operation1::result_type>
  109. {
  110. protected:
  111. _Operation1 _M_fn1;
  112. _Operation2 _M_fn2;
  113. public:
  114. unary_compose(const _Operation1& __x, const _Operation2& __y)
  115. : _M_fn1(__x), _M_fn2(__y) {}
  116. typename _Operation1::result_type
  117. operator()(const typename _Operation2::argument_type& __x) const
  118. { return _M_fn1(_M_fn2(__x)); }
  119. };
  120. /// An \link SGIextensions SGI extension \endlink.
  121. template <class _Operation1, class _Operation2>
  122. inline unary_compose<_Operation1, _Operation2>
  123. compose1(const _Operation1& __fn1, const _Operation2& __fn2)
  124. { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); }
  125. /// An \link SGIextensions SGI extension \endlink.
  126. template <class _Operation1, class _Operation2, class _Operation3>
  127. class binary_compose
  128. : public std::unary_function<typename _Operation2::argument_type,
  129. typename _Operation1::result_type>
  130. {
  131. protected:
  132. _Operation1 _M_fn1;
  133. _Operation2 _M_fn2;
  134. _Operation3 _M_fn3;
  135. public:
  136. binary_compose(const _Operation1& __x, const _Operation2& __y,
  137. const _Operation3& __z)
  138. : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { }
  139. typename _Operation1::result_type
  140. operator()(const typename _Operation2::argument_type& __x) const
  141. { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); }
  142. };
  143. /// An \link SGIextensions SGI extension \endlink.
  144. template <class _Operation1, class _Operation2, class _Operation3>
  145. inline binary_compose<_Operation1, _Operation2, _Operation3>
  146. compose2(const _Operation1& __fn1, const _Operation2& __fn2,
  147. const _Operation3& __fn3)
  148. { return binary_compose<_Operation1, _Operation2, _Operation3>
  149. (__fn1, __fn2, __fn3); }
  150. /** @} */
  151. /** As an extension, SGI provided a functor called @c identity. When a
  152. * functor is required but no operations are desired, this can be used as a
  153. * pass-through. Its @c operator() returns its argument unchanged.
  154. *
  155. * @addtogroup SGIextensions
  156. */
  157. template <class _Tp>
  158. struct identity
  159. : public std::_Identity<_Tp> {};
  160. /** @c select1st and @c select2nd are extensions provided by SGI. Their
  161. * @c operator()s
  162. * take a @c std::pair as an argument, and return either the first member
  163. * or the second member, respectively. They can be used (especially with
  164. * the composition functors) to @a strip data from a sequence before
  165. * performing the remainder of an algorithm.
  166. *
  167. * @addtogroup SGIextensions
  168. * @{
  169. */
  170. /// An \link SGIextensions SGI extension \endlink.
  171. template <class _Pair>
  172. struct select1st
  173. : public std::_Select1st<_Pair> {};
  174. /// An \link SGIextensions SGI extension \endlink.
  175. template <class _Pair>
  176. struct select2nd
  177. : public std::_Select2nd<_Pair> {};
  178. /** @} */
  179. // extension documented next
  180. template <class _Arg1, class _Arg2>
  181. struct _Project1st : public std::binary_function<_Arg1, _Arg2, _Arg1>
  182. {
  183. _Arg1
  184. operator()(const _Arg1& __x, const _Arg2&) const
  185. { return __x; }
  186. };
  187. template <class _Arg1, class _Arg2>
  188. struct _Project2nd : public std::binary_function<_Arg1, _Arg2, _Arg2>
  189. {
  190. _Arg2
  191. operator()(const _Arg1&, const _Arg2& __y) const
  192. { return __y; }
  193. };
  194. /** The @c operator() of the @c project1st functor takes two arbitrary
  195. * arguments and returns the first one, while @c project2nd returns the
  196. * second one. They are extensions provided by SGI.
  197. *
  198. * @addtogroup SGIextensions
  199. * @{
  200. */
  201. /// An \link SGIextensions SGI extension \endlink.
  202. template <class _Arg1, class _Arg2>
  203. struct project1st : public _Project1st<_Arg1, _Arg2> {};
  204. /// An \link SGIextensions SGI extension \endlink.
  205. template <class _Arg1, class _Arg2>
  206. struct project2nd : public _Project2nd<_Arg1, _Arg2> {};
  207. /** @} */
  208. // extension documented next
  209. template <class _Result>
  210. struct _Constant_void_fun
  211. {
  212. typedef _Result result_type;
  213. result_type _M_val;
  214. _Constant_void_fun(const result_type& __v) : _M_val(__v) {}
  215. const result_type&
  216. operator()() const
  217. { return _M_val; }
  218. };
  219. template <class _Result, class _Argument>
  220. struct _Constant_unary_fun
  221. {
  222. typedef _Argument argument_type;
  223. typedef _Result result_type;
  224. result_type _M_val;
  225. _Constant_unary_fun(const result_type& __v) : _M_val(__v) {}
  226. const result_type&
  227. operator()(const _Argument&) const
  228. { return _M_val; }
  229. };
  230. template <class _Result, class _Arg1, class _Arg2>
  231. struct _Constant_binary_fun
  232. {
  233. typedef _Arg1 first_argument_type;
  234. typedef _Arg2 second_argument_type;
  235. typedef _Result result_type;
  236. _Result _M_val;
  237. _Constant_binary_fun(const _Result& __v) : _M_val(__v) {}
  238. const result_type&
  239. operator()(const _Arg1&, const _Arg2&) const
  240. { return _M_val; }
  241. };
  242. /** These three functors are each constructed from a single arbitrary
  243. * variable/value. Later, their @c operator()s completely ignore any
  244. * arguments passed, and return the stored value.
  245. * - @c constant_void_fun's @c operator() takes no arguments
  246. * - @c constant_unary_fun's @c operator() takes one argument (ignored)
  247. * - @c constant_binary_fun's @c operator() takes two arguments (ignored)
  248. *
  249. * The helper creator functions @c constant0, @c constant1, and
  250. * @c constant2 each take a @a result argument and construct variables of
  251. * the appropriate functor type.
  252. *
  253. * @addtogroup SGIextensions
  254. * @{
  255. */
  256. /// An \link SGIextensions SGI extension \endlink.
  257. template <class _Result>
  258. struct constant_void_fun
  259. : public _Constant_void_fun<_Result>
  260. {
  261. constant_void_fun(const _Result& __v)
  262. : _Constant_void_fun<_Result>(__v) {}
  263. };
  264. /// An \link SGIextensions SGI extension \endlink.
  265. template <class _Result, class _Argument = _Result>
  266. struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument>
  267. {
  268. constant_unary_fun(const _Result& __v)
  269. : _Constant_unary_fun<_Result, _Argument>(__v) {}
  270. };
  271. /// An \link SGIextensions SGI extension \endlink.
  272. template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1>
  273. struct constant_binary_fun
  274. : public _Constant_binary_fun<_Result, _Arg1, _Arg2>
  275. {
  276. constant_binary_fun(const _Result& __v)
  277. : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {}
  278. };
  279. /// An \link SGIextensions SGI extension \endlink.
  280. template <class _Result>
  281. inline constant_void_fun<_Result>
  282. constant0(const _Result& __val)
  283. { return constant_void_fun<_Result>(__val); }
  284. /// An \link SGIextensions SGI extension \endlink.
  285. template <class _Result>
  286. inline constant_unary_fun<_Result, _Result>
  287. constant1(const _Result& __val)
  288. { return constant_unary_fun<_Result, _Result>(__val); }
  289. /// An \link SGIextensions SGI extension \endlink.
  290. template <class _Result>
  291. inline constant_binary_fun<_Result,_Result,_Result>
  292. constant2(const _Result& __val)
  293. { return constant_binary_fun<_Result, _Result, _Result>(__val); }
  294. /** @} */
  295. /** The @c subtractive_rng class is documented on
  296. * <a href="http://www.sgi.com/tech/stl/">SGI's site</a>.
  297. * Note that this code assumes that @c int is 32 bits.
  298. *
  299. * @ingroup SGIextensions
  300. */
  301. class subtractive_rng
  302. : public std::unary_function<unsigned int, unsigned int>
  303. {
  304. private:
  305. unsigned int _M_table[55];
  306. std::size_t _M_index1;
  307. std::size_t _M_index2;
  308. public:
  309. /// Returns a number less than the argument.
  310. unsigned int
  311. operator()(unsigned int __limit)
  312. {
  313. _M_index1 = (_M_index1 + 1) % 55;
  314. _M_index2 = (_M_index2 + 1) % 55;
  315. _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2];
  316. return _M_table[_M_index1] % __limit;
  317. }
  318. void
  319. _M_initialize(unsigned int __seed)
  320. {
  321. unsigned int __k = 1;
  322. _M_table[54] = __seed;
  323. std::size_t __i;
  324. for (__i = 0; __i < 54; __i++)
  325. {
  326. std::size_t __ii = (21 * (__i + 1) % 55) - 1;
  327. _M_table[__ii] = __k;
  328. __k = __seed - __k;
  329. __seed = _M_table[__ii];
  330. }
  331. for (int __loop = 0; __loop < 4; __loop++)
  332. {
  333. for (__i = 0; __i < 55; __i++)
  334. _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];
  335. }
  336. _M_index1 = 0;
  337. _M_index2 = 31;
  338. }
  339. /// Ctor allowing you to initialize the seed.
  340. subtractive_rng(unsigned int __seed)
  341. { _M_initialize(__seed); }
  342. /// Default ctor; initializes its state with some number you don't see.
  343. subtractive_rng()
  344. { _M_initialize(161803398u); }
  345. };
  346. #pragma GCC diagnostic pop
  347. // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref,
  348. // provided for backward compatibility, they are no longer part of
  349. // the C++ standard.
  350. template <class _Ret, class _Tp, class _Arg>
  351. inline std::mem_fun1_t<_Ret, _Tp, _Arg>
  352. mem_fun1(_Ret (_Tp::*__f)(_Arg))
  353. { return std::mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
  354. template <class _Ret, class _Tp, class _Arg>
  355. inline std::const_mem_fun1_t<_Ret, _Tp, _Arg>
  356. mem_fun1(_Ret (_Tp::*__f)(_Arg) const)
  357. { return std::const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
  358. template <class _Ret, class _Tp, class _Arg>
  359. inline std::mem_fun1_ref_t<_Ret, _Tp, _Arg>
  360. mem_fun1_ref(_Ret (_Tp::*__f)(_Arg))
  361. { return std::mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
  362. template <class _Ret, class _Tp, class _Arg>
  363. inline std::const_mem_fun1_ref_t<_Ret, _Tp, _Arg>
  364. mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const)
  365. { return std::const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
  366. _GLIBCXX_END_NAMESPACE_VERSION
  367. } // namespace
  368. #endif