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

/*  $Date: 1998/12/11 19:09:08 $ 
 *  $Revision: 1.3 $ 
 *  $NoKeywords: $ 
 *
 *		Portions Copyright  1995-1998 Metrowerks, Inc.
 *		All rights reserved.
 */

/**
 ** deque
 **/

#ifndef _DEQUE
#define _DEQUE

#include <mcompile.h>

#include <iterator>
#include <new>
#include <memory>
#include <algorithm>
#include <limits>
#include <cdeque>

#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 Allocator = allocator<T> >
class deque
{
	#ifdef MSIPL_MEMBER_TEMPLATE
		template <bool b> struct chooser {};
	#endif
public:
	// types:
	typedef typename Allocator::reference         reference;
	typedef typename Allocator::const_reference   const_reference;
	class                                         iterator;
	class                                         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;

	friend class iterator;
	class iterator
		: public _STD::iterator<random_access_iterator_tag, T, difference_type, pointer, reference>
	{
	public:
		iterator() {}
		reference operator * () const {return *(deq_->buf_[pos_ / deq_->alloc_.m_] + pos_ % deq_->alloc_.m_);}
		pointer operator -> () const {return deq_->buf_[pos_ / deq_->alloc_.m_] + pos_ % deq_->alloc_.m_;}
		iterator& operator ++ () {++pos_; return *this;}
		iterator operator ++ (int) {iterator tmp(*this); ++pos_; return tmp;}
		iterator& operator -- () {--pos_; return *this;}
		iterator operator -- (int) {iterator tmp(*this); --pos_; return tmp;}
		iterator& operator += (difference_type n) {pos_ += n; return *this;}
		iterator operator + (difference_type n) const {return iterator(*this) += n;}
		iterator& operator -= (difference_type n) {pos_ -= n; return *this;}
		iterator operator - (difference_type n) const {return iterator(*this) -= n;}
		difference_type operator - (const iterator& rhs) const {return difference_type(pos_ - rhs.pos_);}
		reference operator [] (size_type i) const {i += pos_; return *(deq_->buf_[i / deq_->alloc_.m_] + i % deq_->alloc_.m_);}
		bool operator ==(const iterator& rhs) const {return pos_ == rhs.pos_;}
		bool operator !=(const iterator& rhs) const {return pos_ != rhs.pos_;}
		bool operator < (const iterator& rhs) const {return pos_ <  rhs.pos_;}
		bool operator <=(const iterator& rhs) const {return pos_ <= rhs.pos_;}
		bool operator > (const iterator& rhs) const {return pos_ >  rhs.pos_;}
		bool operator >=(const iterator& rhs) const {return pos_ >= rhs.pos_;}
		friend iterator operator + (difference_type n, const iterator& rhs)
			{return iterator(rhs) += n;}
	private:
		deque* deq_;
		size_type pos_;

		iterator(deque* deq, size_type pos)
			: deq_(deq),
			  pos_(pos)
		{}

		friend class deque;
		friend class deque::const_iterator;
	};

	friend class const_iterator;
	class const_iterator
		: public _STD::iterator<random_access_iterator_tag, T, difference_type, const_pointer, const_reference>
	{
	public:
		const_iterator() {}
		const_iterator(const deque::iterator& rhs) : deq_(rhs.deq_), pos_(rhs.pos_) {}
		const_reference operator * () const {return *(deq_->buf_[pos_ / deq_->alloc_.m_] + pos_ % deq_->alloc_.m_);}
		const_pointer operator -> () const {return deq_->buf_[pos_ / deq_->alloc_.m_] + pos_ % deq_->alloc_.m_;}
		const_iterator& operator ++ () {++pos_; return *this;}
		const_iterator operator ++ (int) {const_iterator tmp(*this); ++pos_; return tmp;}
		const_iterator& operator -- () {--pos_; return *this;}
		const_iterator operator -- (int) {const_iterator tmp(*this); --pos_; return tmp;}
		const_iterator& operator += (difference_type n) {pos_ += n; return *this;}
		const_iterator operator + (difference_type n) const {return const_iterator(*this) += n;}
		const_iterator& operator -= (difference_type n) {pos_ -= n; return *this;}
		const_iterator operator - (difference_type n) const {return const_iterator(*this) -= n;}
		difference_type operator - (const const_iterator& rhs) const {return difference_type(pos_ - rhs.pos_);}
		const_reference operator [] (size_type i) const {i += pos_; return *(deq_->buf_[i / deq_->alloc_.m_] + i % deq_->alloc_.m_);}
		bool operator ==(const const_iterator& rhs) const {return pos_ == rhs.pos_;}
		bool operator !=(const const_iterator& rhs) const {return pos_ != rhs.pos_;}
		bool operator < (const const_iterator& rhs) const {return pos_ <  rhs.pos_;}
		bool operator <=(const const_iterator& rhs) const {return pos_ <= rhs.pos_;}
		bool operator > (const const_iterator& rhs) const {return pos_ >  rhs.pos_;}
		bool operator >=(const const_iterator& rhs) const {return pos_ >= rhs.pos_;}
		friend const_iterator operator + (difference_type n, const const_iterator& rhs)
			{return const_iterator(rhs) += n;}
	private:
		const deque* deq_;
		size_type pos_;

		const_iterator(const deque* deq, size_type pos)
			: deq_(deq),
			  pos_(pos)
		{}

		friend class deque;
	};

	// _lib.deque.cons_ construct/copy/destroy:
	explicit deque(const Allocator& = Allocator());
	explicit deque(size_type n, const T& value = T(), const Allocator& = Allocator());
	#ifdef MSIPL_MEMBER_TEMPLATE
		template <class InputIterator>
			deque(InputIterator first, InputIterator last, const Allocator& a = Allocator())
				: alloc_(a, default_bufsize_s),
				  buf_(buf_allocator(a)),
				  start_(0),
				  size_(0)
			{
				choose_init(first, last, chooser<numeric_limits<InputIterator>::is_integer>());
			}
	#else
		deque(const_iterator first, const_iterator last, const Allocator& = Allocator());
	#endif
	deque(const deque<T,Allocator>& x);
	~deque();
	deque<T,Allocator>& operator=(const deque<T,Allocator>& x);
	#ifdef MSIPL_MEMBER_TEMPLATE
		template <class InputIterator>
			inline
			void assign(InputIterator first, InputIterator last)
			{
				choose_assign(first, last, chooser<numeric_limits<InputIterator>::is_integer>());
			}
	#else
		void assign(const_iterator first, const_iterator last);
	#endif
	void assign(size_type n, const T& t);
	allocator_type get_allocator() const;
	// iterators:
	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;
	// _lib.deque.capacity_ capacity:
	size_type size() const;
	size_type max_size() const;
	void      resize(size_type sz, T c = T());
	bool      empty() const;

	// element access:
	reference       operator[](size_type n);
	const_reference operator[](size_type n) const;
	reference       at(size_type n);
	const_reference at(size_type n) const;
	reference       front();
	const_reference front() const;
	reference       back();
	const_reference back() const;
	// _lib.deque.modifiers_ modifiers:
	void push_front(const T& x);
	void push_back(const T& x);
	iterator insert(iterator position, const T& x);
	void     insert(iterator position, size_type n, const T& x);
	#ifdef MSIPL_MEMBER_TEMPLATE
		template <class InputIterator>
			void insert(iterator position, InputIterator first, InputIterator last)
			{
				choose_insert(position, first, last, chooser<numeric_limits<InputIterator>::is_integer>());
			}
	#else
		void insert(iterator position, const_iterator first, const_iterator last);
	#endif
	void pop_front();
	void pop_back();
	iterator erase(iterator position);
	iterator erase(iterator first, iterator last);
	void     swap(deque<T,Allocator>&);
	void     clear();
private:
	static const size_type min_buf_size_s = 8;
	static const size_type min_foot_print_s = 512;
	static const size_type default_bufsize_s = sizeof(T) * min_buf_size_s < min_foot_print_s ?
	                                           min_foot_print_s / sizeof(T) : min_buf_size_s;
	typedef ALLOC_BIND (pointer) buf_allocator;
	_EmptyMemberOpt<Allocator, size_type> alloc_;  // alloc_.m_ is bufsize_
	__cdeque<pointer, buf_allocator> buf_;
	size_type start_;
	size_type size_;

	#ifdef MSIPL_MEMBER_TEMPLATE
		template <class InputIterator>
			inline
			void
			choose_init(InputIterator first, InputIterator last, chooser<true>)
			{
				init(static_cast<size_type>(first), static_cast<value_type>(last));
			}

		template <class InputIterator>
			inline
			void
			choose_init(InputIterator first, InputIterator last, chooser<false>)
			{
				init(first, last, iterator_traits<InputIterator>::iterator_category());
			}

		template <class InputIterator>
			void
			init(InputIterator first, InputIterator last, input_iterator_tag)
			{
				#ifdef MSIPL_EXCEPT
				try
				{
				#endif
					for (; first != last; ++first)
						push_back(*first);
				#ifdef MSIPL_EXCEPT
				}
				catch (...)
				{
					tear_down();
					throw;
				}
				#endif
			}

