//  deque : 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_DEQUE
#define __CPP_DEQUE

#include<cstddef>
#include<new>

#include<list>
#include<stdexcept>

namespace std {	
	template <class T, class Allocator = allocator<T> > 
	class deque : public list <T, Allocator>
	{
		public:
			/* inherited from list ... 

			explicit deque(const Allocator& = Allocator());
			explicit deque(size_type n, const T& value = T(), const Allocator& = Allocator());
			template <class InputIterator>
			deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
			deque(const deque<T,Allocator>& x);
			~deque();
			deque<T,Allocator>& operator=(const deque<T,Allocator>& x);
			template <class InputIterator>
			void assign(InputIterator first, InputIterator last);
			template <class Size, class T>
			void assign(Size n, const T& t = T());
			allocator_type get_allocator() const;
			iterator               begin();
			const_iterator         begin() const;
			iterator               end();
			const_iterator         end() const;
			reverse_iterator       rbegin();
			const_reverse_iterator rbegin() const;
			reverse_iterator       rend();
			const_reverse_iterator rend() const;
			size_type size() const;
			size_type max_size() const;
			void      resize(size_type sz, T c = T());
			bool      empty() const;
			
			reference       front();
			const_reference front() const;
			reference       back();
			const_reference back() const;

			void push_front(const T& x);
			void push_back(const T& x);
			
			iterator insert(iterator position, const T& x = T());
			void     insert(iterator position, size_type n, const T& x);
			
			template <class InputIterator>
			void insert (iterator position, InputIterator first, InputIterator last);
			
			void pop_front();
			void pop_back();
			
			iterator erase(iterator position);
			iterator erase(iterator first, iterator last);
			
			void     swap(deque<T,Allocator> &);
			void     clear();
			*/
			
			typedef typename Allocator::reference             reference;
			typedef typename Allocator::const_reference       const_reference;
			typedef typename list<T, Allocator>::iterator       iterator;       
			typedef typename list<T, Allocator>::const_iterator const_iterator; 
			typedef typename Allocator::size_type             size_type;
			typedef typename Allocator::difference_type       difference_type;
			typedef T                                         value_type;
			typedef Allocator                                 allocator_type;
			typedef typename Allocator::pointer               pointer;
			typedef typename Allocator::const_pointer         const_pointer;
			typedef std::reverse_iterator<iterator>           reverse_iterator;
			typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;

			reference       operator[](size_type n)
			{
				iterator i = begin();
				while (n--)
					++i;
				return *i;
			}
			
			const_reference operator[](size_type n) const
			{
				iterator i = begin();
				while (n--)
					++i;
				return *i;				
			}

			reference       at(size_type n)
			{
				if (n>size())
					throw out_of_range("out of range");
				return (*this)[n];
			}

			const_reference at(size_type n) const
			{
				if (n>size())
					throw out_of_range("out of range");
				return (*this)[n];				
			}

 	};
	
	template <class T, class Allocator>
	bool operator==(const deque<T,Allocator> &x, const deque<T,Allocator> &y)
	{
		return x.size() == y.size() && equal(x.begin(),x.end(),y.begin());
	}

	template <class T, class Allocator>
	bool operator< (const deque<T,Allocator> &x, const deque<T,Allocator> &y)
	{
		return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
	}

	template <class T, class Allocator>
	bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y)
	{
		return !(x == y);
	}

	template <class T, class Allocator>
	bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y)
	{
		return y < x;
	}

	template <class T, class Allocator>
	bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y)
	{
		return !(x < y);
	}

	template <class T, class Allocator>
	bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y)
	{
		return !(y < x);
	}

	template <class T, class Allocator>
	void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
	{
		x.swap(y);
	}

}

#endif
