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

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

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  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 @a 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 @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_VERSION
} // namespace

#endif

