#ifndef __ALGORITHM_AMV
	#define __ALGORITHM_AMV

#include <iostream>
#include "amvdefs.h"

namespace amv	{

template <class type>
inline void swap(type &a, type &b)
{
type temp(a);
a=b;
b=temp;
}

template <class container>
inline void fill(container &c, const typename container::value_type &value)
{
typename container::iterator it(c.begin());
for(; it!=c.end(); ++it)
	{
	*it=value;
	}
}

template <class container>
inline int count(const container &c, const typename container::value_type &value)
{
int matchs=0;
typename container::const_iterator it(c.begin());

for(; it!=c.end(); ++it)
	if(*it==value)
		{
		++matchs;
		}

return matchs;
}

template <class container>
inline container::size_type findIndex(container &c, const typename container::value_type &value)
{
typename container::iterator it(c.begin());
typename container::size_type pos=c.size(), temp=0;

for(; it!=c.end(); ++it, ++temp)
	if(*it==value)
		{
		pos=temp;
		break;
		}

return pos;
}

template <class container>
inline container::iterator find(container &c, const typename container::value_type &value)
{
typename container::iterator it(c.begin()), itFound(c.end());

for(; it!=c.end(); ++it)
	if(*it==value)
		{
		itFound=it;
		break;
		}

return itFound;
}

template <class container>
inline container::iterator find_last(container &c, const typename container::value_type &value)
{
typename container::reverse_iterator it(c.rbegin());
typename container::iterator itFound(c.end());

for(; it!=c.rend(); ++it)
	if(*it==value)
		{
		itFound=it.base();
		break;
		}

return itFound;
}

template <class container>
inline container::const_iterator find(const container &c, const typename container::value_type &value)
{
typename container::const_iterator it(c.begin()), itFound(c.end());

for(; it!=c.end(); ++it)
	if(*it==value)
		{
		itFound=it;
		break;
		}

return itFound;
}

template <class container>
inline container::const_iterator find_last(const container &c, const typename container::value_type &value)
{
typename container::const_reverse_iterator it(c.rbegin());
typename container::const_iterator itFound(c.end());

for(; it!=c.rend(); ++it)
	if(*it==value)
		{
		itFound=it.base();
		break;
		}

return itFound;
}

template <class it, class type>
inline it find(it begin, it end, type t)
{
while(begin!=end)
	{
	if(*begin==t)
		break;
	++begin;
	}

return begin;
}

template <class container>
void dump_container(const container &c, ostream &os, char delim=' ')
{
typename container::const_iterator it(c.begin());

for(; it!=c.end(); ++it)
	os<<*it<<delim;
}

template <class container>
void extract_container(container &c, istream &is)
{
typename container::iterator it(c.begin());

for(; it!=c.end(); ++it)
	is>>*it;
}

template <class II, class OI>
void copy(II begin, II end, OI target)
{
for(; begin!=end; ++begin)
	{
	*target=*begin;
	++target;
	}
}

template <class it1, class it2>
bool equal(it1 begin1, it1 end1, it2 begin2)
{
while(begin1!=end1 && *begin1==*begin2)
	{
	++begin1;
	++begin2;
	}

if(begin1==end1)
	return true;

return false;
}

template <class II>
void sort(II begin, II end)
{
for(; begin!=end; ++begin)
	{
	II it(begin);
	++it;
	for(; it!=end; ++it)
		{
		if((*it)<(*begin))
			swap(*it,*begin);
		}
	}
}

template <class II, class F>
void sort(II begin, II end, F f)
{
for(; begin!=end; ++begin)
	{
	II it(begin);
	++it;
	for(; it!=end; ++it)
		{
		if(f(*it,*begin))
			swap(*it,*begin);
		}
	}
}

}

#endif