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