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

// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009
// 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 3, 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.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/*
 *
 * 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>
#include <cstddef>

_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

