// Functional extensions -*- C++ -*-

// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.

// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.

/*
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 *
 * Copyright (c) 1996
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

/** @file ext/functional
 *  This file is a GNU extension to the Standard C++ Library (possibly
 *  containing extensions from the HP/SGI STL subset).
 */

#ifndef _EXT_FUNCTIONAL
#define _EXT_FUNCTIONAL 1

#pragma GCC system_header

#include <functional>

_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)

  using std::size_t;
  using std::unary_function;
  using std::binary_function;
  using std::mem_fun1_t;
  using std::const_mem_fun1_t;
  using std::mem_fun1_ref_t;
  using std::const_mem_fun1_ref_t;

  /** The @c identity_element functions are not part of the C++
   *  standard; SGI provided them as an extension.  Its argument is an
   *  operation, and its return value is the identity element for that
   *  operation.  It is overloaded for addition and multiplication,
   *  and you can overload it for your own nefarious operations.
   *
   *  @addtogroup SGIextensions
   *  @{
   */
  /// An \link SGIextensions SGI extension \endlink.
  template <class _Tp>
    inline _Tp
    identity_element(std::plus<_Tp>)
    { return _Tp(0); }

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Tp>
    inline _Tp
    identity_element(std::multiplies<_Tp>)
    { return _Tp(1); }
  /** @}  */
  
  /** As an extension to the binders, SGI provided composition functors and
   *  wrapper functions to aid in their creation.  The @c unary_compose
   *  functor is constructed from two functions/functors, @c f and @c g.
   *  Calling @c operator() with a single argument @c x returns @c f(g(x)).
   *  The function @c compose1 takes the two functions and constructs a
   *  @c unary_compose variable for you.
   *
   *  @c binary_compose is constructed from three functors, @c f, @c g1,
   *  and @c g2.  Its @c operator() returns @c f(g1(x),g2(x)).  The function
   *  @compose2 takes f, g1, and g2, and constructs the @c binary_compose
   *  instance for you.  For example, if @c f returns an int, then
   *  \code
   *  int answer = (compose2(f,g1,g2))(x);
   *  \endcode
   *  is equivalent to
   *  \code
   *  int temp1 = g1(x);
   *  int temp2 = g2(x);
   *  int answer = f(temp1,temp2);
   *  \endcode
   *  But the first form is more compact, and can be passed around as a
   *  functor to other algorithms.
   *
   *  @addtogroup SGIextensions
   *  @{
   */
  /// An \link SGIextensions SGI extension \endlink.
  template <class _Operation1, class _Operation2>
    class unary_compose
    : public unary_function<typename _Operation2::argument_type,
			    typename _Operation1::result_type>
    {
    protected:
      _Operation1 _M_fn1;
      _Operation2 _M_fn2;

    public:
      unary_compose(const _Operation1& __x, const _Operation2& __y)
      : _M_fn1(__x), _M_fn2(__y) {}

      typename _Operation1::result_type
      operator()(const typename _Operation2::argument_type& __x) const
      { return _M_fn1(_M_fn2(__x)); }
    };

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Operation1, class _Operation2>
    inline unary_compose<_Operation1, _Operation2>
    compose1(const _Operation1& __fn1, const _Operation2& __fn2)
    { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); }

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Operation1, class _Operation2, class _Operation3>
    class binary_compose
    : public unary_function<typename _Operation2::argument_type,
			    typename _Operation1::result_type>
    {
    protected:
      _Operation1 _M_fn1;
      _Operation2 _M_fn2;
      _Operation3 _M_fn3;
      
    public:
      binary_compose(const _Operation1& __x, const _Operation2& __y,
		     const _Operation3& __z)
      : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { }

      typename _Operation1::result_type
      operator()(const typename _Operation2::argument_type& __x) const
      { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); }
    };

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Operation1, class _Operation2, class _Operation3>
    inline binary_compose<_Operation1, _Operation2, _Operation3>
    compose2(const _Operation1& __fn1, const _Operation2& __fn2,
	     const _Operation3& __fn3)
    { return binary_compose<_Operation1, _Operation2, _Operation3>
	(__fn1, __fn2, __fn3); }
  /** @}  */

  /** As an extension, SGI provided a functor called @c identity.  When a
   *  functor is required but no operations are desired, this can be used as a
   *  pass-through.  Its @c operator() returns its argument unchanged.
   *
   *  @addtogroup SGIextensions
   */
  template <class _Tp>
    struct identity : public std::_Identity<_Tp> {};

  /** @c select1st and @c select2nd are extensions provided by SGI.  Their
   *  @c operator()s
   *  take a @c std::pair as an argument, and return either the first member
   *  or the second member, respectively.  They can be used (especially with
   *  the composition functors) to "strip" data from a sequence before
   *  performing the remainder of an algorithm.
   *
   *  @addtogroup SGIextensions
   *  @{
   */
  /// An \link SGIextensions SGI extension \endlink.
  template <class _Pair>
    struct select1st : public std::_Select1st<_Pair> {};

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Pair>
    struct select2nd : public std::_Select2nd<_Pair> {};
  /** @}  */

  // extension documented next
  template <class _Arg1, class _Arg2>
    struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1>
    {
      _Arg1
      operator()(const _Arg1& __x, const _Arg2&) const
      { return __x; }
    };

  template <class _Arg1, class _Arg2>
    struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2>
    {
      _Arg2
      operator()(const _Arg1&, const _Arg2& __y) const
      { return __y; }
    };

  /** The @c operator() of the @c project1st functor takes two arbitrary
   *  arguments and returns the first one, while @c project2nd returns the
   *  second one.  They are extensions provided by SGI.
   *
   *  @addtogroup SGIextensions
   *  @{
   */

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Arg1, class _Arg2>
    struct project1st : public _Project1st<_Arg1, _Arg2> {};

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Arg1, class _Arg2>
    struct project2nd : public _Project2nd<_Arg1, _Arg2> {};
  /** @}  */

  // extension documented next
  template <class _Result>
    struct _Constant_void_fun
    {
      typedef _Result result_type;
      result_type _M_val;

      _Constant_void_fun(const result_type& __v) : _M_val(__v) {}

      const result_type&
      operator()() const
      { return _M_val; }
    };

  template <class _Result, class _Argument>
    struct _Constant_unary_fun
    {
      typedef _Argument argument_type;
      typedef  _Result  result_type;
      result_type _M_val;
      
      _Constant_unary_fun(const result_type& __v) : _M_val(__v) {}

      const result_type&
      operator()(const _Argument&) const
      { return _M_val; }
    };

  template <class _Result, class _Arg1, class _Arg2>
    struct _Constant_binary_fun
    {
      typedef  _Arg1   first_argument_type;
      typedef  _Arg2   second_argument_type;
      typedef  _Result result_type;
      _Result _M_val;

      _Constant_binary_fun(const _Result& __v) : _M_val(__v) {}
      
      const result_type&
      operator()(const _Arg1&, const _Arg2&) const
      { return _M_val; }
    };

  /** These three functors are each constructed from a single arbitrary
   *  variable/value.  Later, their @c operator()s completely ignore any
   *  arguments passed, and return the stored value.
   *  - @c constant_void_fun's @c operator() takes no arguments
   *  - @c constant_unary_fun's @c operator() takes one argument (ignored)
   *  - @c constant_binary_fun's @c operator() takes two arguments (ignored)
   *
   *  The helper creator functions @c constant0, @c constant1, and
   *  @c constant2 each take a "result" argument and construct variables of
   *  the appropriate functor type.
   *
   *  @addtogroup SGIextensions
   *  @{
   */
  /// An \link SGIextensions SGI extension \endlink.
  template <class _Result>
    struct constant_void_fun
    : public _Constant_void_fun<_Result>
    {
      constant_void_fun(const _Result& __v)
      : _Constant_void_fun<_Result>(__v) {}
    };

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Result, class _Argument = _Result>
    struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument>
    {
      constant_unary_fun(const _Result& __v)
      : _Constant_unary_fun<_Result, _Argument>(__v) {}
    };

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1>
    struct constant_binary_fun
    : public _Constant_binary_fun<_Result, _Arg1, _Arg2>
    {
      constant_binary_fun(const _Result& __v)
      : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {}
    };

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Result>
    inline constant_void_fun<_Result>
    constant0(const _Result& __val)
    { return constant_void_fun<_Result>(__val); }

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Result>
    inline constant_unary_fun<_Result, _Result>
    constant1(const _Result& __val)
    { return constant_unary_fun<_Result, _Result>(__val); }

  /// An \link SGIextensions SGI extension \endlink.
  template <class _Result>
    inline constant_binary_fun<_Result,_Result,_Result>
    constant2(const _Result& __val)
    { return constant_binary_fun<_Result, _Result, _Result>(__val); }
  /** @}  */

  /** The @c subtractive_rng class is documented on
   *  <a href="http://www.sgi.com/tech/stl/">SGI's site</a>.
   *  Note that this code assumes that @c int is 32 bits.
   *
   *  @ingroup SGIextensions
   */
  class subtractive_rng
  : public unary_function<unsigned int, unsigned int>
  {
  private:
    unsigned int _M_table[55];
    size_t _M_index1;
    size_t _M_index2;

  public:
    /// Returns a number less than the argument.
    unsigned int
    operator()(unsigned int __limit)
    {
      _M_index1 = (_M_index1 + 1) % 55;
      _M_index2 = (_M_index2 + 1) % 55;
      _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2];
      return _M_table[_M_index1] % __limit;
    }

    void
    _M_initialize(unsigned int __seed)
    {
      unsigned int __k = 1;
      _M_table[54] = __seed;
      size_t __i;
      for (__i = 0; __i < 54; __i++)
	{
	  size_t __ii = (21 * (__i + 1) % 55) - 1;
	  _M_table[__ii] = __k;
	  __k = __seed - __k;
	  __seed = _M_table[__ii];
	}
      for (int __loop = 0; __loop < 4; __loop++)
	{
	  for (__i = 0; __i < 55; __i++)
            _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];
	}
      _M_index1 = 0;
      _M_index2 = 31;
    }

    /// Ctor allowing you to initialize the seed.
    subtractive_rng(unsigned int __seed)
    { _M_initialize(__seed); }

    /// Default ctor; initializes its state with some number you don't see.
    subtractive_rng()
    { _M_initialize(161803398u); }
  };

  // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref,
  // provided for backward compatibility, they are no longer part of
  // the C++ standard.
  
  template <class _Ret, class _Tp, class _Arg>
    inline mem_fun1_t<_Ret, _Tp, _Arg>
    mem_fun1(_Ret (_Tp::*__f)(_Arg))
    { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); }

  template <class _Ret, class _Tp, class _Arg>
    inline const_mem_fun1_t<_Ret, _Tp, _Arg>
    mem_fun1(_Ret (_Tp::*__f)(_Arg) const)
    { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); }

  template <class _Ret, class _Tp, class _Arg>
    inline mem_fun1_ref_t<_Ret, _Tp, _Arg>
    mem_fun1_ref(_Ret (_Tp::*__f)(_Arg))
    { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }

  template <class _Ret, class _Tp, class _Arg>
    inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg>
    mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const)
    { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }

_GLIBCXX_END_NAMESPACE

#endif

