// xfunctional internal header (pre-TR1 functional) -*-c++-*-
// Copyright 2014-2017 IAR Systems AB.
#ifndef _XFUNCTIONAL_
#define _XFUNCTIONAL_

#ifndef _SYSTEM_BUILD
#pragma system_include
#endif

#include <cstdlib>
#include <xstring>
#include <xstddef>

namespace std {

// TEMPLATE STRUCT plus
// defined in <xstddef>

// TEMPLATE STRUCT minus
// defined in <xstddef>

// TEMPLATE STRUCT multiplies
// defined in <xstddef>

// TEMPLATE STRUCT divides
template<class _Ty = void>
struct divides
{	// functor for operator/
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator/ to operands
    return _Left / _Right;
  }
};

// TEMPLATE STRUCT modulus
template<class _Ty = void>
struct modulus
{	// functor for operator%
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator% to operands
    return _Left % _Right;
  }
};

// TEMPLATE STRUCT negate
template<class _Ty = void>
struct negate
{	// functor for unary operator-
  typedef _Ty argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left) const
  {	// apply operator- to operand
    return -_Left;
  }
};

// TEMPLATE STRUCT equal_to
// defined in <xstddef>

// TEMPLATE STRUCT not_equal_to
template<class _Ty = void>
struct not_equal_to
{	// functor for operator!=
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator!= to operands
    return _Left != _Right;
  }
	};

// TEMPLATE STRUCT greater
template<class _Ty = void>
struct greater
{	// functor for operator>
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator> to operands
    return _Left > _Right;
  }
};

// TEMPLATE STRUCT less
// defined in <xstddef>

// TEMPLATE STRUCT greater_equal
template<class _Ty = void>
struct greater_equal
{	// functor for operator>=
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator>= to operands
    return _Left >= _Right;
  }
};

// TEMPLATE STRUCT less_equal
template<class _Ty = void>
struct less_equal
{	// functor for operator<=
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator<= to operands
    return _Left <= _Right;
  }
};

// TEMPLATE STRUCT logical_and
template<class _Ty = void>
struct logical_and
{	// functor for operator&&
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator&& to operands
    return _Left && _Right;
  }
};

// TEMPLATE STRUCT logical_or
template<class _Ty = void>
struct logical_or
{	// functor for operator||
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator|| to operands
    return _Left || _Right;
  }
};

// TEMPLATE STRUCT logical_not
template<class _Ty = void>
struct logical_not
{	// functor for unary operator!
  typedef _Ty argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left) const
  {	// apply operator! to operand
    return !_Left;
  }
};

// TEMPLATE STRUCT bit_and
template<class _Ty = void>
struct bit_and
{	// functor for operator&
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator& to operands
    return _Left & _Right;
  }
};

// TEMPLATE STRUCT bit_or
template<class _Ty = void>
struct bit_or
{	// functor for operator|
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator| to operands
    return _Left | _Right;
  }
};

// TEMPLATE STRUCT bit_xor
template<class _Ty = void>
struct bit_xor
{	// functor for operator^
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator^ to operands
    return _Left ^ _Right;
  }
};

// TEMPLATE STRUCT bit_not
template<class _Ty = void>
struct bit_not
{	// functor for unary operator~
  typedef _Ty argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left) const
  {	// apply operator~ to operand
    return ~_Left;
  }
};

// TEMPLATE STRUCT SPECIALIZATION plus
// defined in <xstddef>

// TEMPLATE STRUCT SPECIALIZATION minus
// defined in <xstddef>

// TEMPLATE STRUCT SPECIALIZATION multiplies
// defined in <xstddef>

