You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

423 lines
14KB

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