		template <class ForwardIterator>
			void
			init(ForwardIterator first, ForwardIterator last, forward_iterator_tag)
			{
				size_ = (size_type)distance(first, last);
				if (size_ > max_size())
					#ifdef MSIPL_EXCEPT
						throw length_error("deque::construction length error");
					#else
					{
						fprintf(stderr, "deque::construction length error\n");
						abort();
					}
					#endif
				if (size_ > 0)
				{
					if (alloc_.m_ < size_)
						alloc_.m_ = size_;
					pointer tmp = alloc_.allocate(alloc_.m_);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						buf_.push_back(tmp);
						start_ = (alloc_.m_ - size_) / 2;
						uninitialized_copy(first, last, buf_.front() + start_);
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(tmp, alloc_.m_);
						throw;
					}
					#endif
				}
			}

		template <class InputIterator>
			inline
			void
			choose_assign(InputIterator first, InputIterator last, chooser<true>)
			{
				assign(static_cast<size_type>(first), static_cast<value_type>(last));
			}

		template <class InputIterator>
			inline
			void
			choose_assign(InputIterator first, InputIterator last, chooser<false>)
			{
				do_assign(first, last, iterator_traits<InputIterator>::iterator_category());
			}

		template <class InputIterator>
			void
			do_assign(InputIterator first, InputIterator last, input_iterator_tag)
			{
				deque temp(first, last, get_allocator());
				const deque& tempr = temp;
				do_assign(tempr.begin(), tempr.end(), random_access_iterator_tag());
			}

		template <class ForwardIterator>
			void
			do_assign(ForwardIterator first, ForwardIterator last, forward_iterator_tag)
			{
				size_type n = (size_type)distance(first, last);
				if (n > max_size())
					#ifdef MSIPL_EXCEPT
						throw length_error("deque::assign length error");
					#else
					{
						fprintf(stderr, "deque::assign length error\n");
						abort();
					}
					#endif
				while (n > buf_.size() * alloc_.m_)
				{
					pointer tmp = alloc_.allocate(alloc_.m_);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						buf_.push_back(tmp);
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(tmp, alloc_.m_);
						throw;
					}
					#endif
				}
				destroy(begin(), end());
				size_ = 0;
				start_ = (buf_.size() * alloc_.m_ - n) / 2;
				while (start_ >= alloc_.m_)
				{
					alloc_.deallocate(buf_.back(), alloc_.m_);
					buf_.pop_back();
					start_ = (buf_.size() * alloc_.m_ - n) / 2;
				}
				uninitialized_copy(first, last, begin());
				size_ = n;
			}

		template <class InputIterator>
			inline
			void
			choose_insert(iterator position, InputIterator first, InputIterator last,
				chooser<true>)
			{
				insert(position, static_cast<size_type>(first), static_cast<value_type>(last));
			}

		template <class InputIterator>
			inline
			void
			choose_insert(iterator position, InputIterator first, InputIterator last,
				chooser<false>)
			{
				do_insert(position, first, last, iterator_traits<InputIterator>::iterator_category());
			}

		template <class InputIterator>
			void
			do_insert(iterator position, InputIterator first, InputIterator last,
				input_iterator_tag)
			{
				deque temp(first, last, get_allocator());
				const deque& tempr = temp;
				do_insert(position, tempr.begin(), tempr.end(), random_access_iterator_tag());
			}

		template <class ForwardIterator>
			void
			do_insert(iterator position, ForwardIterator first, ForwardIterator last,
				forward_iterator_tag)
			{
				size_type n = (size_type)distance(first, last);
				if (n == 0)
					return;
				size_type ms = max_size();
				if (n > ms || size_ > ms - n)
					#ifdef MSIPL_EXCEPT
						throw length_error("deque::insert length error");
					#else
					{
						fprintf(stderr, "deque::insert length error\n");
						abort();
					}
					#endif
				size_type pb = size_type(position - begin());
				size_type pe = size_type(end() - position);
				if (pb <= pe)  // hh 981210
				{
					size_type new_buffers = 0;
					size_type oldstart = start_;
					if (start_ < n)
					{
						size_type nc = n;
						nc -= start_;
						while (true)
						{
							pointer tmp = alloc_.allocate(alloc_.m_);
							#ifdef MSIPL_EXCEPT
							try
							{
							#endif
								buf_.push_front(tmp);
								++new_buffers;  // hh 981210
								start_ += alloc_.m_;
								if (nc <= alloc_.m_)
								{
									if (size_ != 0)  // hh 981210
										start_ -= n;
									else
										start_ = (buf_.size() * alloc_.m_ - n) / 2;
									break;
								}
								nc -= alloc_.m_;
							#ifdef MSIPL_EXCEPT
							}
							catch (...)
							{
								alloc_.deallocate(tmp, alloc_.m_);
								for (size_type i = 0; i < new_buffers; ++i)  // hh 981210
								{
									alloc_.deallocate(buf_.front(), alloc_.m_);
									buf_.pop_front();
								}
								start_ = oldstart;
								throw;
							}
							#endif
						}
					}
					else
						start_ -= n;
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						if (pb == 0) // insert at begin()
							uninitialized_copy(first, last, begin());
						else // pos in [1, size_ / 2)
						{
							size_type e = min(pb, n);
							size_type done = 0;
							uninitialized_copy(begin() + difference_type(n),
								begin() + difference_type(n + e), begin());
							done = e;
							#ifdef MSIPL_EXCEPT
							try
							{
							#endif
								if (n < pb)  // hh 981210
									copy(begin() + difference_type(n + e),
										begin() + difference_type(n + pb), begin() + difference_type(n));
								ForwardIterator i = first;
								if (pb < n)
								{
									advance(i, difference_type(n - pb));
									uninitialized_copy(first, i, begin() + difference_type(pb));  // ???
									done = n;
								}
								e = max(pb, n);
								copy(i, last, begin() + difference_type(e));
							#ifdef MSIPL_EXCEPT
							}
							catch (...)
							{
								destroy(begin(), begin() + difference_type(done));
								throw;
							}
							#endif
						}
						size_ += n;
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						for (size_type i = 0; i < new_buffers; ++i)  // hh 981210
						{
							alloc_.deallocate(buf_.front(), alloc_.m_);
							buf_.pop_front();
						}
						start_ = oldstart;
						throw;
					}
					#endif
				}
				else // pos >= size_ / 2
				{
					size_type e = buf_.size() * alloc_.m_ - (start_ + size_);
					if (e < n)
					{
						size_type nc = n;
						nc -= e;
						while (true)
						{
							pointer tmp = alloc_.allocate(alloc_.m_);
							#ifdef MSIPL_EXCEPT
							try
							{
							#endif
								buf_.push_back(tmp);
								if (nc <= alloc_.m_)
									break;
								nc -= alloc_.m_;
							#ifdef MSIPL_EXCEPT
							}
							catch (...)
							{
								alloc_.deallocate(tmp, alloc_.m_);
								throw;
							}
							#endif
						}
					}
					if (pe == 0) // insert at end()
						uninitialized_copy(first, last, position);
					else // pos in [size_ / 2, size_)
					{
						size_type e = min(pe, n);
						uninitialized_copy(end() - difference_type(e), end(),
							end() + difference_type(n - e));
						#ifdef MSIPL_EXCEPT
						try
						{
						#endif
							if (n < pe)
								copy_backward(end() - difference_type(pe),
									end() - difference_type(n), end());
							for (size_type i = 0; i < e; ++i, ++position, ++first)
								*position = *first;
							if (pe < n)
								uninitialized_copy(first, last, position);
						#ifdef MSIPL_EXCEPT
						}
						catch (...)
						{
							destroy(end() + difference_type(n - e), end() + difference_type(n));
							throw;
						}
						#endif
					}
					size_ += n;
				}
				invalidate_iterators();
			}

	#endif
	void init(size_type n, const T& value);
	void tear_down();
	void destroy(iterator first, iterator last);
	void invalidate_iterators();
};

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

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

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

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

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

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

// specialized algorithms:

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

// Implementation deque

template <class T, class Allocator>
inline
void
deque<T, Allocator>::invalidate_iterators()
{
	while (start_ >= 3 * alloc_.m_ / 2)
	{
		alloc_.deallocate(buf_.front(), alloc_.m_);
		buf_.pop_front();
		start_ -= alloc_.m_;
	}
}

template <class T, class Allocator>
deque<T, Allocator>::deque(const Allocator& a)
	: alloc_(a, default_bufsize_s),
#ifdef MSIPL_MEMBER_TEMPLATE
	  buf_(buf_allocator(a)),
#endif
	  start_(0),
	  size_(0)
{
}

template <class T, class Allocator>
deque<T, Allocator>::deque(size_type n, const T& value, const Allocator& a)
	: alloc_(a, default_bufsize_s),
#ifdef MSIPL_MEMBER_TEMPLATE
	  buf_(buf_allocator(a)),
#endif
	  start_(0),
	  size_(0)
{
	init(n, value);
}

#ifndef MSIPL_MEMBER_TEMPLATE

	template <class T, class Allocator>
	deque<T, Allocator>::deque(const_iterator first, const_iterator last, const Allocator& a)
		: alloc_(a, default_bufsize_s),
	#ifdef MSIPL_MEMBER_TEMPLATE
		  buf_(buf_allocator(a)),
	#endif
		  start_(0),
		  size_(size_type(last - first))
	{
		if (size_ > max_size())
			#ifdef MSIPL_EXCEPT
				throw length_error("deque::construction length error");
			#else
			{
				fprintf(stderr, "deque::construction length error\n");
				abort();
			}
			#endif
		if (size_ > 0)
		{
			if (alloc_.m_ < size_)
				alloc_.m_ = size_;
			pointer tmp = alloc_.allocate(alloc_.m_);
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				buf_.push_back(tmp);
				start_ = (alloc_.m_ - size_) / 2;
				uninitialized_copy(first, last, buf_.front() + start_);
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				alloc_.deallocate(tmp, alloc_.m_);
				throw;
			}
			#endif
		}
	}

#endif

