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