/*  Metrowerks Standard Library  Version 4.0  1998 August 10  */

/*  $Date: 1998/12/04 23:58:22 $ 
 *  $Revision: 1.2 $ 
 *  $NoKeywords: $ 
 *
 *		Portions Copyright  1995-1998 Metrowerks, Inc.
 *		All rights reserved.
 */

/**
 **  queue
 **/

#ifndef _QUEUE
#define _QUEUE

#include <mcompile.h>
#include <deque>
#include <vector>
#include <algorithm>
#include <functional>

#ifndef RC_INVOKED

#pragma options align=native
#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
	#pragma import on
#endif

#ifdef MSIPL_USING_NAMESPACE
	namespace std {
#endif

template <class T, class Container = deque<T> >
class queue
{
public:
	typedef typename Container::value_type            value_type;
	typedef typename Container::size_type             size_type;
	typedef          Container                        container_type;

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

	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(); }

protected:
	Container c;

	friend bool operator== <T, Container>(const queue<T, Container>& x, const queue<T, Container>& y);
	friend bool operator!= <T, Container>(const queue<T, Container>& x, const queue<T, Container>& y);
	friend bool operator<  <T, Container>(const queue<T, Container>& x, const queue<T, Container>& y);
	friend bool operator<= <T, Container>(const queue<T, Container>& x, const queue<T, Container>& y);
	friend bool operator>  <T, Container>(const queue<T, Container>& x, const queue<T, Container>& y);
	friend bool operator>= <T, Container>(const queue<T, Container>& x, const queue<T, Container>& y);
};

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;
}

template <class T, class Container = vector<T>,
          class Compare = less<typename Container::value_type> >
class priority_queue
{
public:
	typedef typename Container::value_type            value_type;
	typedef typename Container::size_type             size_type;
	typedef          Container                        container_type;

	explicit priority_queue(const Compare& x = Compare(), const Container& = Container());
	#ifdef MSIPL_MEMBER_TEMPLATE
		template <class InputIterator>
			priority_queue(InputIterator first, InputIterator last,
				const Compare& x = Compare(), const Container& y = Container())
				: c(y),
				  comp(x)
			{
				c.insert(c.end(), first, last);
				make_heap(c.begin(), c.end(), comp);
			}
	#else
		priority_queue(typename Container::const_iterator first, typename Container::const_iterator last,
				const Compare& x = Compare(), const Container& y = Container());
	#endif

	bool      empty() const       { return c.empty(); }
	size_type size()  const       { return c.size(); }
	const value_type& top() const { return c.front(); }
	void push(const value_type& x);
	void pop();
protected:
	Container c;
	Compare comp;
};

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

#ifndef MSIPL_MEMBER_TEMPLATE

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

#endif

template <class T, class Container, class Compare>
void
priority_queue<T, Container, Compare>::push(const value_type& x)
{
	c.push_back(x);
	push_heap(c.begin(), c.end(), comp);
}

template <class T, class Container, class Compare>
void
priority_queue<T, Container, Compare>::pop()
{
	pop_heap(c.begin(), c.end(), comp);
	c.pop_back();
}

#ifdef MSIPL_USING_NAMESPACE
	} // namespace std
#endif

#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
	#pragma import reset
#endif
#pragma options align=reset

#endif // RC_INVOKED

#endif // _QUEUE

// hh 971220 fixed MOD_INCLUDE
// hh 971223 Changed filename from queue.h to queue
// hh 971223 Made include guards standard
// hh 971223 added alignment wrapper
// hh 971229 added <deque>
// hh 971229 added <vector>
// hh 971230 added RC_INVOKED wrapper
// hh 980111 removed <functional>.  Not needed.
// hh 980113 Updated friend syntax of global methods and moved out of template definition.
// hh 980902 #ifdef'd out exception code when ndef MSIPL_EXCEPT
// hh 981129 Rewrote