template <class T, class Allocator>
void
deque<T, Allocator>::init(size_type n, const T& value)
{
	if (n > max_size())
		#ifdef MSIPL_EXCEPT
			throw length_error("deque::construction length error");
		#else
		{
			fprintf(stderr, "deque::construction length error\n");
			abort();
		}
		#endif
	if (n > 0)
	{
		if (alloc_.m_ < n)
			alloc_.m_ = n;
		pointer tmp = alloc_.allocate(alloc_.m_);
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			buf_.push_back(tmp);
			size_ = n;
			start_ = (alloc_.m_ - size_) / 2;
			uninitialized_fill_n(buf_.front() + start_, size_, value);
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			alloc_.deallocate(tmp, alloc_.m_);
			throw;
		}
		#endif
	}
}

template <class T, class Allocator>
deque<T, Allocator>::deque(const deque<T,Allocator>& x)
	: alloc_(x.alloc_, default_bufsize_s),
#ifdef MSIPL_MEMBER_TEMPLATE
	  buf_(buf_allocator(alloc_)),
#endif
	  start_(0),
	  size_(x.size_)
{
	if (size_ > 0)
	{
		if (alloc_.m_ < size_)
			alloc_.m_ = size_;
		pointer tmp = alloc_.allocate(alloc_.m_);
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			buf_.push_back(tmp);
			start_ = (alloc_.m_ - size_) / 2;
			uninitialized_copy(x.begin(), x.end(), buf_.front() + start_);
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			alloc_.deallocate(tmp, alloc_.m_);
			throw;
		}
		#endif
	}
}

template <class T, class Allocator>
inline
deque<T, Allocator>::~deque()
{
	tear_down();
}

template <class T, class Allocator>
void
deque<T, Allocator>::tear_down()
{
	destroy(begin(), end());
	for (size_type i = 0; i < buf_.size(); ++i)
		alloc_.deallocate(buf_[i], alloc_.m_);
}

template <class T, class Allocator>
void
deque<T, Allocator>::destroy(iterator first, iterator last)
{
	if (first != last)
	{
		size_type diff = size_type(last - first);
		size_type i = first.pos_;
		size_type w = i / alloc_.m_;
		i %= alloc_.m_;
		size_type e = min(alloc_.m_, i + diff);
		_STD::destroy(buf_[w] + i, buf_[w] + e);
		diff -= e - i;
		if (diff == 0)
			return;
		++w;
		while (diff >= alloc_.m_)
		{
			_STD::destroy(buf_[w], buf_[w] + alloc_.m_);
			++w;
			diff -= alloc_.m_;
		}
		if (diff > 0)
			_STD::destroy(buf_[w], buf_[w] + diff);
	}
}

template <class T, class Allocator>
inline
deque<T,Allocator>&
deque<T, Allocator>::operator=(const deque<T,Allocator>& x)
{
	if (this != &x)
		assign(x.begin(), x.end());
	return *this;
}

#ifndef MSIPL_MEMBER_TEMPLATE

	template <class T, class Allocator>
	void
	deque<T, Allocator>::assign(const_iterator first, const_iterator last)
	{
		size_type n = (size_type)distance(first, last);
		if (n > max_size())
			#ifdef MSIPL_EXCEPT
				throw length_error("deque::assign length error");
			#else
			{
				fprintf(stderr, "deque::assign length error\n");
				abort();
			}
			#endif
		while (n > buf_.size() * alloc_.m_)
		{
			pointer tmp = alloc_.allocate(alloc_.m_);
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				buf_.push_back(tmp);
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				alloc_.deallocate(tmp, alloc_.m_);
				throw;
			}
			#endif
		}
		destroy(begin(), end());
		size_ = 0;
		start_ = (buf_.size() * alloc_.m_ - n) / 2;
		while (start_ >= alloc_.m_)
		{
			alloc_.deallocate(buf_.back(), alloc_.m_);
			buf_.pop_back();
			start_ = (buf_.size() * alloc_.m_ - n) / 2;
		}
		uninitialized_copy(first, last, begin());
		size_ = n;
	}

#endif

template <class T, class Allocator>
void
deque<T, Allocator>::assign(size_type n, const T& t)
{
	if (n > max_size())
		#ifdef MSIPL_EXCEPT
			throw length_error("deque::assign length error");
		#else
		{
			fprintf(stderr, "deque::assign length error\n");
			abort();
		}
		#endif
	while (n > buf_.size() * alloc_.m_)
	{
		pointer tmp = alloc_.allocate(alloc_.m_);
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			buf_.push_back(tmp);
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			alloc_.deallocate(tmp, alloc_.m_);
			throw;
		}
		#endif
	}
	destroy(begin(), end());
	size_ = 0;
	start_ = (buf_.size() * alloc_.m_ - n) / 2;
	while (start_ >= alloc_.m_)
	{
		alloc_.deallocate(buf_.back(), alloc_.m_);
		buf_.pop_back();
		start_ = (buf_.size() * alloc_.m_ - n) / 2;
	}
	uninitialized_fill_n(begin(), n, t);
	size_ = n;
}

template <class T, class Allocator>
inline
deque<T, Allocator>::allocator_type
deque<T, Allocator>::get_allocator() const
{
	return alloc_;
}

