100db7afdSDavid E. O'Brien// Functional extensions -*- C++ -*-
200db7afdSDavid E. O'Brien
3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
400db7afdSDavid E. O'Brien//
500db7afdSDavid E. O'Brien// This file is part of the GNU ISO C++ Library.  This library is free
600db7afdSDavid E. O'Brien// software; you can redistribute it and/or modify it under the
700db7afdSDavid E. O'Brien// terms of the GNU General Public License as published by the
800db7afdSDavid E. O'Brien// Free Software Foundation; either version 2, or (at your option)
900db7afdSDavid E. O'Brien// any later version.
1000db7afdSDavid E. O'Brien
1100db7afdSDavid E. O'Brien// This library is distributed in the hope that it will be useful,
1200db7afdSDavid E. O'Brien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1300db7afdSDavid E. O'Brien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1400db7afdSDavid E. O'Brien// GNU General Public License for more details.
1500db7afdSDavid E. O'Brien
1600db7afdSDavid E. O'Brien// You should have received a copy of the GNU General Public License along
1700db7afdSDavid E. O'Brien// with this library; see the file COPYING.  If not, write to the Free
18*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1900db7afdSDavid E. O'Brien// USA.
2000db7afdSDavid E. O'Brien
2100db7afdSDavid E. O'Brien// As a special exception, you may use this file as part of a free software
2200db7afdSDavid E. O'Brien// library without restriction.  Specifically, if other files instantiate
2300db7afdSDavid E. O'Brien// templates or use macros or inline functions from this file, or you compile
2400db7afdSDavid E. O'Brien// this file and link it with other files to produce an executable, this
2500db7afdSDavid E. O'Brien// file does not by itself cause the resulting executable to be covered by
2600db7afdSDavid E. O'Brien// the GNU General Public License.  This exception does not however
2700db7afdSDavid E. O'Brien// invalidate any other reasons why the executable file might be covered by
2800db7afdSDavid E. O'Brien// the GNU General Public License.
2900db7afdSDavid E. O'Brien
3000db7afdSDavid E. O'Brien/*
3100db7afdSDavid E. O'Brien *
3200db7afdSDavid E. O'Brien * Copyright (c) 1994
3300db7afdSDavid E. O'Brien * Hewlett-Packard Company
3400db7afdSDavid E. O'Brien *
3500db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software
3600db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee,
3700db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and
3800db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear
3900db7afdSDavid E. O'Brien * in supporting documentation.  Hewlett-Packard Company makes no
4000db7afdSDavid E. O'Brien * representations about the suitability of this software for any
4100db7afdSDavid E. O'Brien * purpose.  It is provided "as is" without express or implied warranty.
4200db7afdSDavid E. O'Brien *
4300db7afdSDavid E. O'Brien *
4400db7afdSDavid E. O'Brien * Copyright (c) 1996
4500db7afdSDavid E. O'Brien * Silicon Graphics Computer Systems, Inc.
4600db7afdSDavid E. O'Brien *
4700db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software
4800db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee,
4900db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and
5000db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear
5100db7afdSDavid E. O'Brien * in supporting documentation.  Silicon Graphics makes no
5200db7afdSDavid E. O'Brien * representations about the suitability of this software for any
5300db7afdSDavid E. O'Brien * purpose.  It is provided "as is" without express or implied warranty.
5400db7afdSDavid E. O'Brien */
5500db7afdSDavid E. O'Brien
5600db7afdSDavid E. O'Brien/** @file ext/functional
5700db7afdSDavid E. O'Brien *  This file is a GNU extension to the Standard C++ Library (possibly
58*f8a1b7d9SAlexander Kabaev *  containing extensions from the HP/SGI STL subset).
5900db7afdSDavid E. O'Brien */
6000db7afdSDavid E. O'Brien
6100db7afdSDavid E. O'Brien#ifndef _EXT_FUNCTIONAL
62ffeaf689SAlexander Kabaev#define _EXT_FUNCTIONAL 1
6300db7afdSDavid E. O'Brien
6400db7afdSDavid E. O'Brien#pragma GCC system_header
65ffeaf689SAlexander Kabaev
6600db7afdSDavid E. O'Brien#include <functional>
6700db7afdSDavid E. O'Brien
68*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
69*f8a1b7d9SAlexander Kabaev
70*f8a1b7d9SAlexander Kabaev  using std::size_t;
7100db7afdSDavid E. O'Brien  using std::unary_function;
7200db7afdSDavid E. O'Brien  using std::binary_function;
7300db7afdSDavid E. O'Brien  using std::mem_fun1_t;
7400db7afdSDavid E. O'Brien  using std::const_mem_fun1_t;
7500db7afdSDavid E. O'Brien  using std::mem_fun1_ref_t;
7600db7afdSDavid E. O'Brien  using std::const_mem_fun1_ref_t;
7700db7afdSDavid E. O'Brien
78*f8a1b7d9SAlexander Kabaev  /** The @c identity_element functions are not part of the C++
79*f8a1b7d9SAlexander Kabaev   *  standard; SGI provided them as an extension.  Its argument is an
80*f8a1b7d9SAlexander Kabaev   *  operation, and its return value is the identity element for that
81*f8a1b7d9SAlexander Kabaev   *  operation.  It is overloaded for addition and multiplication,
82*f8a1b7d9SAlexander Kabaev   *  and you can overload it for your own nefarious operations.
8300db7afdSDavid E. O'Brien   *
8400db7afdSDavid E. O'Brien   *  @addtogroup SGIextensions
8500db7afdSDavid E. O'Brien   *  @{
8600db7afdSDavid E. O'Brien   */
8700db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
88*f8a1b7d9SAlexander Kabaev  template <class _Tp>
89*f8a1b7d9SAlexander Kabaev    inline _Tp
90*f8a1b7d9SAlexander Kabaev    identity_element(std::plus<_Tp>)
91*f8a1b7d9SAlexander Kabaev    { return _Tp(0); }
92*f8a1b7d9SAlexander Kabaev
9300db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
94*f8a1b7d9SAlexander Kabaev  template <class _Tp>
95*f8a1b7d9SAlexander Kabaev    inline _Tp
96*f8a1b7d9SAlexander Kabaev    identity_element(std::multiplies<_Tp>)
97*f8a1b7d9SAlexander Kabaev    { return _Tp(1); }
9800db7afdSDavid E. O'Brien  /** @}  */
9900db7afdSDavid E. O'Brien
10000db7afdSDavid E. O'Brien  /** As an extension to the binders, SGI provided composition functors and
10100db7afdSDavid E. O'Brien   *  wrapper functions to aid in their creation.  The @c unary_compose
10200db7afdSDavid E. O'Brien   *  functor is constructed from two functions/functors, @c f and @c g.
10300db7afdSDavid E. O'Brien   *  Calling @c operator() with a single argument @c x returns @c f(g(x)).
10400db7afdSDavid E. O'Brien   *  The function @c compose1 takes the two functions and constructs a
10500db7afdSDavid E. O'Brien   *  @c unary_compose variable for you.
10600db7afdSDavid E. O'Brien   *
10700db7afdSDavid E. O'Brien   *  @c binary_compose is constructed from three functors, @c f, @c g1,
10800db7afdSDavid E. O'Brien   *  and @c g2.  Its @c operator() returns @c f(g1(x),g2(x)).  The function
10900db7afdSDavid E. O'Brien   *  @compose2 takes f, g1, and g2, and constructs the @c binary_compose
11000db7afdSDavid E. O'Brien   *  instance for you.  For example, if @c f returns an int, then
11100db7afdSDavid E. O'Brien   *  \code
11200db7afdSDavid E. O'Brien   *  int answer = (compose2(f,g1,g2))(x);
11300db7afdSDavid E. O'Brien   *  \endcode
11400db7afdSDavid E. O'Brien   *  is equivalent to
11500db7afdSDavid E. O'Brien   *  \code
11600db7afdSDavid E. O'Brien   *  int temp1 = g1(x);
11700db7afdSDavid E. O'Brien   *  int temp2 = g2(x);
11800db7afdSDavid E. O'Brien   *  int answer = f(temp1,temp2);
11900db7afdSDavid E. O'Brien   *  \endcode
12000db7afdSDavid E. O'Brien   *  But the first form is more compact, and can be passed around as a
12100db7afdSDavid E. O'Brien   *  functor to other algorithms.
12200db7afdSDavid E. O'Brien   *
12300db7afdSDavid E. O'Brien   *  @addtogroup SGIextensions
12400db7afdSDavid E. O'Brien   *  @{
12500db7afdSDavid E. O'Brien   */
12600db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
12700db7afdSDavid E. O'Brien  template <class _Operation1, class _Operation2>
12800db7afdSDavid E. O'Brien    class unary_compose
12900db7afdSDavid E. O'Brien    : public unary_function<typename _Operation2::argument_type,
13000db7afdSDavid E. O'Brien			    typename _Operation1::result_type>
13100db7afdSDavid E. O'Brien    {
13200db7afdSDavid E. O'Brien    protected:
13300db7afdSDavid E. O'Brien      _Operation1 _M_fn1;
13400db7afdSDavid E. O'Brien      _Operation2 _M_fn2;
135*f8a1b7d9SAlexander Kabaev
13600db7afdSDavid E. O'Brien    public:
13700db7afdSDavid E. O'Brien      unary_compose(const _Operation1& __x, const _Operation2& __y)
13800db7afdSDavid E. O'Brien      : _M_fn1(__x), _M_fn2(__y) {}
139*f8a1b7d9SAlexander Kabaev
14000db7afdSDavid E. O'Brien      typename _Operation1::result_type
141*f8a1b7d9SAlexander Kabaev      operator()(const typename _Operation2::argument_type& __x) const
142*f8a1b7d9SAlexander Kabaev      { return _M_fn1(_M_fn2(__x)); }
14300db7afdSDavid E. O'Brien    };
14400db7afdSDavid E. O'Brien
14500db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
14600db7afdSDavid E. O'Brien  template <class _Operation1, class _Operation2>
14700db7afdSDavid E. O'Brien    inline unary_compose<_Operation1, _Operation2>
14800db7afdSDavid E. O'Brien    compose1(const _Operation1& __fn1, const _Operation2& __fn2)
149*f8a1b7d9SAlexander Kabaev    { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); }
15000db7afdSDavid E. O'Brien
15100db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
15200db7afdSDavid E. O'Brien  template <class _Operation1, class _Operation2, class _Operation3>
15300db7afdSDavid E. O'Brien    class binary_compose
15400db7afdSDavid E. O'Brien    : public unary_function<typename _Operation2::argument_type,
155*f8a1b7d9SAlexander Kabaev			    typename _Operation1::result_type>
156*f8a1b7d9SAlexander Kabaev    {
15700db7afdSDavid E. O'Brien    protected:
15800db7afdSDavid E. O'Brien      _Operation1 _M_fn1;
15900db7afdSDavid E. O'Brien      _Operation2 _M_fn2;
16000db7afdSDavid E. O'Brien      _Operation3 _M_fn3;
161*f8a1b7d9SAlexander Kabaev
16200db7afdSDavid E. O'Brien    public:
16300db7afdSDavid E. O'Brien      binary_compose(const _Operation1& __x, const _Operation2& __y,
16400db7afdSDavid E. O'Brien		     const _Operation3& __z)
16500db7afdSDavid E. O'Brien      : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { }
166*f8a1b7d9SAlexander Kabaev
16700db7afdSDavid E. O'Brien      typename _Operation1::result_type
168*f8a1b7d9SAlexander Kabaev      operator()(const typename _Operation2::argument_type& __x) const
169*f8a1b7d9SAlexander Kabaev      { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); }
17000db7afdSDavid E. O'Brien    };
17100db7afdSDavid E. O'Brien
17200db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
17300db7afdSDavid E. O'Brien  template <class _Operation1, class _Operation2, class _Operation3>
17400db7afdSDavid E. O'Brien    inline binary_compose<_Operation1, _Operation2, _Operation3>
17500db7afdSDavid E. O'Brien    compose2(const _Operation1& __fn1, const _Operation2& __fn2,
17600db7afdSDavid E. O'Brien	     const _Operation3& __fn3)
177*f8a1b7d9SAlexander Kabaev    { return binary_compose<_Operation1, _Operation2, _Operation3>
178*f8a1b7d9SAlexander Kabaev	(__fn1, __fn2, __fn3); }
17900db7afdSDavid E. O'Brien  /** @}  */
18000db7afdSDavid E. O'Brien
18100db7afdSDavid E. O'Brien  /** As an extension, SGI provided a functor called @c identity.  When a
18200db7afdSDavid E. O'Brien   *  functor is required but no operations are desired, this can be used as a
18300db7afdSDavid E. O'Brien   *  pass-through.  Its @c operator() returns its argument unchanged.
18400db7afdSDavid E. O'Brien   *
18500db7afdSDavid E. O'Brien   *  @addtogroup SGIextensions
18600db7afdSDavid E. O'Brien   */
187*f8a1b7d9SAlexander Kabaev  template <class _Tp>
188*f8a1b7d9SAlexander Kabaev    struct identity : public std::_Identity<_Tp> {};
18900db7afdSDavid E. O'Brien
19000db7afdSDavid E. O'Brien  /** @c select1st and @c select2nd are extensions provided by SGI.  Their
19100db7afdSDavid E. O'Brien   *  @c operator()s
19200db7afdSDavid E. O'Brien   *  take a @c std::pair as an argument, and return either the first member
19300db7afdSDavid E. O'Brien   *  or the second member, respectively.  They can be used (especially with
19400db7afdSDavid E. O'Brien   *  the composition functors) to "strip" data from a sequence before
19500db7afdSDavid E. O'Brien   *  performing the remainder of an algorithm.
19600db7afdSDavid E. O'Brien   *
19700db7afdSDavid E. O'Brien   *  @addtogroup SGIextensions
19800db7afdSDavid E. O'Brien   *  @{
19900db7afdSDavid E. O'Brien   */
20000db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
201*f8a1b7d9SAlexander Kabaev  template <class _Pair>
202*f8a1b7d9SAlexander Kabaev    struct select1st : public std::_Select1st<_Pair> {};
203*f8a1b7d9SAlexander Kabaev
20400db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
205*f8a1b7d9SAlexander Kabaev  template <class _Pair>
206*f8a1b7d9SAlexander Kabaev    struct select2nd : public std::_Select2nd<_Pair> {};
20700db7afdSDavid E. O'Brien  /** @}  */
20800db7afdSDavid E. O'Brien
20900db7afdSDavid E. O'Brien  // extension documented next
21000db7afdSDavid E. O'Brien  template <class _Arg1, class _Arg2>
211*f8a1b7d9SAlexander Kabaev    struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1>
212*f8a1b7d9SAlexander Kabaev    {
213*f8a1b7d9SAlexander Kabaev      _Arg1
214*f8a1b7d9SAlexander Kabaev      operator()(const _Arg1& __x, const _Arg2&) const
215*f8a1b7d9SAlexander Kabaev      { return __x; }
21600db7afdSDavid E. O'Brien    };
21700db7afdSDavid E. O'Brien
21800db7afdSDavid E. O'Brien  template <class _Arg1, class _Arg2>
219*f8a1b7d9SAlexander Kabaev    struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2>
220*f8a1b7d9SAlexander Kabaev    {
221*f8a1b7d9SAlexander Kabaev      _Arg2
222*f8a1b7d9SAlexander Kabaev      operator()(const _Arg1&, const _Arg2& __y) const
223*f8a1b7d9SAlexander Kabaev      { return __y; }
22400db7afdSDavid E. O'Brien    };
22500db7afdSDavid E. O'Brien
22600db7afdSDavid E. O'Brien  /** The @c operator() of the @c project1st functor takes two arbitrary
22700db7afdSDavid E. O'Brien   *  arguments and returns the first one, while @c project2nd returns the
22800db7afdSDavid E. O'Brien   *  second one.  They are extensions provided by SGI.
22900db7afdSDavid E. O'Brien   *
23000db7afdSDavid E. O'Brien   *  @addtogroup SGIextensions
23100db7afdSDavid E. O'Brien   *  @{
23200db7afdSDavid E. O'Brien   */
23300db7afdSDavid E. O'Brien
23400db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
23500db7afdSDavid E. O'Brien  template <class _Arg1, class _Arg2>
23600db7afdSDavid E. O'Brien    struct project1st : public _Project1st<_Arg1, _Arg2> {};
23700db7afdSDavid E. O'Brien
23800db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
23900db7afdSDavid E. O'Brien  template <class _Arg1, class _Arg2>
24000db7afdSDavid E. O'Brien    struct project2nd : public _Project2nd<_Arg1, _Arg2> {};
24100db7afdSDavid E. O'Brien  /** @}  */
24200db7afdSDavid E. O'Brien
24300db7afdSDavid E. O'Brien  // extension documented next
24400db7afdSDavid E. O'Brien  template <class _Result>
245*f8a1b7d9SAlexander Kabaev    struct _Constant_void_fun
246*f8a1b7d9SAlexander Kabaev    {
24700db7afdSDavid E. O'Brien      typedef _Result result_type;
24800db7afdSDavid E. O'Brien      result_type _M_val;
24900db7afdSDavid E. O'Brien
25000db7afdSDavid E. O'Brien      _Constant_void_fun(const result_type& __v) : _M_val(__v) {}
251*f8a1b7d9SAlexander Kabaev
252*f8a1b7d9SAlexander Kabaev      const result_type&
253*f8a1b7d9SAlexander Kabaev      operator()() const
254*f8a1b7d9SAlexander Kabaev      { return _M_val; }
25500db7afdSDavid E. O'Brien    };
25600db7afdSDavid E. O'Brien
25700db7afdSDavid E. O'Brien  template <class _Result, class _Argument>
258*f8a1b7d9SAlexander Kabaev    struct _Constant_unary_fun
259*f8a1b7d9SAlexander Kabaev    {
26000db7afdSDavid E. O'Brien      typedef _Argument argument_type;
26100db7afdSDavid E. O'Brien      typedef  _Result  result_type;
26200db7afdSDavid E. O'Brien      result_type _M_val;
26300db7afdSDavid E. O'Brien
26400db7afdSDavid E. O'Brien      _Constant_unary_fun(const result_type& __v) : _M_val(__v) {}
265*f8a1b7d9SAlexander Kabaev
266*f8a1b7d9SAlexander Kabaev      const result_type&
267*f8a1b7d9SAlexander Kabaev      operator()(const _Argument&) const
268*f8a1b7d9SAlexander Kabaev      { return _M_val; }
26900db7afdSDavid E. O'Brien    };
27000db7afdSDavid E. O'Brien
27100db7afdSDavid E. O'Brien  template <class _Result, class _Arg1, class _Arg2>
272*f8a1b7d9SAlexander Kabaev    struct _Constant_binary_fun
273*f8a1b7d9SAlexander Kabaev    {
27400db7afdSDavid E. O'Brien      typedef  _Arg1   first_argument_type;
27500db7afdSDavid E. O'Brien      typedef  _Arg2   second_argument_type;
27600db7afdSDavid E. O'Brien      typedef  _Result result_type;
27700db7afdSDavid E. O'Brien      _Result _M_val;
27800db7afdSDavid E. O'Brien
27900db7afdSDavid E. O'Brien      _Constant_binary_fun(const _Result& __v) : _M_val(__v) {}
280*f8a1b7d9SAlexander Kabaev
281*f8a1b7d9SAlexander Kabaev      const result_type&
282*f8a1b7d9SAlexander Kabaev      operator()(const _Arg1&, const _Arg2&) const
283*f8a1b7d9SAlexander Kabaev      { return _M_val; }
28400db7afdSDavid E. O'Brien    };
28500db7afdSDavid E. O'Brien
28600db7afdSDavid E. O'Brien  /** These three functors are each constructed from a single arbitrary
28700db7afdSDavid E. O'Brien   *  variable/value.  Later, their @c operator()s completely ignore any
28800db7afdSDavid E. O'Brien   *  arguments passed, and return the stored value.
28900db7afdSDavid E. O'Brien   *  - @c constant_void_fun's @c operator() takes no arguments
29000db7afdSDavid E. O'Brien   *  - @c constant_unary_fun's @c operator() takes one argument (ignored)
29100db7afdSDavid E. O'Brien   *  - @c constant_binary_fun's @c operator() takes two arguments (ignored)
29200db7afdSDavid E. O'Brien   *
29300db7afdSDavid E. O'Brien   *  The helper creator functions @c constant0, @c constant1, and
29400db7afdSDavid E. O'Brien   *  @c constant2 each take a "result" argument and construct variables of
29500db7afdSDavid E. O'Brien   *  the appropriate functor type.
29600db7afdSDavid E. O'Brien   *
29700db7afdSDavid E. O'Brien   *  @addtogroup SGIextensions
29800db7afdSDavid E. O'Brien   *  @{
29900db7afdSDavid E. O'Brien   */
30000db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
30100db7afdSDavid E. O'Brien  template <class _Result>
302*f8a1b7d9SAlexander Kabaev    struct constant_void_fun
303*f8a1b7d9SAlexander Kabaev    : public _Constant_void_fun<_Result>
304*f8a1b7d9SAlexander Kabaev    {
305*f8a1b7d9SAlexander Kabaev      constant_void_fun(const _Result& __v)
306*f8a1b7d9SAlexander Kabaev      : _Constant_void_fun<_Result>(__v) {}
30700db7afdSDavid E. O'Brien    };
30800db7afdSDavid E. O'Brien
30900db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
310*f8a1b7d9SAlexander Kabaev  template <class _Result, class _Argument = _Result>
31100db7afdSDavid E. O'Brien    struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument>
31200db7afdSDavid E. O'Brien    {
31300db7afdSDavid E. O'Brien      constant_unary_fun(const _Result& __v)
31400db7afdSDavid E. O'Brien      : _Constant_unary_fun<_Result, _Argument>(__v) {}
31500db7afdSDavid E. O'Brien    };
31600db7afdSDavid E. O'Brien
31700db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
318*f8a1b7d9SAlexander Kabaev  template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1>
31900db7afdSDavid E. O'Brien    struct constant_binary_fun
32000db7afdSDavid E. O'Brien    : public _Constant_binary_fun<_Result, _Arg1, _Arg2>
32100db7afdSDavid E. O'Brien    {
32200db7afdSDavid E. O'Brien      constant_binary_fun(const _Result& __v)
32300db7afdSDavid E. O'Brien      : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {}
32400db7afdSDavid E. O'Brien    };
32500db7afdSDavid E. O'Brien
32600db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
32700db7afdSDavid E. O'Brien  template <class _Result>
328*f8a1b7d9SAlexander Kabaev    inline constant_void_fun<_Result>
329*f8a1b7d9SAlexander Kabaev    constant0(const _Result& __val)
330*f8a1b7d9SAlexander Kabaev    { return constant_void_fun<_Result>(__val); }
33100db7afdSDavid E. O'Brien
33200db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
33300db7afdSDavid E. O'Brien  template <class _Result>
334*f8a1b7d9SAlexander Kabaev    inline constant_unary_fun<_Result, _Result>
335*f8a1b7d9SAlexander Kabaev    constant1(const _Result& __val)
336*f8a1b7d9SAlexander Kabaev    { return constant_unary_fun<_Result, _Result>(__val); }
33700db7afdSDavid E. O'Brien
33800db7afdSDavid E. O'Brien  /// An \link SGIextensions SGI extension \endlink.
33900db7afdSDavid E. O'Brien  template <class _Result>
34000db7afdSDavid E. O'Brien    inline constant_binary_fun<_Result,_Result,_Result>
34100db7afdSDavid E. O'Brien    constant2(const _Result& __val)
342*f8a1b7d9SAlexander Kabaev    { return constant_binary_fun<_Result, _Result, _Result>(__val); }
34300db7afdSDavid E. O'Brien  /** @}  */
34400db7afdSDavid E. O'Brien
34500db7afdSDavid E. O'Brien  /** The @c subtractive_rng class is documented on
34600db7afdSDavid E. O'Brien   *  <a href="http://www.sgi.com/tech/stl/">SGI's site</a>.
34700db7afdSDavid E. O'Brien   *  Note that this code assumes that @c int is 32 bits.
34800db7afdSDavid E. O'Brien   *
34900db7afdSDavid E. O'Brien   *  @ingroup SGIextensions
35000db7afdSDavid E. O'Brien   */
351*f8a1b7d9SAlexander Kabaev  class subtractive_rng
352*f8a1b7d9SAlexander Kabaev  : public unary_function<unsigned int, unsigned int>
353*f8a1b7d9SAlexander Kabaev  {
35400db7afdSDavid E. O'Brien  private:
35500db7afdSDavid E. O'Brien    unsigned int _M_table[55];
35600db7afdSDavid E. O'Brien    size_t _M_index1;
35700db7afdSDavid E. O'Brien    size_t _M_index2;
358*f8a1b7d9SAlexander Kabaev
35900db7afdSDavid E. O'Brien  public:
36000db7afdSDavid E. O'Brien    /// Returns a number less than the argument.
361*f8a1b7d9SAlexander Kabaev    unsigned int
362*f8a1b7d9SAlexander Kabaev    operator()(unsigned int __limit)
363*f8a1b7d9SAlexander Kabaev    {
36400db7afdSDavid E. O'Brien      _M_index1 = (_M_index1 + 1) % 55;
36500db7afdSDavid E. O'Brien      _M_index2 = (_M_index2 + 1) % 55;
36600db7afdSDavid E. O'Brien      _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2];
36700db7afdSDavid E. O'Brien      return _M_table[_M_index1] % __limit;
36800db7afdSDavid E. O'Brien    }
36900db7afdSDavid E. O'Brien
370*f8a1b7d9SAlexander Kabaev    void
371*f8a1b7d9SAlexander Kabaev    _M_initialize(unsigned int __seed)
37200db7afdSDavid E. O'Brien    {
37300db7afdSDavid E. O'Brien      unsigned int __k = 1;
37400db7afdSDavid E. O'Brien      _M_table[54] = __seed;
37500db7afdSDavid E. O'Brien      size_t __i;
376*f8a1b7d9SAlexander Kabaev      for (__i = 0; __i < 54; __i++)
377*f8a1b7d9SAlexander Kabaev	{
37800db7afdSDavid E. O'Brien	  size_t __ii = (21 * (__i + 1) % 55) - 1;
37900db7afdSDavid E. O'Brien	  _M_table[__ii] = __k;
38000db7afdSDavid E. O'Brien	  __k = __seed - __k;
38100db7afdSDavid E. O'Brien	  __seed = _M_table[__ii];
38200db7afdSDavid E. O'Brien	}
383*f8a1b7d9SAlexander Kabaev      for (int __loop = 0; __loop < 4; __loop++)
384*f8a1b7d9SAlexander Kabaev	{
38500db7afdSDavid E. O'Brien	  for (__i = 0; __i < 55; __i++)
38600db7afdSDavid E. O'Brien            _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];
38700db7afdSDavid E. O'Brien	}
38800db7afdSDavid E. O'Brien      _M_index1 = 0;
38900db7afdSDavid E. O'Brien      _M_index2 = 31;
39000db7afdSDavid E. O'Brien    }
39100db7afdSDavid E. O'Brien
39200db7afdSDavid E. O'Brien    /// Ctor allowing you to initialize the seed.
393*f8a1b7d9SAlexander Kabaev    subtractive_rng(unsigned int __seed)
394*f8a1b7d9SAlexander Kabaev    { _M_initialize(__seed); }
395*f8a1b7d9SAlexander Kabaev
39600db7afdSDavid E. O'Brien    /// Default ctor; initializes its state with some number you don't see.
397*f8a1b7d9SAlexander Kabaev    subtractive_rng()
398*f8a1b7d9SAlexander Kabaev    { _M_initialize(161803398u); }
39900db7afdSDavid E. O'Brien  };
40000db7afdSDavid E. O'Brien
40100db7afdSDavid E. O'Brien  // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref,
40200db7afdSDavid E. O'Brien  // provided for backward compatibility, they are no longer part of
40300db7afdSDavid E. O'Brien  // the C++ standard.
40400db7afdSDavid E. O'Brien
40500db7afdSDavid E. O'Brien  template <class _Ret, class _Tp, class _Arg>
406*f8a1b7d9SAlexander Kabaev    inline mem_fun1_t<_Ret, _Tp, _Arg>
407*f8a1b7d9SAlexander Kabaev    mem_fun1(_Ret (_Tp::*__f)(_Arg))
40800db7afdSDavid E. O'Brien    { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
40900db7afdSDavid E. O'Brien
41000db7afdSDavid E. O'Brien  template <class _Ret, class _Tp, class _Arg>
411*f8a1b7d9SAlexander Kabaev    inline const_mem_fun1_t<_Ret, _Tp, _Arg>
412*f8a1b7d9SAlexander Kabaev    mem_fun1(_Ret (_Tp::*__f)(_Arg) const)
41300db7afdSDavid E. O'Brien    { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
41400db7afdSDavid E. O'Brien
41500db7afdSDavid E. O'Brien  template <class _Ret, class _Tp, class _Arg>
416*f8a1b7d9SAlexander Kabaev    inline mem_fun1_ref_t<_Ret, _Tp, _Arg>
417*f8a1b7d9SAlexander Kabaev    mem_fun1_ref(_Ret (_Tp::*__f)(_Arg))
41800db7afdSDavid E. O'Brien    { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
41900db7afdSDavid E. O'Brien
42000db7afdSDavid E. O'Brien  template <class _Ret, class _Tp, class _Arg>
42100db7afdSDavid E. O'Brien    inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg>
42200db7afdSDavid E. O'Brien    mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const)
42300db7afdSDavid E. O'Brien    { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
424*f8a1b7d9SAlexander Kabaev
425*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE
42600db7afdSDavid E. O'Brien
427ffeaf689SAlexander Kabaev#endif
42800db7afdSDavid E. O'Brien
429