
#ifndef STACK_HPP
# define STACK_HPP

# include "vector.hpp"

namespace ft {

template <
	typename T,
	typename Container = ft::vector<T>
> class stack {

public:
	typedef Container						container_type;
	typedef typename Container::value_type	value_type;
	typedef typename Container::size_type	size_type;


	/************
	 * copliens :
	 ************/
// constructors ------------------------------
	explicit stack(const container_type& cont = Container()) : c(cont) {}


	/**********************
	 * overload functions :
	 **********************/
// empty -------------------------------------
	bool				empty() const { return c.empty(); }
// size --------------------------------------
	size_type			size() const { return c.size(); }
// top ---------------------------------------
	value_type&			top() { return c.back(); }
	const value_type&	top() const { return c.back(); }
// push --------------------------------------
	void				push(const value_type& value) { c.push_back(value); }
// pop ---------------------------------------
	void				pop() { c.pop_back(); }

// Relational Operators (friend)
	template < typename T2, typename C2 >
		friend bool	operator==(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
	template < typename T2, typename C2 >
		friend bool	operator!=(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
	template < typename T2, typename C2 >
		friend bool	operator<(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
	template < typename T2, typename C2 >
		friend bool	operator>(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
	template < typename T2, typename C2 >
		friend bool	operator<=(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);
	template < typename T2, typename C2 >
		friend bool	operator>=(const stack<T2,C2>& lhs, const stack<T2,C2>& rhs);

protected:
	container_type	c;

};


	/************************
	 * non-member functions :
	 ************************/
// operator == -------------------------------
template < typename T, typename Container >
	bool	operator==(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
	{ return lhs.c == rhs.c; }
// operator != -------------------------------
template < typename T, typename Container >
	bool	operator!=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
	{ return lhs.c != rhs.c; }
// operator < --------------------------------
template < typename T, typename Container >
	bool	operator<(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
	{ return lhs.c < rhs.c; }
// operator > --------------------------------
template < typename T, typename Container >
	bool	operator>(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
	{ return lhs.c > rhs.c; }
// operator <= -------------------------------
template < typename T, typename Container >
	bool	operator<=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
	{ return lhs.c <= rhs.c; }
// operator >= -------------------------------
template < typename T, typename Container >
	bool	operator>=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
	{ return lhs.c >= rhs.c; }

} // namespace ft

#endif

