//  queue : headerfile for the free standard C++ library
//  
//  Copyright (C) 1999 by the free standard C++ Library Team
//                        see AUTHORS for more details
//
//  Homepage : http://www.inf.fu-berlin.de/~mkrueger/fscl/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either	
//  version 2 of the License, 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
//  Library General Public License for more details.
//  You should have received a copy of the GNU Library General Public
//  License along with this library; if not, write to the Free
//  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//  version : 0.1 last modified : 17.09.99

#ifndef __CPP_QUEUE
#define __CPP_QUEUE

#include<functional>
#include<deque>
#include<vector>
#include<algorithm>

namespace std {

	// 23.2.3.1 Template class queue
	template <class T, class Container = deque<T> >
	class queue
	{
		protected:
			Container c;

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

			explicit queue(const Container& con = Container()) 
			: c(con)
			{
			}

			bool      empty() const
			{
				return c.empty();
			}
			size_type size() const 
			{
				return c.size();
			}
			value_type& front()
			{
				return c.front();
			}
			const value_type& front() const
			{
				return c.front();
			}
			value_type& back()
			{
				return c.back();
			}
			const value_type& back() const
			{
				return c.back();
			}
			void push(const value_type& x)
			{
				c.push_back(x);
			}
			void pop()
			{
				c.pop_front();
			}
	};

	template <class T, class Container>
	inline bool operator==(const queue<T, Container>& x, const queue<T, Container>& y)
	{
		return x.c == y.c;
	}

	template <class T, class Container>
	inline bool operator< (const queue<T, Container>& x, const queue<T, Container>& y)	
	{
		return x.c < y.c;
	}

	template <class T, class Container>
	inline bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y)
	{
		return x.c != y.c;
	}

	template <class T, class Container>
	inline bool operator> (const queue<T, Container>& x, const queue<T, Container>& y)
	{
		return x.c > y.c;
	}

	template <class T, class Container>
	inline bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y)
	{
		return x.c >= y.c;
	}

	template <class T, class Container>
	inline bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y)
	{
		return x.c <= y.c;
	}

	// 23.2.3.2 Template class priority_queue
	template <class T, class Container = vector<T>, class Compare = less<typename Container::value_type> >
	class priority_queue
	{
		protected:
			Container c;
			Compare comp;

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

			// 23.2.3.2.1 priority_queue constructors
			explicit priority_queue(const Compare& x = Compare(), const Container& y = Container())
			: comp(x), c(y)
			{
				make_heap(c.begin(), c.end(), comp);
			}

			template <class InputIterator>
			priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare(), const Container& y = Container())
			: comp(x), c(y)
			{
				c.insert(c.end(), first, last);
				make_heap(c.begin(), c.end(), comp);
			}

			bool      empty() const
			{
				return c.empty();
			}

			size_type size()  const
			{
				return c.size();
			}

			const value_type& top() const
			{
				return c.front();
			}

			// 23.2.3.2.2 priority_queue members
			void push(const value_type& x)
			{
				c.push_back(x);
				push_heap(c.begin(), c.end(), comp);
			}

			void pop()
			{
				pop_heap(c.begin(), c.end(), comp);
				c.pop_back();
			}
	};
}
#endif
