functional 14 KB

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