//
// C++ Interface: extalgorithm
//
// Description: 
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef __EXTALGORITHM_2004_06_22
#define __EXTALGORITHM_2004_06_22

#include <algorithm>
#include <functional>

namespace NExtStd
{

 /**
	*  @brief Apply a function to every element of a sequence.
	*  @param  __first  An input iterator.
	*  @param  __last   An input iterator.
	*  @param  __f      A unary method function object.
	*  @param o  the class the method should be called for
	*  @return   @p f.
	*
	*  Applies the function object @p f to each element in the range
	*  @p [first,last).  @p f must not modify the order of the sequence.
	*  If @p f has a return value it is ignored.
	* @note this function is based on the GNU libcpp foreach function. 
	*/
template<typename _InputIter, typename _Function, typename Object>
_Function
for_each_ref(_InputIter __first, _InputIter __last, _Function __f, Object& o)
{
	// concept requirements
//	__glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
	for ( ; __first != __last; ++__first)
		(o.*__f)(*__first);
	return __f;
}

template<typename _InputIter, typename _Function, typename Object>
_Function
for_each(_InputIter __first, _InputIter __last, _Function __f, Object* o)
{
	// concept requirements
//	__glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
	for ( ; __first != __last; ++__first)
		(o->*__f)(*__first);
	return __f;
}


/** Copy algorithm as taken from Stroustrup2000 (Fourth Edition) page 566 (german translation)
  */
template <class In, class Out, class Pred>
Out copy_if(In anf, In end, Out res, Pred p)
{
	while (anf!=end)
	{
		if (p(*anf)) *res++ = *anf;
		++anf;
	}
	return res;
}

}	// namespace NExtStd


namespace std	// add some neccessary partial specilisations
{

/** Partial specialisation allowing handing parameters by reference.
  *
  * See: Adapters and Binders - Overcoming problems in the design and implementation of the C++-STL
  * Volker Simonis1 
  * Universität Tübingen
  * @author Volker Simonis1
  * Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds. 
  * Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney. 
  */
template <class Arg1, class Arg2, class Result>
struct binary_function<Arg1, Arg2&, Result> {
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
};

}	// namespace std

#endif	// __EXTALGORITHM_2004_06_22
