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