197403Sobrien// Functional extensions -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
497403Sobrien//
597403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
697403Sobrien// software; you can redistribute it and/or modify it under the
797403Sobrien// terms of the GNU General Public License as published by the
897403Sobrien// Free Software Foundation; either version 2, or (at your option)
997403Sobrien// any later version.
1097403Sobrien
1197403Sobrien// This library is distributed in the hope that it will be useful,
1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1497403Sobrien// GNU General Public License for more details.
1597403Sobrien
1697403Sobrien// You should have received a copy of the GNU General Public License along
1797403Sobrien// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1997403Sobrien// USA.
2097403Sobrien
2197403Sobrien// As a special exception, you may use this file as part of a free software
2297403Sobrien// library without restriction.  Specifically, if other files instantiate
2397403Sobrien// templates or use macros or inline functions from this file, or you compile
2497403Sobrien// this file and link it with other files to produce an executable, this
2597403Sobrien// file does not by itself cause the resulting executable to be covered by
2697403Sobrien// the GNU General Public License.  This exception does not however
2797403Sobrien// invalidate any other reasons why the executable file might be covered by
2897403Sobrien// the GNU General Public License.
2997403Sobrien
3097403Sobrien/*
3197403Sobrien *
3297403Sobrien * Copyright (c) 1994
3397403Sobrien * Hewlett-Packard Company
3497403Sobrien *
3597403Sobrien * Permission to use, copy, modify, distribute and sell this software
3697403Sobrien * and its documentation for any purpose is hereby granted without fee,
3797403Sobrien * provided that the above copyright notice appear in all copies and
3897403Sobrien * that both that copyright notice and this permission notice appear
3997403Sobrien * in supporting documentation.  Hewlett-Packard Company makes no
4097403Sobrien * representations about the suitability of this software for any
4197403Sobrien * purpose.  It is provided "as is" without express or implied warranty.
4297403Sobrien *
4397403Sobrien *
4497403Sobrien * Copyright (c) 1996
4597403Sobrien * Silicon Graphics Computer Systems, Inc.
4697403Sobrien *
4797403Sobrien * Permission to use, copy, modify, distribute and sell this software
4897403Sobrien * and its documentation for any purpose is hereby granted without fee,
4997403Sobrien * provided that the above copyright notice appear in all copies and
5097403Sobrien * that both that copyright notice and this permission notice appear
5197403Sobrien * in supporting documentation.  Silicon Graphics makes no
5297403Sobrien * representations about the suitability of this software for any
5397403Sobrien * purpose.  It is provided "as is" without express or implied warranty.
5497403Sobrien */
5597403Sobrien
5697403Sobrien/** @file ext/functional
5797403Sobrien *  This file is a GNU extension to the Standard C++ Library (possibly
58169691Skan *  containing extensions from the HP/SGI STL subset).
5997403Sobrien */
6097403Sobrien
6197403Sobrien#ifndef _EXT_FUNCTIONAL
62132720Skan#define _EXT_FUNCTIONAL 1
6397403Sobrien
6497403Sobrien#pragma GCC system_header
65132720Skan
6697403Sobrien#include <functional>
6797403Sobrien
68169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
6997403Sobrien
70169691Skan  using std::size_t;
71169691Skan  using std::unary_function;
72169691Skan  using std::binary_function;
73169691Skan  using std::mem_fun1_t;
74169691Skan  using std::const_mem_fun1_t;
75169691Skan  using std::mem_fun1_ref_t;
76169691Skan  using std::const_mem_fun1_ref_t;
7797403Sobrien
78169691Skan  /** The @c identity_element functions are not part of the C++
79169691Skan   *  standard; SGI provided them as an extension.  Its argument is an
80169691Skan   *  operation, and its return value is the identity element for that
81169691Skan   *  operation.  It is overloaded for addition and multiplication,
82169691Skan   *  and you can overload it for your own nefarious operations.
83169691Skan   *
84169691Skan   *  @addtogroup SGIextensions
85169691Skan   *  @{
86169691Skan   */
87169691Skan  /// An \link SGIextensions SGI extension \endlink.
88169691Skan  template <class _Tp>
89169691Skan    inline _Tp
90169691Skan    identity_element(std::plus<_Tp>)
91169691Skan    { return _Tp(0); }
9297403Sobrien
93169691Skan  /// An \link SGIextensions SGI extension \endlink.
94169691Skan  template <class _Tp>
95169691Skan    inline _Tp
96169691Skan    identity_element(std::multiplies<_Tp>)
97169691Skan    { return _Tp(1); }
98169691Skan  /** @}  */
99169691Skan  
100169691Skan  /** As an extension to the binders, SGI provided composition functors and
101169691Skan   *  wrapper functions to aid in their creation.  The @c unary_compose
102169691Skan   *  functor is constructed from two functions/functors, @c f and @c g.
103169691Skan   *  Calling @c operator() with a single argument @c x returns @c f(g(x)).
104169691Skan   *  The function @c compose1 takes the two functions and constructs a
105169691Skan   *  @c unary_compose variable for you.
106169691Skan   *
107169691Skan   *  @c binary_compose is constructed from three functors, @c f, @c g1,
108169691Skan   *  and @c g2.  Its @c operator() returns @c f(g1(x),g2(x)).  The function
109169691Skan   *  @compose2 takes f, g1, and g2, and constructs the @c binary_compose
110169691Skan   *  instance for you.  For example, if @c f returns an int, then
111169691Skan   *  \code
112169691Skan   *  int answer = (compose2(f,g1,g2))(x);
113169691Skan   *  \endcode
114169691Skan   *  is equivalent to
115169691Skan   *  \code
116169691Skan   *  int temp1 = g1(x);
117169691Skan   *  int temp2 = g2(x);
118169691Skan   *  int answer = f(temp1,temp2);
119169691Skan   *  \endcode
120169691Skan   *  But the first form is more compact, and can be passed around as a
121169691Skan   *  functor to other algorithms.
122169691Skan   *
123169691Skan   *  @addtogroup SGIextensions
124169691Skan   *  @{
125169691Skan   */
126169691Skan  /// An \link SGIextensions SGI extension \endlink.
127169691Skan  template <class _Operation1, class _Operation2>
128169691Skan    class unary_compose
129169691Skan    : public unary_function<typename _Operation2::argument_type,
130169691Skan			    typename _Operation1::result_type>
131169691Skan    {
132169691Skan    protected:
133169691Skan      _Operation1 _M_fn1;
134169691Skan      _Operation2 _M_fn2;
13597403Sobrien
136169691Skan    public:
137169691Skan      unary_compose(const _Operation1& __x, const _Operation2& __y)
138169691Skan      : _M_fn1(__x), _M_fn2(__y) {}
13997403Sobrien
140169691Skan      typename _Operation1::result_type
141169691Skan      operator()(const typename _Operation2::argument_type& __x) const
142169691Skan      { return _M_fn1(_M_fn2(__x)); }
143169691Skan    };
14497403Sobrien
145169691Skan  /// An \link SGIextensions SGI extension \endlink.
146169691Skan  template <class _Operation1, class _Operation2>
147169691Skan    inline unary_compose<_Operation1, _Operation2>
148169691Skan    compose1(const _Operation1& __fn1, const _Operation2& __fn2)
149169691Skan    { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); }
15097403Sobrien
151169691Skan  /// An \link SGIextensions SGI extension \endlink.
152169691Skan  template <class _Operation1, class _Operation2, class _Operation3>
153169691Skan    class binary_compose
154169691Skan    : public unary_function<typename _Operation2::argument_type,
155169691Skan			    typename _Operation1::result_type>
156169691Skan    {
157169691Skan    protected:
158169691Skan      _Operation1 _M_fn1;
159169691Skan      _Operation2 _M_fn2;
160169691Skan      _Operation3 _M_fn3;
161169691Skan      
162169691Skan    public:
163169691Skan      binary_compose(const _Operation1& __x, const _Operation2& __y,
164169691Skan		     const _Operation3& __z)
165169691Skan      : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { }
16697403Sobrien
167169691Skan      typename _Operation1::result_type
168169691Skan      operator()(const typename _Operation2::argument_type& __x) const
169169691Skan      { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); }
170169691Skan    };
17197403Sobrien
172169691Skan  /// An \link SGIextensions SGI extension \endlink.
173169691Skan  template <class _Operation1, class _Operation2, class _Operation3>
174169691Skan    inline binary_compose<_Operation1, _Operation2, _Operation3>
175169691Skan    compose2(const _Operation1& __fn1, const _Operation2& __fn2,
176169691Skan	     const _Operation3& __fn3)
177169691Skan    { return binary_compose<_Operation1, _Operation2, _Operation3>
178169691Skan	(__fn1, __fn2, __fn3); }
179169691Skan  /** @}  */
18097403Sobrien
181169691Skan  /** As an extension, SGI provided a functor called @c identity.  When a
182169691Skan   *  functor is required but no operations are desired, this can be used as a
183169691Skan   *  pass-through.  Its @c operator() returns its argument unchanged.
184169691Skan   *
185169691Skan   *  @addtogroup SGIextensions
186169691Skan   */
187169691Skan  template <class _Tp>
188169691Skan    struct identity : public std::_Identity<_Tp> {};
18997403Sobrien
190169691Skan  /** @c select1st and @c select2nd are extensions provided by SGI.  Their
191169691Skan   *  @c operator()s
192169691Skan   *  take a @c std::pair as an argument, and return either the first member
193169691Skan   *  or the second member, respectively.  They can be used (especially with
194169691Skan   *  the composition functors) to "strip" data from a sequence before
195169691Skan   *  performing the remainder of an algorithm.
196169691Skan   *
197169691Skan   *  @addtogroup SGIextensions
198169691Skan   *  @{
199169691Skan   */
200169691Skan  /// An \link SGIextensions SGI extension \endlink.
201169691Skan  template <class _Pair>
202169691Skan    struct select1st : public std::_Select1st<_Pair> {};
20397403Sobrien
204169691Skan  /// An \link SGIextensions SGI extension \endlink.
205169691Skan  template <class _Pair>
206169691Skan    struct select2nd : public std::_Select2nd<_Pair> {};
207169691Skan  /** @}  */
20897403Sobrien
209169691Skan  // extension documented next
210169691Skan  template <class _Arg1, class _Arg2>
211169691Skan    struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1>
212169691Skan    {
213169691Skan      _Arg1
214169691Skan      operator()(const _Arg1& __x, const _Arg2&) const
215169691Skan      { return __x; }
216169691Skan    };
21797403Sobrien
218169691Skan  template <class _Arg1, class _Arg2>
219169691Skan    struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2>
220169691Skan    {
221169691Skan      _Arg2
222169691Skan      operator()(const _Arg1&, const _Arg2& __y) const
223169691Skan      { return __y; }
224169691Skan    };
22597403Sobrien
226169691Skan  /** The @c operator() of the @c project1st functor takes two arbitrary
227169691Skan   *  arguments and returns the first one, while @c project2nd returns the
228169691Skan   *  second one.  They are extensions provided by SGI.
229169691Skan   *
230169691Skan   *  @addtogroup SGIextensions
231169691Skan   *  @{
232169691Skan   */
23397403Sobrien
234169691Skan  /// An \link SGIextensions SGI extension \endlink.
235169691Skan  template <class _Arg1, class _Arg2>
236169691Skan    struct project1st : public _Project1st<_Arg1, _Arg2> {};
23797403Sobrien
238169691Skan  /// An \link SGIextensions SGI extension \endlink.
239169691Skan  template <class _Arg1, class _Arg2>
240169691Skan    struct project2nd : public _Project2nd<_Arg1, _Arg2> {};
241169691Skan  /** @}  */
24297403Sobrien
243169691Skan  // extension documented next
244169691Skan  template <class _Result>
245169691Skan    struct _Constant_void_fun
246169691Skan    {
247169691Skan      typedef _Result result_type;
248169691Skan      result_type _M_val;
24997403Sobrien
250169691Skan      _Constant_void_fun(const result_type& __v) : _M_val(__v) {}
25197403Sobrien
252169691Skan      const result_type&
253169691Skan      operator()() const
254169691Skan      { return _M_val; }
255169691Skan    };
25697403Sobrien
257169691Skan  template <class _Result, class _Argument>
258169691Skan    struct _Constant_unary_fun
259169691Skan    {
260169691Skan      typedef _Argument argument_type;
261169691Skan      typedef  _Result  result_type;
262169691Skan      result_type _M_val;
263169691Skan      
264169691Skan      _Constant_unary_fun(const result_type& __v) : _M_val(__v) {}
26597403Sobrien
266169691Skan      const result_type&
267169691Skan      operator()(const _Argument&) const
268169691Skan      { return _M_val; }
269169691Skan    };
27097403Sobrien
271169691Skan  template <class _Result, class _Arg1, class _Arg2>
272169691Skan    struct _Constant_binary_fun
273169691Skan    {
274169691Skan      typedef  _Arg1   first_argument_type;
275169691Skan      typedef  _Arg2   second_argument_type;
276169691Skan      typedef  _Result result_type;
277169691Skan      _Result _M_val;
27897403Sobrien
279169691Skan      _Constant_binary_fun(const _Result& __v) : _M_val(__v) {}
280169691Skan      
281169691Skan      const result_type&
282169691Skan      operator()(const _Arg1&, const _Arg2&) const
283169691Skan      { return _M_val; }
284169691Skan    };
28597403Sobrien
286169691Skan  /** These three functors are each constructed from a single arbitrary
287169691Skan   *  variable/value.  Later, their @c operator()s completely ignore any
288169691Skan   *  arguments passed, and return the stored value.
289169691Skan   *  - @c constant_void_fun's @c operator() takes no arguments
290169691Skan   *  - @c constant_unary_fun's @c operator() takes one argument (ignored)
291169691Skan   *  - @c constant_binary_fun's @c operator() takes two arguments (ignored)
292169691Skan   *
293169691Skan   *  The helper creator functions @c constant0, @c constant1, and
294169691Skan   *  @c constant2 each take a "result" argument and construct variables of
295169691Skan   *  the appropriate functor type.
296169691Skan   *
297169691Skan   *  @addtogroup SGIextensions
298169691Skan   *  @{
299169691Skan   */
300169691Skan  /// An \link SGIextensions SGI extension \endlink.
301169691Skan  template <class _Result>
302169691Skan    struct constant_void_fun
303169691Skan    : public _Constant_void_fun<_Result>
304169691Skan    {
305169691Skan      constant_void_fun(const _Result& __v)
306169691Skan      : _Constant_void_fun<_Result>(__v) {}
307169691Skan    };
30897403Sobrien
309169691Skan  /// An \link SGIextensions SGI extension \endlink.
310169691Skan  template <class _Result, class _Argument = _Result>
311169691Skan    struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument>
312169691Skan    {
313169691Skan      constant_unary_fun(const _Result& __v)
314169691Skan      : _Constant_unary_fun<_Result, _Argument>(__v) {}
315169691Skan    };
316169691Skan
317169691Skan  /// An \link SGIextensions SGI extension \endlink.
318169691Skan  template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1>
319169691Skan    struct constant_binary_fun
320169691Skan    : public _Constant_binary_fun<_Result, _Arg1, _Arg2>
321169691Skan    {
322169691Skan      constant_binary_fun(const _Result& __v)
323169691Skan      : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {}
324169691Skan    };
325169691Skan
326169691Skan  /// An \link SGIextensions SGI extension \endlink.
327169691Skan  template <class _Result>
328169691Skan    inline constant_void_fun<_Result>
329169691Skan    constant0(const _Result& __val)
330169691Skan    { return constant_void_fun<_Result>(__val); }
331169691Skan
332169691Skan  /// An \link SGIextensions SGI extension \endlink.
333169691Skan  template <class _Result>
334169691Skan    inline constant_unary_fun<_Result, _Result>
335169691Skan    constant1(const _Result& __val)
336169691Skan    { return constant_unary_fun<_Result, _Result>(__val); }
337169691Skan
338169691Skan  /// An \link SGIextensions SGI extension \endlink.
339169691Skan  template <class _Result>
340169691Skan    inline constant_binary_fun<_Result,_Result,_Result>
341169691Skan    constant2(const _Result& __val)
342169691Skan    { return constant_binary_fun<_Result, _Result, _Result>(__val); }
343169691Skan  /** @}  */
344169691Skan
345169691Skan  /** The @c subtractive_rng class is documented on
346169691Skan   *  <a href="http://www.sgi.com/tech/stl/">SGI's site</a>.
347169691Skan   *  Note that this code assumes that @c int is 32 bits.
348169691Skan   *
349169691Skan   *  @ingroup SGIextensions
350169691Skan   */
351169691Skan  class subtractive_rng
352169691Skan  : public unary_function<unsigned int, unsigned int>
35397403Sobrien  {
354169691Skan  private:
355169691Skan    unsigned int _M_table[55];
356169691Skan    size_t _M_index1;
357169691Skan    size_t _M_index2;
358169691Skan
359169691Skan  public:
360169691Skan    /// Returns a number less than the argument.
361169691Skan    unsigned int
362169691Skan    operator()(unsigned int __limit)
363169691Skan    {
364169691Skan      _M_index1 = (_M_index1 + 1) % 55;
365169691Skan      _M_index2 = (_M_index2 + 1) % 55;
366169691Skan      _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2];
367169691Skan      return _M_table[_M_index1] % __limit;
36897403Sobrien    }
369169691Skan
370169691Skan    void
371169691Skan    _M_initialize(unsigned int __seed)
372169691Skan    {
373169691Skan      unsigned int __k = 1;
374169691Skan      _M_table[54] = __seed;
375169691Skan      size_t __i;
376169691Skan      for (__i = 0; __i < 54; __i++)
377169691Skan	{
378169691Skan	  size_t __ii = (21 * (__i + 1) % 55) - 1;
379169691Skan	  _M_table[__ii] = __k;
380169691Skan	  __k = __seed - __k;
381169691Skan	  __seed = _M_table[__ii];
382169691Skan	}
383169691Skan      for (int __loop = 0; __loop < 4; __loop++)
384169691Skan	{
385169691Skan	  for (__i = 0; __i < 55; __i++)
38697403Sobrien            _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];
387169691Skan	}
388169691Skan      _M_index1 = 0;
389169691Skan      _M_index2 = 31;
39097403Sobrien    }
39197403Sobrien
392169691Skan    /// Ctor allowing you to initialize the seed.
393169691Skan    subtractive_rng(unsigned int __seed)
394169691Skan    { _M_initialize(__seed); }
39597403Sobrien
396169691Skan    /// Default ctor; initializes its state with some number you don't see.
397169691Skan    subtractive_rng()
398169691Skan    { _M_initialize(161803398u); }
399169691Skan  };
40097403Sobrien
401169691Skan  // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref,
402169691Skan  // provided for backward compatibility, they are no longer part of
403169691Skan  // the C++ standard.
404169691Skan  
405169691Skan  template <class _Ret, class _Tp, class _Arg>
406169691Skan    inline mem_fun1_t<_Ret, _Tp, _Arg>
407169691Skan    mem_fun1(_Ret (_Tp::*__f)(_Arg))
408169691Skan    { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
40997403Sobrien
410169691Skan  template <class _Ret, class _Tp, class _Arg>
411169691Skan    inline const_mem_fun1_t<_Ret, _Tp, _Arg>
412169691Skan    mem_fun1(_Ret (_Tp::*__f)(_Arg) const)
413169691Skan    { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
41497403Sobrien
415169691Skan  template <class _Ret, class _Tp, class _Arg>
416169691Skan    inline mem_fun1_ref_t<_Ret, _Tp, _Arg>
417169691Skan    mem_fun1_ref(_Ret (_Tp::*__f)(_Arg))
418169691Skan    { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
41997403Sobrien
420169691Skan  template <class _Ret, class _Tp, class _Arg>
421169691Skan    inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg>
422169691Skan    mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const)
423169691Skan    { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
42497403Sobrien
425169691Skan_GLIBCXX_END_NAMESPACE
426169691Skan
427132720Skan#endif
42897403Sobrien
429