template <class T, class Allocator>
inline
deque<T, Allocator>::iterator
deque<T, Allocator>::begin()
{
	return iterator(this, start_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::const_iterator
deque<T, Allocator>::begin() const
{
	return const_iterator(this, start_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::iterator
deque<T, Allocator>::end()
{	
	return iterator(this, start_ + size_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::const_iterator
deque<T, Allocator>::end() const
{	
	return const_iterator(this, start_ + size_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::reverse_iterator
deque<T, Allocator>::rbegin()
{
	return reverse_iterator(end());
}

template <class T, class Allocator>
inline
deque<T, Allocator>::const_reverse_iterator
deque<T, Allocator>::rbegin() const
{
	return const_reverse_iterator(end());
}

template <class T, class Allocator>
inline
deque<T, Allocator>::reverse_iterator
deque<T, Allocator>::rend()
{
	return reverse_iterator(begin());
}

template <class T, class Allocator>
inline
deque<T, Allocator>::const_reverse_iterator
deque<T, Allocator>::rend() const
{
	return const_reverse_iterator(begin());
}

template <class T, class Allocator>
inline
deque<T, Allocator>::size_type
deque<T, Allocator>::size() const
{
	return size_;
}

template <class T, class Allocator>
inline
deque<T, Allocator>::size_type
deque<T, Allocator>::max_size() const
{
	return alloc_.max_size();
}

template <class T, class Allocator>
void
deque<T, Allocator>::resize(size_type sz, T c)
{
	if (sz > size())
		insert(end(), sz-size(), c);
	else if (sz < size())
		erase(begin() + difference_type(sz), end());
}

template <class T, class Allocator>
inline
bool
deque<T, Allocator>::empty() const
{
	return size_ == 0;
}

template <class T, class Allocator>
inline
deque<T, Allocator>::reference
deque<T, Allocator>::operator[](size_type n)
{
	size_type i = n + start_;
	return *(buf_[i / alloc_.m_] + i % alloc_.m_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::const_reference
deque<T, Allocator>::operator[](size_type n) const
{
	size_type i = n + start_;
	return *(buf_[i / alloc_.m_] + i % alloc_.m_);
}

template <class T, class Allocator>
deque<T, Allocator>::reference
deque<T, Allocator>::at(size_type n)
{
	if (n >= size_)
		#ifdef MSIPL_EXCEPT
			throw out_of_range("deque::at index out of range");
		#else
		{
			fprintf(stderr, "deque::at index out of range");
			abort();
		}
		#endif
	size_type i = n + start_;
	return *(buf_[i / alloc_.m_] + i % alloc_.m_);
}

template <class T, class Allocator>
deque<T, Allocator>::const_reference
deque<T, Allocator>::at(size_type n) const
{
	if (n >= size_)
		#ifdef MSIPL_EXCEPT
			throw out_of_range("deque::at index out of range");
		#else
		{
			fprintf(stderr, "deque::at index out of range");
			abort();
		}
		#endif
	size_type i = n + start_;
	return *(buf_[i / alloc_.m_] + i % alloc_.m_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::reference
deque<T, Allocator>::front()
{
	return *(buf_[start_ / alloc_.m_] + start_ % alloc_.m_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::const_reference
deque<T, Allocator>::front() const
{
	return *(buf_[start_ / alloc_.m_] + start_ % alloc_.m_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::reference
deque<T, Allocator>::back()
{
	size_type i = start_ + size_ - 1;
	return *(buf_[i / alloc_.m_] + i % alloc_.m_);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::const_reference
deque<T, Allocator>::back() const
{
	size_type i = start_ + size_ - 1;
	return *(buf_[i / alloc_.m_] + i % alloc_.m_);
}

template <class T, class Allocator>
inline
void
deque<T, Allocator>::push_front(const T& x)
{
	insert(begin(), x);
}

template <class T, class Allocator>
inline
void
deque<T, Allocator>::push_back(const T& x)
{
	insert(end(), x);
}

template <class T, class Allocator>
deque<T, Allocator>::iterator
deque<T, Allocator>::insert(iterator position, const T& x)
{
	difference_type pos = position - begin();
	insert(position, 1, x);
	return begin() + pos;
}

template <class T, class Allocator>
void
deque<T, Allocator>::insert(iterator position, size_type n, const T& x)
{
	if (n == 0)
		return;
	size_type ms = max_size();
	if (n > ms || size_ > ms - n)
		#ifdef MSIPL_EXCEPT
			throw length_error("deque::insert length error");
		#else
		{
			fprintf(stderr, "deque::insert length error\n");
			abort();
		}
		#endif
	size_type pb = size_type(position - begin());
	size_type pe = size_type(end() - position);
	if (pb <= pe)  // hh 981210
	{
		size_type new_buffers = 0;
		size_type oldstart = start_;
		if (start_ < n)
		{
			size_type nc = n;
			nc -= start_;
			while (true)
			{
				pointer tmp = alloc_.allocate(alloc_.m_);
				#ifdef MSIPL_EXCEPT
				try
				{
				#endif
					buf_.push_front(tmp);
					++new_buffers;  // hh 981210
					start_ += alloc_.m_;
					if (nc <= alloc_.m_)
					{
						if (size_ != 0)  // hh 981210
							start_ -= n;
						else
							start_ = (buf_.size() * alloc_.m_ - n) / 2;
						break;
					}
					nc -= alloc_.m_;
				#ifdef MSIPL_EXCEPT
				}
				catch (...)
				{
					alloc_.deallocate(tmp, alloc_.m_);
					for (size_type i = 0; i < new_buffers; ++i)  // hh 981210
					{
						alloc_.deallocate(buf_.front(), alloc_.m_);
						buf_.pop_front();
					}
					start_ = oldstart;
					throw;
				}
				#endif
			}
		}
		else
			start_ -= n;
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			if (pb == 0) // insert at begin()
				uninitialized_fill_n(begin(), n, x);
			else // pos in [1, size_ / 2)
			{
				size_type e = min(pb, n);
				size_type done = 0;
				uninitialized_copy(begin() + difference_type(n),
					begin() + difference_type(n + e), begin());
				done = e;
				#ifdef MSIPL_EXCEPT
				try
				{
				#endif
					if (n < pb)
						copy(begin() + difference_type(n + e),
							begin() + difference_type(n + pb), begin() + difference_type(n));
					if (pb < n)
					{
						uninitialized_fill(begin() + difference_type(pb),
							begin() + difference_type(n), x);
						done = n;
					}
					e = max(pb, n);
					fill(begin() + difference_type(e), begin() + difference_type(n + pb), x);
				}
				catch (...)
				{
					destroy(begin(), begin() + difference_type(done));
					throw;
				}
			}
			size_ += n;
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			for (size_type i = 0; i < new_buffers; ++i)  // hh 981210
			{
				alloc_.deallocate(buf_.front(), alloc_.m_);
				buf_.pop_front();
			}
			start_ = oldstart;
			throw;
		}
		#endif
	}
	else // pos >= size_ / 2
	{
		size_type e = buf_.size() * alloc_.m_ - (start_ + size_);
		if (e < n)
		{
			size_type nc = n;
			nc -= e;
			while (true)
			{
				pointer tmp = alloc_.allocate(alloc_.m_);
				#ifdef MSIPL_EXCEPT
				try
				{
				#endif
					buf_.push_back(tmp);
					if (nc <= alloc_.m_)
						break;
					nc -= alloc_.m_;
				#ifdef MSIPL_EXCEPT
				}
				catch (...)
				{
					alloc_.deallocate(tmp, alloc_.m_);
					throw;
				}
				#endif
			}
		}
		if (pe == 0) // insert at end()
			uninitialized_fill_n(position, n, x);
		else // pos in [size_ / 2, size_)
		{
			size_type e = min(pe, n);
			uninitialized_copy(end() - difference_type(e), end(),
				end() + difference_type(n - e));
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				if (n < pe)
					copy_backward(end() - difference_type(pe), end() - difference_type(n), end());
				fill(end() - difference_type(pe), end() - difference_type(pe - e), x);
				if (pe < n)
					uninitialized_fill(end(), end() + difference_type(n - pe), x);
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				destroy(end() + difference_type(n - e), end() + difference_type(n));
				throw;
			}
			#endif
		}
		size_ += n;
	}
	invalidate_iterators();
}

#ifndef MSIPL_MEMBER_TEMPLATE

	template <class T, class Allocator>
	void
	deque<T, Allocator>::do_insert(iterator position, const_iterator first, const_iterator last)
	{
		size_type n = (size_type)distance(first, last);
		if (n == 0)
			return;
		size_type ms = max_size();
		if (n > ms || size_ > ms - n)
			#ifdef MSIPL_EXCEPT
				throw length_error("deque::insert length error");
			#else
			{
				fprintf(stderr, "deque::insert length error\n");
				abort();
			}
			#endif
		size_type pb = size_type(position - begin());
		size_type pe = size_type(end() - position);
		if (pb <= pe)  // hh 981210
		{
			size_type new_buffers = 0;
			size_type oldstart = start_;
			if (start_ < n)
			{
				size_type nc = n;
				nc -= start_;
				while (true)
				{
					pointer tmp = alloc_.allocate(alloc_.m_);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						buf_.push_front(tmp);
						++new_buffers;  // hh 981210
						start_ += alloc_.m_;
						if (nc <= alloc_.m_)
						{
							if (size_ != 0)  // hh 981210
								start_ -= n;
							else
								start_ = (buf_.size() * alloc_.m_ - n) / 2;
							break;
						}
						nc -= alloc_.m_;
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(tmp, alloc_.m_);
						for (size_type i = 0; i < new_buffers; ++i)  // hh 981210
						{
							alloc_.deallocate(buf_.front(), alloc_.m_);
							buf_.pop_front();
						}
						start_ = oldstart;
						throw;
					}
					#endif
				}
			}
			else
				start_ -= n;
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				if (pb == 0) // insert at begin()
					uninitialized_copy(first, last, begin());
				else // pos in [1, size_ / 2)
				{
					size_type e = min(pb, n);
					size_type done = 0;
					uninitialized_copy(begin() + difference_type(n),
						begin() + difference_type(n + e), begin());
					done = e;
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						if (n < pb)  // hh 981210
							copy(begin() + difference_type(n + e),
								begin() + difference_type(n + pb), begin() + difference_type(n));
						const_iterator i = first;
						if (pb < n)
						{
							advance(i, difference_type(n - pb));
							uninitialized_copy(first, i, begin() + difference_type(pb));
							done = n;
						}
						e = max(pb, n);
						copy(i, last, begin() + difference_type(e));
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						destroy(begin(), begin() + difference_type(done));
						throw;
					}
					#endif
				}
				size_ += n;
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				for (size_type i = 0; i < new_buffers; ++i)  // hh 981210
				{
					alloc_.deallocate(buf_.front(), alloc_.m_);
					buf_.pop_front();
				}
				start_ = oldstart;
				throw;
			}
			#endif
		}
		else // pos >= size_ / 2
		{
			size_type e = buf_.size() * alloc_.m_ - (start_ + size_);
			if (e < n)
			{
				size_type nc = n;
				nc -= e;
				while (true)
				{
					pointer tmp = alloc_.allocate(alloc_.m_);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						buf_.push_back(tmp);
						if (nc <= alloc_.m_)
							break;
						nc -= alloc_.m_;
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(tmp, alloc_.m_);
						throw;
					}
					#endif
				}
			}
			if (pe == 0) // insert at end()
				uninitialized_copy(first, last, position);
			else // pos in [size_ / 2, size_)
			{
				size_type e = min(pe, n);
				uninitialized_copy(end() - difference_type(e), end(),
					end() + difference_type(n - e));
				#ifdef MSIPL_EXCEPT
				try
				{
				#endif
					if (n < pe)
						copy_backward(end() - difference_type(pe),
							end() - difference_type(n), end());
					for (size_type i = 0; i < e; ++i, ++position, ++first)
						*position = *first;
					if (pe < n)
						uninitialized_copy(first, last, position);
				#ifdef MSIPL_EXCEPT
				}
				catch (...)
				{
					destroy(end() + difference_type(n - e), end() + difference_type(n));
					throw;
				}
				#endif
			}
			size_ += n;
		}
		invalidate_iterators();
	}

#endif

template <class T, class Allocator>
inline
void
deque<T, Allocator>::pop_front()
{
	erase(begin());
}

template <class T, class Allocator>
inline
void
deque<T, Allocator>::pop_back()
{
	erase(end() - 1);
}

template <class T, class Allocator>
inline
deque<T, Allocator>::iterator
deque<T, Allocator>::erase(iterator position)
{
	return erase(position, position + 1);
}

template <class T, class Allocator>
deque<T, Allocator>::iterator
deque<T, Allocator>::erase(iterator first, iterator last)
{
	if (first == last)
		return first;
	const size_type pb = size_type(first - begin());
	const size_type pe = size_type(end() - last);
	const size_type diff = size_type(last - first);
	if (pb < pe)
	{
		if (pb == 0)  // erase from beginning, no copying necessary
		{
			destroy(first, last);
			start_ += diff;
			size_ -= diff;
		}
		else  // erase from beginning, needs copying
		{
			copy_backward(begin(), first, last);
			destroy(begin(), begin() + difference_type(diff));
			start_ += diff;
			size_ -= diff;
			invalidate_iterators();
		}
	}
	else  // pb >= pe - erase from end
	{
		if (pe == 0)  // erase from end, no copying necessary
			destroy(first, last);
		else  // erase from end, needs copying
		{
			copy(last, end(), first);
			destroy(first + difference_type(pe), end());
			invalidate_iterators();
		}
		size_ -= diff;
		while (buf_.size() * alloc_.m_ - (start_ + size_) >= 3 * alloc_.m_ / 2)
		{
			alloc_.deallocate(buf_.back(), alloc_.m_);
			buf_.pop_back();
		}
	}
	if (size_ == 0)
	{
		for (size_type i = buf_.size() - 1; i > 0; --i)
		{
			alloc_.deallocate(buf_.back(), alloc_.m_);
			buf_.pop_back();
		}
		start_ = alloc_.m_ / 2;
	}
	return iterator(this, start_ + pb);
}

template <class T, class Allocator>
void
deque<T, Allocator>::swap(deque<T,Allocator>& x)
{
	if (this != &x)
	{
		_STD::swap(alloc_, x.alloc_);
		_STD::swap(buf_, x.buf_);
		_STD::swap(start_, x.start_);
		_STD::swap(size_, x.size_);
	}
}

template <class T, class Allocator>
void
deque<T, Allocator>::clear()
{
	if (!buf_.empty())  // hh 981209
	{
		destroy(begin(), end());
		size_ = 0;
		for (size_type i = buf_.size() - 1; i > 0; --i)
		{
			alloc_.deallocate(buf_.back(), alloc_.m_);
			buf_.pop_back();
		}
		start_ = alloc_.m_ / 2;
	}
}

template <class T, class Allocator>
inline
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>
inline
bool
operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y)
{
	return !(x == y);
}

template <class T, class Allocator>
inline
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>
inline
bool
operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y)
{
	return y < x;
}

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

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

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

#if defined(MSIPL_PARTIAL_SPECIALIZATION) && defined(MSIPL_MEMBER_TEMPLATE) && !defined(_Inhibit_Container_Optimization)

	// Specialize for T* to save on code bloat

	// void*

	template <class Allocator>
	class deque<void*, Allocator>
	{
		template <bool b> struct chooser {};
	public:
		// types:
		typedef typename Allocator::reference         reference;
		typedef typename Allocator::const_reference   const_reference;
		class                                         iterator;
		class                                         const_iterator;
		typedef typename Allocator::size_type         size_type;
		typedef typename Allocator::difference_type   difference_type;
		typedef void*                                 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;

		friend class iterator;
		class iterator
			: public _STD::iterator<random_access_iterator_tag, value_type, difference_type, pointer, reference>
		{
		public:
			iterator() {}
			reference operator * () const {return *(deq_->buf_[pos_ / deq_->alloc_.m_] + pos_ % deq_->alloc_.m_);}
			pointer operator -> () const {return deq_->buf_[pos_ / deq_->alloc_.m_] + pos_ % deq_->alloc_.m_;}
			iterator& operator ++ () {++pos_; return *this;}
			iterator operator ++ (int) {iterator tmp(*this); ++pos_; return tmp;}
			iterator& operator -- () {--pos_; return *this;}
			iterator operator -- (int) {iterator tmp(*this); --pos_; return tmp;}
			iterator& operator += (difference_type n) {pos_ += n; return *this;}
			iterator operator + (difference_type n) const {return iterator(*this) += n;}
			iterator& operator -= (difference_type n) {pos_ -= n; return *this;}
			iterator operator - (difference_type n) const {return iterator(*this) -= n;}
			difference_type operator - (const iterator& rhs) const {return difference_type(pos_ - rhs.pos_);}
			reference operator [] (size_type i) const {i += pos_; return *(deq_->buf_[i / deq_->alloc_.m_] + i % deq_->alloc_.m_);}
			bool operator ==(const iterator& rhs) const {return pos_ == rhs.pos_;}
			bool operator !=(const iterator& rhs) const {return pos_ != rhs.pos_;}
			bool operator < (const iterator& rhs) const {return pos_ <  rhs.pos_;}
			bool operator <=(const iterator& rhs) const {return pos_ <= rhs.pos_;}
			bool operator > (const iterator& rhs) const {return pos_ >  rhs.pos_;}
			bool operator >=(const iterator& rhs) const {return pos_ >= rhs.pos_;}
			friend iterator operator + (difference_type n, const iterator& rhs)
				{return iterator(rhs) += n;}
		private:
			deque* deq_;
			size_type pos_;

			iterator(deque* deq, size_type pos)
				: deq_(deq),
				  pos_(pos)
			{}

			friend class deque;
			friend class deque::const_iterator;
		};

		friend class const_iterator;
		class const_iterator
			: public _STD::iterator<random_access_iterator_tag, value_type, difference_type, const_pointer, const_reference>
		{
		public:
			const_iterator() {}
			const_iterator(const deque::iterator& rhs) : deq_(rhs.deq_), pos_(rhs.pos_) {}
			const_reference operator * () const {return *(deq_->buf_[pos_ / deq_->alloc_.m_] + pos_ % deq_->alloc_.m_);}
			const_pointer operator -> () const {return deq_->buf_[pos_ / deq_->alloc_.m_] + pos_ % deq_->alloc_.m_;}
			const_iterator& operator ++ () {++pos_; return *this;}
			const_iterator operator ++ (int) {const_iterator tmp(*this); ++pos_; return tmp;}
			const_iterator& operator -- () {--pos_; return *this;}
			const_iterator operator -- (int) {const_iterator tmp(*this); --pos_; return tmp;}
			const_iterator& operator += (difference_type n) {pos_ += n; return *this;}
			const_iterator operator + (difference_type n) const {return const_iterator(*this) += n;}
			const_iterator& operator -= (difference_type n) {pos_ -= n; return *this;}
			const_iterator operator - (difference_type n) const {return const_iterator(*this) -= n;}
			difference_type operator - (const const_iterator& rhs) const {return difference_type(pos_ - rhs.pos_);}
			const_reference operator [] (size_type i) const {i += pos_; return *(deq_->buf_[i / deq_->alloc_.m_] + i % deq_->alloc_.m_);}
			bool operator ==(const const_iterator& rhs) const {return pos_ == rhs.pos_;}
			bool operator !=(const const_iterator& rhs) const {return pos_ != rhs.pos_;}
			bool operator < (const const_iterator& rhs) const {return pos_ <  rhs.pos_;}
			bool operator <=(const const_iterator& rhs) const {return pos_ <= rhs.pos_;}
			bool operator > (const const_iterator& rhs) const {return pos_ >  rhs.pos_;}
			bool operator >=(const const_iterator& rhs) const {return pos_ >= rhs.pos_;}
			friend const_iterator operator + (difference_type n, const const_iterator& rhs)
				{return const_iterator(rhs) += n;}
		private:
			const deque* deq_;
			size_type pos_;

			const_iterator(const deque* deq, size_type pos)
				: deq_(deq),
				  pos_(pos)
			{}

			friend class deque;
		};

		// _lib.deque.cons_ construct/copy/destroy:
		explicit deque(const Allocator& = Allocator());
		explicit deque(size_type n, const value_type& value = 0, const Allocator& = Allocator());
		template <class InputIterator>
			deque(InputIterator first, InputIterator last, const Allocator& a = Allocator())
				: alloc_(a, default_bufsize_s),
				  buf_(buf_allocator(a)),
				  start_(0),
				  size_(0)
			{
				choose_init(first, last, chooser<numeric_limits<InputIterator>::is_integer>());
			}
		deque(const deque<void*,Allocator>& x);
		~deque();
		deque<void*,Allocator>& operator=(const deque<void*,Allocator>& x);
		template <class InputIterator>
			inline
			void assign(InputIterator first, InputIterator last)
			{
				choose_assign(first, last, chooser<numeric_limits<InputIterator>::is_integer>());
			}
		void assign(size_type n, const value_type& t);
		allocator_type get_allocator() const;
		// iterators:
		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;
		// _lib.deque.capacity_ capacity:
		size_type size() const;
		size_type max_size() const;
		void      resize(size_type sz, value_type c = 0);
		bool      empty() const;

		// element access:
		reference       operator[](size_type n);
		const_reference operator[](size_type n) const;
		reference       at(size_type n);
		const_reference at(size_type n) const;
		reference       front();
		const_reference front() const;
		reference       back();
		const_reference back() const;
		// _lib.deque.modifiers_ modifiers:
		void push_front(const value_type& x);
		void push_back(const value_type& x);
		iterator insert(iterator position, const value_type& x);
		void     insert(iterator position, size_type n, const value_type& x);
		template <class InputIterator>
			void insert(iterator position, InputIterator first, InputIterator last)
			{
				choose_insert(position, first, last, chooser<numeric_limits<InputIterator>::is_integer>());
			}
		void pop_front();
		void pop_back();
		iterator erase(iterator position);
		iterator erase(iterator first, iterator last);
		void     swap(deque<void*,Allocator>&);
		void     clear();
	private:
		static const size_type min_buf_size_s = 8;
		static const size_type min_foot_print_s = 512;
		static const size_type default_bufsize_s = sizeof(value_type) * min_buf_size_s < min_foot_print_s ?
		                                           min_foot_print_s / sizeof(value_type) : min_buf_size_s;
		typedef Allocator::rebind<pointer>::other buf_allocator;
		_EmptyMemberOpt<Allocator, size_type> alloc_;  // alloc_.m_ is bufsize_
		__cdeque<pointer, buf_allocator> buf_;
		size_type start_;
		size_type size_;

		template <class InputIterator>
			inline
			void
			choose_init(InputIterator first, InputIterator last, chooser<true>)
			{
				init(static_cast<size_type>(first), reinterpret_cast<value_type>(last));  // hh 981208
			}

		template <class InputIterator>
			inline
			void
			choose_init(InputIterator first, InputIterator last, chooser<false>)
			{
				init(first, last, iterator_traits<InputIterator>::iterator_category());
			}

		template <class InputIterator>
			void
			init(InputIterator first, InputIterator last, input_iterator_tag)
			{
				#ifdef MSIPL_EXCEPT
				try
				{
				#endif
					for (; first != last; ++first)
						push_back(*first);
				#ifdef MSIPL_EXCEPT
				}
				catch (...)
				{
					tear_down();
					throw;
				}
				#endif
			}

		template <class ForwardIterator>
			void
			init(ForwardIterator first, ForwardIterator last, forward_iterator_tag)
			{
				size_ = (size_type)distance(first, last);
				if (size_ > max_size())
					#ifdef MSIPL_EXCEPT
						throw length_error("deque::construction length error");
					#else
					{
						fprintf(stderr, "deque::construction length error\n");
						abort();
					}
					#endif
				if (size_ > 0)
				{
					if (alloc_.m_ < size_)
						alloc_.m_ = size_;
					pointer tmp = alloc_.allocate(alloc_.m_);
					buf_.push_back(tmp);
					start_ = (alloc_.m_ - size_) / 2;
					copy(first, last, buf_.front() + start_);
				}
			}

		template <class InputIterator>
			inline
			void
			choose_assign(InputIterator first, InputIterator last, chooser<true>)
			{
				assign(static_cast<size_type>(first), static_cast<value_type>(last));
			}

		template <class InputIterator>
			inline
			void
			choose_assign(InputIterator first, InputIterator last, chooser<false>)
			{
				do_assign(first, last, iterator_traits<InputIterator>::iterator_category());
			}

		template <class InputIterator>
			void
			do_assign(InputIterator first, InputIterator last, input_iterator_tag)
			{
				deque temp(first, last, get_allocator());
				const deque& tempr = temp;
				do_assign(tempr.begin(), tempr.end(), random_access_iterator_tag());
			}

		template <class ForwardIterator>
			void
			do_assign(ForwardIterator first, ForwardIterator last, forward_iterator_tag)
			{
				size_type n = (size_type)distance(first, last);
				if (n > max_size())
					#ifdef MSIPL_EXCEPT
						throw length_error("deque::assign length error");
					#else
					{
						fprintf(stderr, "deque::assign length error\n");
						abort();
					}
					#endif
				while (n > buf_.size() * alloc_.m_)
				{
					pointer tmp = alloc_.allocate(alloc_.m_);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						buf_.push_back(tmp);
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(tmp, alloc_.m_);
						throw;
					}
					#endif
				}
				size_ = 0;
				start_ = (buf_.size() * alloc_.m_ - n) / 2;
				while (start_ >= alloc_.m_)
				{
					alloc_.deallocate(buf_.back(), alloc_.m_);
					buf_.pop_back();
					start_ = (buf_.size() * alloc_.m_ - n) / 2;
				}
				copy(first, last, begin());
				size_ = n;
			}

		template <class InputIterator>
			inline
			void
			choose_insert(iterator position, InputIterator first, InputIterator last,
				chooser<true>)
			{
				insert(position, static_cast<size_type>(first), static_cast<value_type>(last));
			}

		template <class InputIterator>
			inline
			void
			choose_insert(iterator position, InputIterator first, InputIterator last,
				chooser<false>)
			{
				do_insert(position, first, last, iterator_traits<InputIterator>::iterator_category());
			}

		template <class InputIterator>
			void
			do_insert(iterator position, InputIterator first, InputIterator last,
				input_iterator_tag)
			{
				deque temp(first, last, get_allocator());
				const deque& tempr = temp;
				do_insert(position, tempr.begin(), tempr.end(), random_access_iterator_tag());
			}

		template <class ForwardIterator>
			void
			do_insert(iterator position, ForwardIterator first, ForwardIterator last,
				forward_iterator_tag)
			{
				size_type n = (size_type)distance(first, last);
				if (n == 0)
					return;
				size_type ms = max_size();
				if (n > ms || size_ > ms - n)
					#ifdef MSIPL_EXCEPT
						throw length_error("deque::insert length error");
					#else
					{
						fprintf(stderr, "deque::insert length error\n");
						abort();
					}
					#endif
				size_type pb = size_type(position - begin());
				size_type pe = size_type(end() - position);
				if (pb <= pe)  // hh 981210
				{
					size_type new_buffers = 0;
					size_type oldstart = start_;
					if (start_ < n)
					{
						size_type nc = n;
						nc -= start_;
						while (true)
						{
							pointer tmp = alloc_.allocate(alloc_.m_);
							#ifdef MSIPL_EXCEPT
							try
							{
							#endif
								buf_.push_front(tmp);
								++new_buffers;  // hh 981210
								start_ += alloc_.m_;
								if (nc <= alloc_.m_)
								{
									if (size_ != 0)  // hh 981210
										start_ -= n;
									else
										start_ = (buf_.size() * alloc_.m_ - n) / 2;
									break;
								}
								nc -= alloc_.m_;
							#ifdef MSIPL_EXCEPT
							}
							catch (...)
							{
								alloc_.deallocate(tmp, alloc_.m_);
								for (size_type i = 0; i < new_buffers; ++i)  // hh 981210
								{
									alloc_.deallocate(buf_.front(), alloc_.m_);
									buf_.pop_front();
								}
								start_ = oldstart;
								throw;
							}
							#endif
						}
					}
					else
						start_ -= n;
					if (pb == 0) // insert at begin()
						copy(first, last, begin());
					else // pos in [1, size_ / 2)
					{
						copy(begin() + difference_type(n),
							begin() + difference_type(n + pb), begin());
						copy(first, last, begin() + difference_type(pb));
					}
					size_ += n;
				}
				else // pos >= size_ / 2
				{
					size_type e = buf_.size() * alloc_.m_ - (start_ + size_);
					if (e < n)
					{
						size_type nc = n;
						nc -= e;
						while (true)
						{
							pointer tmp = alloc_.allocate(alloc_.m_);
							#ifdef MSIPL_EXCEPT
							try
							{
							#endif
								buf_.push_back(tmp);
								if (nc <= alloc_.m_)
									break;
								nc -= alloc_.m_;
							#ifdef MSIPL_EXCEPT
							}
							catch (...)
							{
								alloc_.deallocate(tmp, alloc_.m_);
								throw;
							}
							#endif
						}
					}
					if (pe == 0) // insert at end()
						copy(first, last, position);
					else // pos in [size_ / 2, size_)
					{
						copy_backward(position, end(), end() + difference_type(n));
						copy(first, last, position);
					}
					size_ += n;
				}
				invalidate_iterators();
			}

		void init(size_type n, const value_type& value);
		void tear_down();
		void invalidate_iterators();
	};

	// Implementation deque<void*>

	template <class Allocator>
	inline
	void
	deque<void*, Allocator>::invalidate_iterators()
	{
		while (start_ >= 3 * alloc_.m_ / 2)
		{
			alloc_.deallocate(buf_.front(), alloc_.m_);
			buf_.pop_front();
			start_ -= alloc_.m_;
		}
	}

	template <class Allocator>
	deque<void*, Allocator>::deque(const Allocator& a)
		: alloc_(a, default_bufsize_s),
		  buf_(buf_allocator(a)),
		  start_(0),
		  size_(0)
	{
	}

	template <class Allocator>
	deque<void*, Allocator>::deque(size_type n, const value_type& value, const Allocator& a)
		: alloc_(a, default_bufsize_s),
		  buf_(buf_allocator(a)),
		  start_(0),
		  size_(0)
	{
		init(n, value);
	}

	template <class Allocator>
	void
	deque<void*, Allocator>::init(size_type n, const value_type& value)
	{
		if (size_ > max_size())
			#ifdef MSIPL_EXCEPT
				throw length_error("deque::construction length error");
			#else
			{
				fprintf(stderr, "deque::construction length error\n");
				abort();
			}
			#endif
		if (n > 0)
		{
			if (alloc_.m_ < n)
				alloc_.m_ = n;
			pointer tmp = alloc_.allocate(alloc_.m_);
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				buf_.push_back(tmp);
				size_ = n;
				start_ = (alloc_.m_ - size_) / 2;
				fill_n(buf_.front() + start_, size_, value);
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				alloc_.deallocate(tmp, alloc_.m_);
				throw;
			}
			#endif
		}
	}

	template <class Allocator>
	deque<void*, Allocator>::deque(const deque<void*,Allocator>& x)
		: alloc_(x.alloc_, default_bufsize_s),
		  buf_(buf_allocator(alloc_)),
		  start_(0),
		  size_(x.size_)
	{
		if (size_ > 0)
		{
			if (alloc_.m_ < size_)
				alloc_.m_ = size_;
			pointer tmp = alloc_.allocate(alloc_.m_);
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				buf_.push_back(tmp);
				start_ = (alloc_.m_ - size_) / 2;
				copy(x.begin(), x.end(), buf_.front() + start_);
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				alloc_.deallocate(tmp, alloc_.m_);
				throw;
			}
			#endif
		}
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::~deque()
	{
		tear_down();
	}

	template <class Allocator>
	void
	deque<void*, Allocator>::tear_down()
	{
		for (size_type i = 0; i < buf_.size(); ++i)
			alloc_.deallocate(buf_[i], alloc_.m_);
	}

	template <class Allocator>
	deque<void*,Allocator>&
	deque<void*, Allocator>::operator=(const deque<void*,Allocator>& x)
	{
		if (this != &x)
			assign(x.begin(), x.end());
		return *this;
	}

	template <class Allocator>
	void
	deque<void*, Allocator>::assign(size_type n, const value_type& t)
	{
		if (n > max_size())
			#ifdef MSIPL_EXCEPT
				throw length_error("deque::assign length error");
			#else
			{
				fprintf(stderr, "deque::assign length error\n");
				abort();
			}
			#endif
		while (n > buf_.size() * alloc_.m_)
		{
			pointer tmp = alloc_.allocate(alloc_.m_);
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				buf_.push_back(tmp);
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				alloc_.deallocate(tmp, alloc_.m_);
				throw;
			}
			#endif
		}
		start_ = (buf_.size() * alloc_.m_ - n) / 2;
		while (start_ >= alloc_.m_)
		{
			alloc_.deallocate(buf_.back(), alloc_.m_);
			buf_.pop_back();
			start_ = (buf_.size() * alloc_.m_ - n) / 2;
		}
		fill_n(begin(), n, t);
		size_ = n;
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::allocator_type
	deque<void*, Allocator>::get_allocator() const
	{
		return alloc_;
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::iterator
	deque<void*, Allocator>::begin()
	{
		return iterator(this, start_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::const_iterator
	deque<void*, Allocator>::begin() const
	{
		return const_iterator(this, start_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::iterator
	deque<void*, Allocator>::end()
	{	
		return iterator(this, start_ + size_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::const_iterator
	deque<void*, Allocator>::end() const
	{	
		return const_iterator(this, start_ + size_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::reverse_iterator
	deque<void*, Allocator>::rbegin()
	{
		return reverse_iterator(end());
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::const_reverse_iterator
	deque<void*, Allocator>::rbegin() const
	{
		return const_reverse_iterator(end());
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::reverse_iterator
	deque<void*, Allocator>::rend()
	{
		return reverse_iterator(begin());
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::const_reverse_iterator
	deque<void*, Allocator>::rend() const
	{
		return const_reverse_iterator(begin());
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::size_type
	deque<void*, Allocator>::size() const
	{
		return size_;
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::size_type
	deque<void*, Allocator>::max_size() const
	{
		return alloc_.max_size();
	}

	template <class Allocator>
	void
	deque<void*, Allocator>::resize(size_type sz, value_type c)
	{
		if (sz > size())
			insert(end(), sz-size(), c);
		else if (sz < size())
			erase(begin() + difference_type(sz), end());
	}

	template <class Allocator>
	inline
	bool
	deque<void*, Allocator>::empty() const
	{
		return size_ == 0;
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::reference
	deque<void*, Allocator>::operator[](size_type n)
	{
		size_type i = n + start_;
		return *(buf_[i / alloc_.m_] + i % alloc_.m_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::const_reference
	deque<void*, Allocator>::operator[](size_type n) const
	{
		size_type i = n + start_;
		return *(buf_[i / alloc_.m_] + i % alloc_.m_);
	}

	template <class Allocator>
	deque<void*, Allocator>::reference
	deque<void*, Allocator>::at(size_type n)
	{
		if (n >= size_)
			#ifdef MSIPL_EXCEPT
				throw out_of_range("deque::at index out of range");
			#else
			{
				fprintf(stderr, "deque::at index out of range");
				abort();
			}
			#endif
		size_type i = n + start_;
		return *(buf_[i / alloc_.m_] + i % alloc_.m_);
	}

	template <class Allocator>
	deque<void*, Allocator>::const_reference
	deque<void*, Allocator>::at(size_type n) const
	{
		if (n >= size_)
			#ifdef MSIPL_EXCEPT
				throw out_of_range("deque::at index out of range");
			#else
			{
				fprintf(stderr, "deque::at index out of range");
				abort();
			}
			#endif
		size_type i = n + start_;
		return *(buf_[i / alloc_.m_] + i % alloc_.m_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::reference
	deque<void*, Allocator>::front()
	{
		return *(buf_[start_ / alloc_.m_] + start_ % alloc_.m_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::const_reference
	deque<void*, Allocator>::front() const
	{
		return *(buf_[start_ / alloc_.m_] + start_ % alloc_.m_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::reference
	deque<void*, Allocator>::back()
	{
		size_type i = start_ + size_ - 1;
		return *(buf_[i / alloc_.m_] + i % alloc_.m_);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::const_reference
	deque<void*, Allocator>::back() const
	{
		size_type i = start_ + size_ - 1;
		return *(buf_[i / alloc_.m_] + i % alloc_.m_);
	}

	template <class Allocator>
	inline
	void
	deque<void*, Allocator>::push_front(const value_type& x)
	{
		insert(begin(), x);
	}

	template <class Allocator>
	inline
	void
	deque<void*, Allocator>::push_back(const value_type& x)
	{
		insert(end(), x);
	}

	template <class Allocator>
	deque<void*, Allocator>::iterator
	deque<void*, Allocator>::insert(iterator position, const value_type& x)
	{
		difference_type pos = position - begin();
		insert(position, 1, x);
		return begin() + pos;
	}

	template <class Allocator>
	void
	deque<void*, Allocator>::insert(iterator position, size_type n, const value_type& x)
	{
		if (n == 0)
			return;
		size_type ms = max_size();
		if (n > ms || size_ > ms - n)
			#ifdef MSIPL_EXCEPT
				throw length_error("deque::insert length error");
			#else
			{
				fprintf(stderr, "deque::insert length error\n");
				abort();
			}
			#endif
		size_type pb = size_type(position - begin());
		size_type pe = size_type(end() - position);
		if (pb <= pe)  // hh 981210
		{
			size_type new_buffers = 0;
			size_type oldstart = start_;
			if (start_ < n)
			{
				size_type nc = n;
				nc -= start_;
				while (true)
				{
					pointer tmp = alloc_.allocate(alloc_.m_);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						buf_.push_front(tmp);
						++new_buffers;  // hh 981210
						start_ += alloc_.m_;
						if (nc <= alloc_.m_)
						{
							if (size_ != 0)  // hh 981210
								start_ -= n;
							else
								start_ = (buf_.size() * alloc_.m_ - n) / 2;
							break;
						}
						nc -= alloc_.m_;
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(tmp, alloc_.m_);
						for (size_type i = 0; i < new_buffers; ++i)  // hh 981210
						{
							alloc_.deallocate(buf_.front(), alloc_.m_);
							buf_.pop_front();
						}
						start_ = oldstart;
						throw;
					}
					#endif
				}
			}
			else
				start_ -= n;
			if (pb == 0) // insert at begin()
				fill_n(begin(), n, x);
			else // pos in [1, size_ / 2)
			{
				copy(begin() + difference_type(n),
					begin() + difference_type(n + pb), begin());
				fill_n(begin() + difference_type(pb), n, x);
			}
			size_ += n;
		}
		else // pos >= size_ / 2
		{
			size_type e = buf_.size() * alloc_.m_ - (start_ + size_);
			if (e < n)
			{
				size_type nc = n;
				nc -= e;
				while (true)
				{
					pointer tmp = alloc_.allocate(alloc_.m_);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						buf_.push_back(tmp);
						if (nc <= alloc_.m_)
							break;
						nc -= alloc_.m_;
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(tmp, alloc_.m_);
						throw;
					}
					#endif
				}
			}
			if (pe == 0) // insert at end()
				fill_n(position, n, x);
			else // pos in [size_ / 2, size_)
			{
				copy_backward(position, end(), end() + difference_type(n));
				fill_n(position, n, x);
			}
			size_ += n;
		}
		invalidate_iterators();
	}

	template <class Allocator>
	inline
	void
	deque<void*, Allocator>::pop_front()
	{
		erase(begin());
	}

	template <class Allocator>
	inline
	void
	deque<void*, Allocator>::pop_back()
	{
		erase(end() - 1);
	}

	template <class Allocator>
	inline
	deque<void*, Allocator>::iterator
	deque<void*, Allocator>::erase(iterator position)
	{
		return erase(position, position + 1);
	}

	template <class Allocator>
	deque<void*, Allocator>::iterator
	deque<void*, Allocator>::erase(iterator first, iterator last)
	{
		if (first == last)
			return first;
		const size_type pb = size_type(first - begin());
		const size_type pe = size_type(end() - last);
		const size_type diff = size_type(last - first);
		if (pb < pe)
		{
			if (pb == 0)  // erase from beginning, no copying necessary
			{
				start_ += diff;
				size_ -= diff;
			}
			else  // erase from beginning, needs copying
			{
				copy_backward(begin(), first, last);
				start_ += diff;
				size_ -= diff;
				invalidate_iterators();
			}
		}
		else  // pb >= pe - erase from end
		{
			if (pe != 0)  // erase from end, needs copying
			{
				copy(last, end(), first);
				invalidate_iterators();
			}
			size_ -= diff;
			while (buf_.size() * alloc_.m_ - (start_ + size_) >= 3 * alloc_.m_ / 2)
			{
				alloc_.deallocate(buf_.back(), alloc_.m_);
				buf_.pop_back();
			}
		}
		if (size_ == 0)
		{
			for (size_type i = buf_.size() - 1; i > 0; --i)
			{
				alloc_.deallocate(buf_.back(), alloc_.m_);
				buf_.pop_back();
			}
			start_ = alloc_.m_ / 2;
		}
		return iterator(this, start_ + pb);
	}

	template <class Allocator>
	void
	deque<void*, Allocator>::swap(deque<void*,Allocator>& x)
	{
		if (this != &x)
		{
			_STD::swap(alloc_, x.alloc_);
			_STD::swap(buf_, x.buf_);
			_STD::swap(start_, x.start_);
			_STD::swap(size_, x.size_);
		}
	}

	template <class Allocator>
	void
	deque<void*, Allocator>::clear()
	{
		if (!buf_.empty())  // hh 981209
		{
			size_ = 0;
			for (size_type i = buf_.size() - 1; i > 0; --i)
			{
				alloc_.deallocate(buf_.back(), alloc_.m_);
				buf_.pop_back();
			}
			start_ = alloc_.m_ / 2;
		}
	}

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

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

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

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

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

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

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

	// T*

	template <class T, class Allocator>
	class deque<T*, Allocator>
		: private deque<void*, Allocator::rebind<void*>::other>
	{
		typedef deque<void*, Allocator::rebind<void*>::other> base;
		typedef base::allocator_type base_allocator;
	public:
		// types:
		typedef typename Allocator::reference         reference;
		typedef typename Allocator::const_reference   const_reference;
		class                                         iterator;
		class                                         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;

		class iterator
			: public _STD::iterator<random_access_iterator_tag, value_type,
				difference_type, pointer, reference>
		{
		public:
			iterator() {}
			explicit iterator(const base::iterator& i) : i_(i) {}
			operator base::iterator() const {return i_;}
			reference operator * () const {return reference(*i_);}
			pointer operator -> () const {return pointer(i_.operator->());}
			iterator& operator ++ () {++i_; return *this;}
			iterator operator ++ (int) {iterator tmp(*this); ++i_; return tmp;}
			iterator& operator -- () {--i_; return *this;}
			iterator operator -- (int) {iterator tmp(*this); --i_; return tmp;}
			iterator& operator += (difference_type n) {i_ += n; return *this;}
			iterator operator + (difference_type n) const {return iterator(*this) += n;}
			iterator& operator -= (difference_type n) {i_ -= n; return *this;}
			iterator operator - (difference_type n) const {return iterator(*this) -= n;}
			difference_type operator - (const iterator& rhs) const {return i_ - rhs.i_;}
			reference operator [] (size_type i) const {return reference(i_[i]);}
			bool operator ==(const iterator& rhs) const {return i_ == rhs.i_;}
			bool operator !=(const iterator& rhs) const {return i_ != rhs.i_;}
			bool operator < (const iterator& rhs) const {return i_ <  rhs.i_;}
			bool operator <=(const iterator& rhs) const {return i_ <= rhs.i_;}
			bool operator > (const iterator& rhs) const {return i_ >  rhs.i_;}
			bool operator >=(const iterator& rhs) const {return i_ >= rhs.i_;}
			friend iterator operator + (difference_type n, const iterator& rhs)
				{return iterator(rhs) += n;}
		private:
			base::iterator i_;

			friend deque::const_iterator;
		};

		class const_iterator
			: public _STD::iterator<random_access_iterator_tag, value_type,
				difference_type, const_pointer, const_reference>
		{
		public:
			const_iterator() {}
			const_iterator(const deque::iterator& rhs) : i_(rhs.i_) {}
			explicit const_iterator(const base::const_iterator& i) : i_(i) {}
			operator base::const_iterator() const {return i_;}
			const_reference operator * () const {return const_reference(*i_);}
			const_pointer operator -> () const {return const_pointer(i_.operator->());}
			const_iterator& operator ++ () {++i_; return *this;}
			const_iterator operator ++ (int) {const_iterator tmp(*this); ++i_; return tmp;}
			const_iterator& operator -- () {--i_; return *this;}
			const_iterator operator -- (int) {const_iterator tmp(*this); --i_; return tmp;}
			const_iterator& operator += (difference_type n) {i_ += n; return *this;}
			const_iterator operator + (difference_type n) const {return const_iterator(*this) += n;}
			const_iterator& operator -= (difference_type n) {i_ -= n; return *this;}
			const_iterator operator - (difference_type n) const {return const_iterator(*this) -= n;}
			difference_type operator - (const const_iterator& rhs) const {return i_ - rhs.i_;}
			const_reference operator [] (size_type i) const {return const_reference(i_[i]);}
			bool operator ==(const const_iterator& rhs) const {return i_ == rhs.i_;}
			bool operator !=(const const_iterator& rhs) const {return i_ != rhs.i_;}
			bool operator < (const const_iterator& rhs) const {return i_ <  rhs.i_;}
			bool operator <=(const const_iterator& rhs) const {return i_ <= rhs.i_;}
			bool operator > (const const_iterator& rhs) const {return i_ >  rhs.i_;}
			bool operator >=(const const_iterator& rhs) const {return i_ >= rhs.i_;}
			friend const_iterator operator + (difference_type n, const const_iterator& rhs)
				{return const_iterator(rhs) += n;}
		private:
			base::const_iterator i_;
		};

		// _lib.deque.cons_ construct/copy/destroy:
		explicit deque(const Allocator& = Allocator());
		explicit deque(size_type n, const value_type& value = 0, const Allocator& = Allocator());
		template <class InputIterator>
			inline
			deque(InputIterator first, InputIterator last, const Allocator& a = Allocator())
				: base(first, last, base_allocator(a))
			{
			}
		template <class InputIterator>
			inline
			void assign(InputIterator first, InputIterator last)
			{
				base::assign(first, last);
			}
		void assign(size_type n, const value_type& t);
		allocator_type get_allocator() const;
		// iterators:
		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;
		// _lib.deque.capacity_ capacity:
		size_type size() const;
		size_type max_size() const;
		void      resize(size_type sz, value_type c = 0);
		bool      empty() const;

		// element access:
		reference       operator[](size_type n);
		const_reference operator[](size_type n) const;
		reference       at(size_type n);
		const_reference at(size_type n) const;
		reference       front();
		const_reference front() const;
		reference       back();
		const_reference back() const;
		// _lib.deque.modifiers_ modifiers:
		void push_front(const value_type& x);
		void push_back(const value_type& x);
		iterator insert(iterator position, const value_type& x);
		void     insert(iterator position, size_type n, const value_type& x);
		template <class InputIterator>
			void insert(iterator position, InputIterator first, InputIterator last)
			{
				base::insert(position, first, last);
			}
		void pop_front();
		void pop_back();
		iterator erase(iterator position);
		iterator erase(iterator first, iterator last);
		void     swap(deque<T*,Allocator>&);
		void     clear();
	};

	// Implementation deque<T*>

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::deque(const Allocator& a)
		: base(base_allocator(a))
	{
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::deque(size_type n, const value_type& value, const Allocator& a)
		: base(n, value, base_allocator(a))
	{
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::assign(size_type n, const value_type& t)
	{
		base::assign(n, t);
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::allocator_type
	deque<T*, Allocator>::get_allocator() const
	{
		return base::get_allocator();
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::iterator
	deque<T*, Allocator>::begin()
	{
		return iterator(base::begin());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::const_iterator
	deque<T*, Allocator>::begin() const
	{
		return const_iterator(base::begin());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::iterator
	deque<T*, Allocator>::end()
	{	
		return iterator(base::end());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::const_iterator
	deque<T*, Allocator>::end() const
	{	
		return const_iterator(base::end());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::reverse_iterator
	deque<T*, Allocator>::rbegin()
	{
		return reverse_iterator(end());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::const_reverse_iterator
	deque<T*, Allocator>::rbegin() const
	{
		return const_reverse_iterator(end());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::reverse_iterator
	deque<T*, Allocator>::rend()
	{
		return reverse_iterator(begin());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::const_reverse_iterator
	deque<T*, Allocator>::rend() const
	{
		return const_reverse_iterator(begin());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::size_type
	deque<T*, Allocator>::size() const
	{
		return base::size();
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::size_type
	deque<T*, Allocator>::max_size() const
	{
		return base::max_size();
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::resize(size_type sz, value_type c)
	{
		base::resize(sz, c);
	}

	template <class T, class Allocator>
	inline
	bool
	deque<T*, Allocator>::empty() const
	{
		return base::empty();
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::reference
	deque<T*, Allocator>::operator[](size_type n)
	{
		return reference(base::operator[](n));
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::const_reference
	deque<T*, Allocator>::operator[](size_type n) const
	{
		return const_reference(base::operator[](n));
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::reference
	deque<T*, Allocator>::at(size_type n)
	{
		return reference(base::at(n));
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::const_reference
	deque<T*, Allocator>::at(size_type n) const
	{
		return const_reference(base::at(n));
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::reference
	deque<T*, Allocator>::front()
	{
		return reference(base::front());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::const_reference
	deque<T*, Allocator>::front() const
	{
		return const_reference(base::front());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::reference
	deque<T*, Allocator>::back()
	{
		return reference(base::back());
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::const_reference
	deque<T*, Allocator>::back() const
	{
		return const_reference(base::back());
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::push_front(const value_type& x)
	{
		base::push_front(x);
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::push_back(const value_type& x)
	{
		base::push_back(x);
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::iterator
	deque<T*, Allocator>::insert(iterator position, const value_type& x)
	{
		return iterator(base::insert(position, x));
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::insert(iterator position, size_type n, const value_type& x)
	{
		base::insert(position, n, x);
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::pop_front()
	{
		base::pop_front();
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::pop_back()
	{
		base::pop_back();
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::iterator
	deque<T*, Allocator>::erase(iterator position)
	{
		return iterator(base::erase(position));
	}

	template <class T, class Allocator>
	inline
	deque<T*, Allocator>::iterator
	deque<T*, Allocator>::erase(iterator first, iterator last)
	{
		return iterator(base::erase(first, last));
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::swap(deque<T*,Allocator>& x)
	{
		base::swap((base&)x);
	}

	template <class T, class Allocator>
	inline
	void
	deque<T*, Allocator>::clear()
	{
		base::clear();
	}

	template <class T, class Allocator>
	inline
	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>
	inline
	bool
	operator!=(const deque<T*,Allocator>& x, const deque<T*,Allocator>& y)
	{
		return !(x == y);
	}

	template <class T, class Allocator>
	inline
	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>
	inline
	bool
	operator> (const deque<T*,Allocator>& x, const deque<T*,Allocator>& y)
	{
		return y < x;
	}

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

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

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

#endif // defined(MSIPL_PARTIAL_SPECIALIZATION) && defined(MSIPL_MEMBER_TEMPLATE) && !defined(_Inhibit_Container_Optimization)

#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 // _DEQUE

// hh 971220 fixed MOD_INCLUDE
// hh 971221 Changed filename from deque.h to deque
// hh 971221 Made include guards standard
// hh 971221 Added qualified name to const_iterator
// hh 971221 Added qualified name to iterator
// hh 971230 added RC_INVOKED wrapper
// hh 980105 changed pointer & reference to const versions in const_iterator base class
// hh 980105 rewrote some constructors to get rid of unused arg dq warning
// hh 980111 <string> added so deque could throw a stdexcept
// hh 980111 made at and operator[] standard compliant
// hh 980713 Temporarily moved member templates into class definition to support compiler
// hh 980902 #ifdef'd out exception code when ndef MSIPL_EXCEPT
// hh 981027 rewrote
// hh 981208 changed static_cast to reinterpret_cast on the value_type (pointer specialization only)
// hh 981209 Protected clear() from an empty buf_
// hh 981210 Modified insertion into front half to preserve outstanding iterators under exceptions
//           and made it more efficient when the initial size is zero.
// hh 981210 Added forgotten for loop in insert