// TEMPLATE STRUCT SPECIALIZATION divides
template<>
struct divides<void>
{       // transparent functor for operator/
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) / std::forward<_Ty2>(_Right))
  {       // transparently apply operator/ to operands
    return std::forward<_Ty1>(_Left) / std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION modulus
template<>
struct modulus<void>
{       // transparent functor for operator%
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) % std::forward<_Ty2>(_Right))
  {       // transparently apply operator% to operands
    return std::forward<_Ty1>(_Left) % std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION negate
template<>
struct negate<void>
{       // transparent functor for unary operator-
  typedef _Is_trans is_transparent;

  template<class _Ty>
  constexpr auto operator()(_Ty&& _Left) const
    -> decltype(-std::forward<_Ty>(_Left))
  {       // transparently apply operator- to operand
    return -std::forward<_Ty>(_Left);
  }
};

// TEMPLATE STRUCT SPECIALIZATION equal_to
// defined in <xstddef>

// TEMPLATE STRUCT SPECIALIZATION not_equal_to
template<>
struct not_equal_to<void>
{       // transparent functor for operator!=
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) != std::forward<_Ty2>(_Right))
  {       // transparently apply operator!= to operands
    return std::forward<_Ty1>(_Left) != std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION greater
template<>
struct greater<void>
{       // transparent functor for operator>
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) > std::forward<_Ty2>(_Right))
  {       // transparently apply operator> to operands
    return std::forward<_Ty1>(_Left) > std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION less
// defined in <xstddef>

// TEMPLATE STRUCT SPECIALIZATION greater_equal
template<>
struct greater_equal<void>
{       // transparent functor for operator>=
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) >= std::forward<_Ty2>(_Right))
  {       // transparently apply operator>= to operands
    return std::forward<_Ty1>(_Left) >= std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION less_equal
template<>
struct less_equal<void>
{       // transparent functor for operator<=
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) <= std::forward<_Ty2>(_Right))
  {       // transparently apply operator<= to operands
    return std::forward<_Ty1>(_Left) <= std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION logical_and
template<>
struct logical_and<void>
{       // transparent functor for operator&&
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) && std::forward<_Ty2>(_Right))
  {       // transparently apply operator&& to operands
    return std::forward<_Ty1>(_Left) && std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION logical_or
template<>
struct logical_or<void>
{       // transparent functor for operator||
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) || std::forward<_Ty2>(_Right))
  {       // transparently apply operator|| to operands
    return std::forward<_Ty1>(_Left) || std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION logical_not
template<>
struct logical_not<void>
{       // transparent functor for unary operator!
  typedef _Is_trans is_transparent;

  template<class _Ty>
  constexpr auto operator()(_Ty&& _Left) const
    -> decltype(!std::forward<_Ty>(_Left))
  {       // transparently apply operator! to operand
    return !std::forward<_Ty>(_Left);
  }
};

// TEMPLATE STRUCT SPECIALIZATION bit_and
template<>
struct bit_and<void>
{       // transparent functor for operator&
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) & std::forward<_Ty2>(_Right))
  {       // transparently apply operator& to operands
    return std::forward<_Ty1>(_Left) & std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION bit_or
template<>
struct bit_or<void>
{       // transparent functor for operator|
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) | std::forward<_Ty2>(_Right))
  {       // transparently apply operator| to operands
    return std::forward<_Ty1>(_Left) | std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION bit_xor
template<>
struct bit_xor<void>
{       // transparent functor for operator^
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(std::forward<_Ty1>(_Left) ^ std::forward<_Ty2>(_Right))
  {       // transparently apply operator^ to operands
    return std::forward<_Ty1>(_Left) ^ std::forward<_Ty2>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION bit_not
template<>
struct bit_not<void>
{       // transparent functor for unary operator~
  typedef _Is_trans is_transparent;

  template<class _Ty>
  constexpr auto operator()(_Ty&& _Left) const
    -> decltype(~std::forward<_Ty>(_Left))
  {       // transparently apply operator~ to operand
    return ~std::forward<_Ty>(_Left);
  }
};

// TEMPLATE CLASS unary_negate
template<class _Fn1>
class unary_negate
{       // functor adapter !_Func(left)
public:
  typedef typename _Fn1::argument_type argument_type;
  typedef bool result_type;

  constexpr explicit unary_negate(const _Fn1& _Func)
    : _Functor(_Func)
  {       // construct from functor
  }

  constexpr bool operator()(const argument_type& _Left) const
  {       // apply functor to operand
    return !_Functor(_Left);
  }

private:
  _Fn1 _Functor;  // the functor to apply
};

// TEMPLATE FUNCTION not1
template<class _Fn1> inline
constexpr unary_negate<_Fn1> not1(const _Fn1& _Func)
{       // return a unary_negate functor adapter
  return unary_negate<_Fn1>(_Func);
}

// TEMPLATE CLASS binary_negate
template<class _Fn2>
class binary_negate
{       // functor adapter !_Func(left, right)
public:
  typedef typename _Fn2::first_argument_type first_argument_type;
  typedef typename _Fn2::second_argument_type second_argument_type;
  typedef bool result_type;

  constexpr explicit binary_negate(const _Fn2& _Func)
    : _Functor(_Func)
  {       // construct from functor
  }

  constexpr bool operator()(const first_argument_type& _Left,
                            const second_argument_type& _Right) const
  {       // apply functor to operands
    return !_Functor(_Left, _Right);
  }

private:
  _Fn2 _Functor;  // the functor to apply
};

// TEMPLATE FUNCTION not2
template<class _Fn2> inline
constexpr binary_negate<_Fn2> not2(const _Fn2& _Func)
{       // return a binary_negate functor adapter
  return binary_negate<_Fn2>(_Func);
}

// TEMPLATE CLASS binder1st
template<class _Fn2>
class binder1st
  : public unary_function<typename _Fn2::second_argument_type,
                          typename _Fn2::result_type>
{       // functor adapter _Func(stored, right)
public:
  typedef unary_function<typename _Fn2::second_argument_type,
                         typename _Fn2::result_type> _Base;
  typedef typename _Base::argument_type argument_type;
  typedef typename _Base::result_type result_type;

  binder1st(const _Fn2& _Func,
            const typename _Fn2::first_argument_type& _Left)
    : op(_Func), value(_Left)
  {       // construct from functor and left operand
  }

  result_type operator()(const argument_type& _Right) const
  {       // apply functor to operands
    return op(value, _Right);
  }

  result_type operator()(argument_type& _Right) const
  {       // apply functor to operands
    return op(value, _Right);
  }

protected:
  _Fn2 op;        // the functor to apply
  typename _Fn2::first_argument_type value;       // the left operand
};

// TEMPLATE FUNCTION bind1st
template<class _Fn2,
         class _Ty> inline
binder1st<_Fn2> bind1st(const _Fn2& _Func, const _Ty& _Left)
{       // return a binder1st functor adapter
  typename _Fn2::first_argument_type _Val(_Left);
  return binder1st<_Fn2>(_Func, _Val);
}

// TEMPLATE CLASS binder2nd
template<class _Fn2>
class binder2nd
  : public unary_function<typename _Fn2::first_argument_type,
                          typename _Fn2::result_type>
{       // functor adapter _Func(left, stored)
public:
  typedef unary_function<typename _Fn2::first_argument_type,
                         typename _Fn2::result_type> _Base;
  typedef typename _Base::argument_type argument_type;
  typedef typename _Base::result_type result_type;

  binder2nd(const _Fn2& _Func,
            const typename _Fn2::second_argument_type& _Right)
    : op(_Func), value(_Right)
  {       // construct from functor and right operand
  }

  result_type operator()(const argument_type& _Left) const
  {       // apply functor to operands
    return op(_Left, value);
  }

  result_type operator()(argument_type& _Left) const
  {       // apply functor to operands
    return op(_Left, value);
  }

protected:
  _Fn2 op;        // the functor to apply
  typename _Fn2::second_argument_type value;      // the right operand
};

// TEMPLATE FUNCTION bind2nd
template<class _Fn2,
         class _Ty> inline
binder2nd<_Fn2> bind2nd(const _Fn2& _Func, const _Ty& _Right)
{       // return a binder2nd functor adapter
  typename _Fn2::second_argument_type _Val(_Right);
  return binder2nd<_Fn2>(_Func, _Val);
}

// TEMPLATE CLASS pointer_to_unary_function
template<class _Arg,
         class _Result>
class pointer_to_unary_function
  : public unary_function<_Arg, _Result>
{       // functor adapter (*pfunc)(left)
public:
  explicit pointer_to_unary_function(_Result (*_Left)(_Arg))
  : _Pfun(_Left)
  {       // construct from pointer
  }

  _Result operator()(_Arg _Left) const
  {       // call function with operand
    return _Pfun(_Left);
  }

protected:
  _Result (*_Pfun)(_Arg); // the function pointer
};

// TEMPLATE CLASS pointer_to_binary_function
template<class _Arg1,
         class _Arg2,
         class _Result>
class pointer_to_binary_function
  : public binary_function<_Arg1, _Arg2, _Result>
{       // functor adapter (*pfunc)(left, right)
public:
  explicit pointer_to_binary_function(
    _Result (*_Left)(_Arg1, _Arg2))
  : _Pfun(_Left)
  {       // construct from pointer
  }

  _Result operator()(_Arg1 _Left, _Arg2 _Right) const
  {       // call function with operands
    return _Pfun(_Left, _Right);
  }

protected:
  _Result (*_Pfun)(_Arg1, _Arg2); // the function pointer
};

// TEMPLATE FUNCTION ptr_fun
template<class _Arg,
         class _Result> inline
pointer_to_unary_function<_Arg, _Result>
ptr_fun(_Result (*_Left)(_Arg))
{       // return pointer_to_unary_function functor adapter
  return pointer_to_unary_function<_Arg, _Result>(_Left);
}

template<class _Arg1,
         class _Arg2,
         class _Result> inline
pointer_to_binary_function<_Arg1, _Arg2, _Result>
ptr_fun(_Result (*_Left)(_Arg1, _Arg2))
{       // return pointer_to_binary_function functor adapter
  return pointer_to_binary_function<_Arg1, _Arg2, _Result>(_Left);
}

// TEMPLATE CLASS mem_fun_t
template<class _Result,
         class _Ty>
class mem_fun_t
  : public unary_function<_Ty *, _Result>
{       // functor adapter (*p->*pfunc)(), non-const *pfunc
public:
  explicit mem_fun_t(_Result (_Ty::*_Pm)())
  : _Pmemfun(_Pm)
  {       // construct from pointer
  }

  _Result operator()(_Ty *_Pleft) const
  {       // call function
    return (_Pleft->*_Pmemfun)();
  }

private:
  _Result (_Ty::*_Pmemfun)();     // the member function pointer
};

// TEMPLATE CLASS mem_fun1_t
template<class _Result,
         class _Ty,
         class _Arg>
class mem_fun1_t
  : public binary_function<_Ty *, _Arg, _Result>
{       // functor adapter (*p->*pfunc)(val), non-const *pfunc
public:
  explicit mem_fun1_t(_Result (_Ty::*_Pm)(_Arg))
  : _Pmemfun(_Pm)
  {       // construct from pointer
  }

  _Result operator()(_Ty *_Pleft, _Arg _Right) const
  {       // call function with operand
    return (_Pleft->*_Pmemfun)(_Right);
  }

private:
  _Result (_Ty::*_Pmemfun)(_Arg); // the member function pointer
};

// TEMPLATE CLASS const_mem_fun_t
template<class _Result,
         class _Ty>
class const_mem_fun_t
  : public unary_function<const _Ty *, _Result>
{       // functor adapter (*p->*pfunc)(), const *pfunc
public:
  explicit const_mem_fun_t(_Result (_Ty::*_Pm)() const)
  : _Pmemfun(_Pm)
  {       // construct from pointer
  }

  _Result operator()(const _Ty *_Pleft) const
  {       // call function
    return (_Pleft->*_Pmemfun)();
  }

private:
  _Result (_Ty::*_Pmemfun)() const;       // the member function pointer
};

// TEMPLATE CLASS const_mem_fun1_t
template<class _Result,
         class _Ty,
         class _Arg>
class const_mem_fun1_t
  : public binary_function<const _Ty *, _Arg, _Result>
{       // functor adapter (*p->*pfunc)(val), const *pfunc
public:
  explicit const_mem_fun1_t(_Result (_Ty::*_Pm)(_Arg) const)
  : _Pmemfun(_Pm)
  {       // construct from pointer
  }

  _Result operator()(const _Ty *_Pleft, _Arg _Right) const
  {       // call function with operand
    return (_Pleft->*_Pmemfun)(_Right);
  }

private:
  _Result (_Ty::*_Pmemfun)(_Arg) const;   // the member function pointer
};

// TEMPLATE FUNCTION mem_fun
template<class _Result,
         class _Ty> inline
mem_fun_t<_Result, _Ty> mem_fun(_Result (_Ty::*_Pm)())
{       // return a mem_fun_t functor adapter
  return mem_fun_t<_Result, _Ty>(_Pm);
}

template<class _Result,
         class _Ty,
         class _Arg> inline
mem_fun1_t<_Result, _Ty, _Arg> mem_fun(_Result (_Ty::*_Pm)(_Arg))
{       // return a mem_fun1_t functor adapter
  return mem_fun1_t<_Result, _Ty, _Arg>(_Pm);
}

template<class _Result,
         class _Ty> inline
const_mem_fun_t<_Result, _Ty>
mem_fun(_Result (_Ty::*_Pm)() const)
{       // return a const_mem_fun_t functor adapter
  return const_mem_fun_t<_Result, _Ty>(_Pm);
}

template<class _Result,
         class _Ty,
         class _Arg> inline
const_mem_fun1_t<_Result, _Ty, _Arg>
mem_fun(_Result (_Ty::*_Pm)(_Arg) const)
{       // return a const_mem_fun1_t functor adapter
  return const_mem_fun1_t<_Result, _Ty, _Arg>(_Pm);
}

// TEMPLATE FUNCTION mem_fun1 (retained)
template<class _Result,
         class _Ty,
         class _Arg> inline
mem_fun1_t<_Result, _Ty, _Arg> mem_fun1(_Result (_Ty::*_Pm)(_Arg))
{       // return a mem_fun1_t functor adapter
  return mem_fun1_t<_Result, _Ty, _Arg>(_Pm);
}

// TEMPLATE CLASS mem_fun_ref_t
template<class _Result,
         class _Ty>
class mem_fun_ref_t
  : public unary_function<_Ty, _Result>
{       // functor adapter (*left.*pfunc)(), non-const *pfunc
public:
  explicit mem_fun_ref_t(_Result (_Ty::*_Pm)())
  : _Pmemfun(_Pm)
  {       // construct from pointer
  }

  _Result operator()(_Ty& _Left) const
  {       // call function
    return (_Left.*_Pmemfun)();
  }

private:
  _Result (_Ty::*_Pmemfun)();     // the member function pointer
};

// TEMPLATE CLASS mem_fun1_ref_t
template<class _Result,
         class _Ty,
         class _Arg>
class mem_fun1_ref_t
  : public binary_function<_Ty, _Arg, _Result>
{       // functor adapter (*left.*pfunc)(val), non-const *pfunc
public:
  explicit mem_fun1_ref_t(_Result (_Ty::*_Pm)(_Arg))
  : _Pmemfun(_Pm)
  {       // construct from pointer
  }

  _Result operator()(_Ty& _Left, _Arg _Right) const
  {       // call function with operand
    return (_Left.*_Pmemfun)(_Right);
  }

private:
  _Result (_Ty::*_Pmemfun)(_Arg); // the member function pointer
};

// TEMPLATE CLASS const_mem_fun_ref_t
template<class _Result,
         class _Ty>
class const_mem_fun_ref_t
  : public unary_function<_Ty, _Result>
{       // functor adapter (*left.*pfunc)(), const *pfunc
public:
  explicit const_mem_fun_ref_t(_Result (_Ty::*_Pm)() const)
  : _Pmemfun(_Pm)
  {       // construct from pointer
  }

  _Result operator()(const _Ty& _Left) const
  {       // call function
    return (_Left.*_Pmemfun)();
  }

private:
  _Result (_Ty::*_Pmemfun)() const;       // the member function pointer
};

// TEMPLATE CLASS const_mem_fun1_ref_t
template<class _Result,
         class _Ty,
         class _Arg>
class const_mem_fun1_ref_t
  : public binary_function<_Ty, _Arg, _Result>
{       // functor adapter (*left.*pfunc)(val), const *pfunc
public:
  explicit const_mem_fun1_ref_t(_Result (_Ty::*_Pm)(_Arg) const)
  : _Pmemfun(_Pm)
  {       // construct from pointer
  }

  _Result operator()(const _Ty& _Left, _Arg _Right) const
  {       // call function with operand
    return (_Left.*_Pmemfun)(_Right);
  }

private:
  _Result (_Ty::*_Pmemfun)(_Arg) const;   // the member function pointer
};

// TEMPLATE FUNCTION mem_fun_ref
template<class _Result,
         class _Ty> inline
mem_fun_ref_t<_Result, _Ty> mem_fun_ref(_Result (_Ty::*_Pm)())
{       // return a mem_fun_ref_t functor adapter
  return mem_fun_ref_t<_Result, _Ty>(_Pm);
}

template<class _Result,
         class _Ty,
         class _Arg> inline
mem_fun1_ref_t<_Result, _Ty, _Arg>
mem_fun_ref(_Result (_Ty::*_Pm)(_Arg))
{       // return a mem_fun1_ref_t functor adapter
  return mem_fun1_ref_t<_Result, _Ty, _Arg>(_Pm);
}

template<class _Result,
         class _Ty> inline
const_mem_fun_ref_t<_Result, _Ty>
mem_fun_ref(_Result (_Ty::*_Pm)() const)
{       // return a const_mem_fun_ref_t functor adapter
  return const_mem_fun_ref_t<_Result, _Ty>(_Pm);
}

template<class _Result,
         class _Ty,
         class _Arg> inline
const_mem_fun1_ref_t<_Result, _Ty, _Arg>
mem_fun_ref(_Result (_Ty::*_Pm)(_Arg) const)
{       // return a const_mem_fun1_ref_t functor adapter
  return const_mem_fun1_ref_t<_Result, _Ty, _Arg>(_Pm);
}

// TEMPLATE FUNCTION mem_fun1_ref (retained)
template<class _Result,
         class _Ty,
         class _Arg> inline
mem_fun1_ref_t<_Result, _Ty, _Arg> mem_fun1_ref(_Result (_Ty::*_Pm)(_Arg))
{       // return a mem_fun1_ref_t functor adapter
  return mem_fun1_ref_t<_Result, _Ty, _Arg>(_Pm);
}

// TEMPLATE STRUCT project1st
template<class _Arg1,
         class _Arg2>
struct project1st
  : public binary_function<_Arg1, _Arg2, _Arg1>
{	// functor for binary first of two arg selector operator
  _Arg1 operator()(const _Arg1& _Left, const _Arg2&) const
  {	// apply first selector operator to two operands
    return _Left;
  }
};

// TEMPLATE STRUCT project2nd
template<class _Arg1,
         class _Arg2>
struct project2nd
  : public binary_function<_Arg1, _Arg2, _Arg2>
{	// functor for binary second of two arg selector operator
  _Arg2 operator()(const _Arg1&, const _Arg2& _Right) const
  {	// apply second selector operator to two operands
    return _Right;
  }
};

// TEMPLATE STRUCT select1st
template<class _Pair>
struct select1st
  : public unary_function<_Pair, typename _Pair::first_type>
{	// functor for unary first of pair selector operator
  const typename _Pair::first_type& operator()(const _Pair& _Left) const
  {	// apply first selector operator to pair operand
    return _Left.first;
  }
};

// TEMPLATE STRUCT select2nd
template<class _Pair>
struct select2nd
  : public unary_function<_Pair, typename _Pair::second_type>
{	// functor for unary second of pair selector operator
  const typename _Pair::second_type& operator()(const _Pair& _Left) const
  {	// apply second selector operator to pair operand
    return _Left.second;
  }
};

// TEMPLATE CLASS unary_compose
template<class _Fn1,
         class _Fn2>
class unary_compose
  : public unary_function<typename _Fn2::argument_type,
                          typename _Fn1::result_type>
{	// functor for f1(f2(x))
public:
  unary_compose(const _Fn1& _Func1, const _Fn2& _Func2)
    : _Functor1(_Func1), _Functor2(_Func2)
  {	// construct from functors
  }

  typename _Fn1::result_type operator()(
    const typename _Fn2::argument_type& _Left) const
  {	// apply functors to operand
    return _Functor1(_Functor2(_Left));
  }

protected:
  _Fn1 _Functor1;
  _Fn2 _Functor2;
};

// TEMPLATE FUNCTION compose1
template<class _Fn1,
         class _Fn2> inline
unary_compose<_Fn1, _Fn2> compose1(const _Fn1& _Func1,
                                   const _Fn2& _Func2)
{	// return a unary_compose<_Fn1, _Fn2> functor adapter
  return unary_compose<_Fn1, _Fn2>(_Func1, _Func2);
}

// TEMPLATE CLASS binary_compose
template<class _Fn1,
         class _Fn2,
         class _Fn3>
class binary_compose
  : public unary_function<typename _Fn2::argument_type,
                          typename _Fn1::result_type>
{	// functor for f1(f2(x), f3(x))
public:
  binary_compose(const _Fn1& _Func1, const _Fn2& _Func2, const _Fn3& _Func3)
    : _Functor1(_Func1), _Functor2(_Func2), _Functor3(_Func3)
  {	// construct from functors
  }

  typename _Fn1::result_type operator()(
    const typename _Fn2::argument_type& _Left) const
  {	// apply functors to operand
    return _Functor1(_Functor2(_Left), _Functor3(_Left));
  }

protected:
  _Fn1 _Functor1;
  _Fn2 _Functor2;
  _Fn3 _Functor3;
};

// TEMPLATE FUNCTION compose2
template<class _Fn1,
         class _Fn2,
         class _Fn3> inline
binary_compose<_Fn1, _Fn2, _Fn3> compose2(const _Fn1& _Func1,
                                          const _Fn2& _Func2,
                                          const _Fn3& _Func3)
{	// return a binary_compose<_Fn1, _Fn2, _Fn3> functor adapter
  return binary_compose<_Fn1, _Fn2, _Fn3>(_Func1, _Func2, _Func3);
}

} /* namespace std */

#endif /* _XFUNCTIONAL_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:0576 */
