/*  Metrowerks Standard Library  Version 4.0  1998 Sep 28  */

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

/**
 **  cdeque
 **/

// WARNING
//
// cdeque is a non-standard, non-portable header and container.
//
// WARNING
//
// It's purpose here is to aid in the implementation of deque.
// cdeque is very similar to deque except that it has capacity
// and reserve methods like vector.  It guarantees amoritized
// constant time push_front and push_back, but it may invalidate
// references (when capacity is increased) during these operations.
//
// cdeque is short for "circular deque".  It is implemented with
// a contiguous chunk of memory like vector.  vector elements always
// start at the low memory address, and there is an uninitialized chunk
// of reserve memory at the high end to grow into.  In contrast, cdeque
// maps the memory into a circular path.  The first element can start
// anywhere on the circle, and the reserve memory extends from beyond
// the last element up to the first element.  That is:
// In use     : [first, last)
// In reserve : [last, first)
//

#ifndef _CDEQUE
#define _CDEQUE

#include <mcompile.h>

#include <climits>
#include <algorithm>
#include <iterator>
#include <limits>
#include <memory>
#include <new>
#include <stdexcept>
#include <string>

#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 DEFTEMPARG(Allocator, allocator<T>)>
class __cdeque
{
	#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;

	class iterator
		: public _STD::iterator<random_access_iterator_tag, value_type,
			difference_type, pointer, reference>
	{
	public:
		iterator() {}
		reference operator * () const {return (*cdeq_)[pos_];}
		pointer operator -> () const {return &(*cdeq_)[pos_];}
		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 {return (*cdeq_)[pos_ + i];}
		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:
		__cdeque* cdeq_;
		size_type pos_;

		iterator(__cdeque* cdeq, size_type pos)
			: cdeq_(cdeq),
			  pos_(pos)
		{}

		friend class __cdeque;
		friend class __cdeque::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 __cdeque::iterator& rhs) : cdeq_(rhs.cdeq_), pos_(rhs.pos_) {}
		const_reference operator * () const {return (*cdeq_)[pos_];}
		const_pointer operator -> () const {return &(*cdeq_)[pos_];}
		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 {return (*cdeq_)[pos_ + i];}
		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 __cdeque* cdeq_;
		size_type pos_;

		const_iterator(const __cdeque* cdeq, size_type pos)
			: cdeq_(cdeq),
			  pos_(pos)
		{}

		friend class __cdeque;
	};

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

	// element access:
	reference       operator[](size_type n);
	const_reference operator[](size_type n) const;
	const_reference at(size_type n) const;
	reference       at(size_type n);
	reference       front();
	const_reference front() const;
	reference       back();
	const_reference back() const;
	// cdeque.modifiers_ modifiers:
	void push_front(const T& x);
	void push_back(const T& x);
	void pop_front();
	void pop_back();
	iterator insert(iterator position, const T& x);
	void     insert(iterator position, size_type n, const T& x);
	#ifdef MSIPL_MEMBER_TEMPLATE
		template <class InputIterator>
			inline
			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
	iterator erase(iterator position);
	iterator erase(iterator first, iterator last);
	void     swap(__cdeque<T,Allocator>&);
	void     clear();
private:
	_EmptyMemberOpt<Allocator, size_type> alloc_;  // m_ is capacity
	size_type size_;
	size_type start_;
	pointer data_;

	#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_ = alloc_.m_ = (size_type)distance(first, last);
				if (size_ > max_size())
					#ifdef MSIPL_EXCEPT
						throw length_error("cdeque::construction length error");
					#else
					{
						fprintf(stderr, "cdeque::construction length error\n");
						abort();
					}
					#endif
				if (alloc_.m_ > 0)
				{
					data_ = alloc_.allocate(alloc_.m_);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						uninitialized_copy(first, last, data_);
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(data_, 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)
			{
				__cdeque temp(first, last, get_allocator());
				const __cdeque& 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("cdeque::assign length error");
					#else
					{
						fprintf(stderr, "cdeque::assign length error\n");
						abort();
					}
					#endif
				if (n <= capacity())
				{
					difference_type n1 = (difference_type)min(n, size_);
					iterator i = begin();
					iterator e = i + n1;
					for (; i < e; ++i, ++first)
						*i = *first;
					if (n < size_)
						destroy(i, end());
					else if (size_ < n)
						uninitialized_copy(first, last, i);
					size_ = n;
				}
				else
				{
					pointer newdata = alloc_.allocate(n);
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						uninitialized_copy(first, last, newdata);
						tear_down();
						data_ = newdata;
						size_ = alloc_.m_ = n;
						start_ = 0;
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						alloc_.deallocate(newdata, n);
						throw;
					}
					#endif
				}
			}

		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)
			{
				__cdeque temp(first, last, get_allocator());
				const __cdeque& 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("cdeque::insert length error");
					#else
					{
						fprintf(stderr, "cdeque::insert length error\n");
						abort();
					}
					#endif
				if (size_ + n <= capacity())
				{
					size_type pb = size_type(position - begin());
					size_type pe = size_type(end() - position);
					if (pb < pe)
					{
						size_type oldstart = start_;
						if (start_ >= n)
							start_ -= n;
						else
							start_ = alloc_.m_ - (n - start_);
						#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)
										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 (...)
						{
							start_ = oldstart;
							throw;
						}
						#endif
					}
					else // pos >= size_ / 2
					{
						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;
					}
				}
				else // size_ + n > capacity()
				{
					size_type newsize = size_ + n;
					size_type newcap = max(alloc_.m_, size_type(1));
					while (newsize > newcap)
						newcap *= 2;
					size_type pos = size_type(position - begin());
					pointer newdata = alloc_.allocate(newcap);
					size_type done = 0;
					#ifdef MSIPL_EXCEPT
					try
					{
					#endif
						if (pos > 0)
						{
							uninitialized_copy(begin(), position, newdata);
							done = pos;
						}
						uninitialized_copy(first, last, newdata + pos);
						done += n;
						if (pos < size_)
							uninitialized_copy(position, end(), newdata + pos + n);
						tear_down();
						data_ = newdata;
						size_ = newsize;
						alloc_.m_ = newcap;
						start_ = 0;
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						_STD::destroy(newdata, newdata + done);
						alloc_.deallocate(newdata, newcap);
						throw;
					}
					#endif
				}
			}

	#endif

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

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

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

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

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

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

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

// specialized algorithms:
template <class T, class Allocator>
void
swap(__cdeque<T,Allocator>& x, __cdeque<T,Allocator>& y);

// Implementation __cdeque

template <class T, class Allocator>
inline
__cdeque<T, Allocator>::__cdeque(const Allocator& a)
	: alloc_(a),
	  size_(0),
	  start_(0),
	  data_(0)
{
}

template <class T, class Allocator>
inline
__cdeque<T, Allocator>::__cdeque(size_type n, const T& value, const Allocator& a)
	: alloc_(a),
	  size_(0),
	  start_(0),
	  data_(0)
{
	init(n, value);
}	  

template <class T, class Allocator>
__cdeque<T, Allocator>::__cdeque(const __cdeque<T,Allocator>& x)
	: alloc_(x.alloc_, x.size_),
	  size_(x.size_),
	  start_(0),
	  data_(0)
{
	if (alloc_.m_ > 0)
	{
		data_ = alloc_.allocate(alloc_.m_);
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			uninitialized_copy(x.begin(), x.end(), data_);
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			alloc_.deallocate(data_, alloc_.m_);
			throw;
		}
		#endif
	}
}

#ifndef MSIPL_MEMBER_TEMPLATE

	template <class T, class Allocator>
	__cdeque<T, Allocator>::__cdeque(const_iterator first, const_iterator last, const Allocator& a)
		: alloc_(a, size_type(last - first)),
		  size_(alloc_.m_),
		  start_(0),
		  data_(0)
	{
		if (alloc_.m_ > max_size())
			#ifdef MSIPL_EXCEPT
				throw length_error("cdeque::construction length error");
			#else
			{
				fprintf(stderr, "cdeque::construction length error\n");
				abort();
			}
			#endif
		if (alloc_.m_ > 0)
		{
			data_ = alloc_.allocate(alloc_.m_);
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				uninitialized_copy(first, last, data_);
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				alloc_.deallocate(data_, alloc_.m_);
				throw;
			}
			#endif
		}
	}

#endif

template <class T, class Allocator>
void
__cdeque<T, Allocator>::init(size_type n, const T& value)
{
	if (n > max_size())
		#ifdef MSIPL_EXCEPT
			throw length_error("cdeque::construction length error");
		#else
		{
			fprintf(stderr, "cdeque::construction length error\n");
			abort();
		}
		#endif
	if (n > 0)
	{
		size_ = alloc_.m_ = n;
		data_ = alloc_.allocate(n);
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			uninitialized_fill_n(data_, size_, value);
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			alloc_.deallocate(data_, n);
			throw;
		}
		#endif
	}
}

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

template <class T, class Allocator>
void
__cdeque<T, Allocator>::tear_down()
{
	if (data_ != 0)
	{
		destroy(begin(), end());
		alloc_.deallocate(data_, alloc_.m_);
	}
}

template <class T, class Allocator>
void
__cdeque<T, Allocator>::destroy(iterator first, iterator last)
{
	if (first != last)
	{
		size_type diff = size_type(last - first);
		size_type e = start_ + diff;
		if (e > alloc_.m_)
		{
			e = alloc_.m_;
			_STD::destroy(data_ + start_, data_ + e);
			e = start_ + diff - alloc_.m_;
			_STD::destroy(data_, data_ + e);
		}
		else
			_STD::destroy(data_ + start_, data_ + e);
	}
}

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

#ifndef MSIPL_MEMBER_TEMPLATE

	template <class T, class Allocator>
	void
	__cdeque<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("cdeque::assign length error");
			#else
			{
				fprintf(stderr, "cdeque::assign length error\n");
				abort();
			}
			#endif
		if (n <= capacity())
		{
			size_type n1 = min(n, size_);
			iterator i = begin();
			iterator e = i + n1;
			for (; i < e; ++i, ++first)
				*i = *first;
			if (n < size_)
				destroy(i, end());
			else if (size_ < n)
				uninitialized_copy(first, last, i);
			size_ = n;
		}
		else
		{
			pointer newdata = alloc_.allocate(n);
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				uninitialized_copy(first, last, newdata);
				tear_down();
				data_ = newdata;
				size_ = alloc_.m_ = n;
				start_ = 0;
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				alloc_.deallocate(newdata, n);
				throw;
			}
			#endif
		}
	}

#endif

template <class T, class Allocator>
void
__cdeque<T, Allocator>::assign(size_type n, const T& u)
{
	if (n > max_size())
		#ifdef MSIPL_EXCEPT
			throw length_error("cdeque::assign length error");
		#else
		{
			fprintf(stderr, "cdeque::assign length error\n");
			abort();
		}
		#endif
	if (n <= capacity())
	{
		difference_type n1 = (difference_type)min(n, size_);
		iterator i = begin();
		iterator e = i + n1;
		for (; i < e; ++i)
			*i = u;
		if (n < size_)
			destroy(i, end());
		else if (size_ < n)
			uninitialized_fill(i, begin() + difference_type(n), u);
		size_ = n;
	}
	else
	{
		pointer newdata = alloc_.allocate(n);
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			uninitialized_fill_n(newdata, n, u);
			tear_down();
			data_ = newdata;
			size_ = alloc_.m_ = n;
			start_ = 0;
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			alloc_.deallocate(newdata, n);
			throw;
		}
		#endif
	}
}

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

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

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

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

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

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

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

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

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

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

template <class T, class Allocator>
__cdeque<T, Allocator>::size_type
__cdeque<T, Allocator>::max_size() const
{
	size_type ma = alloc_.max_size();
	size_type mx = numeric_limits<size_type>::max() / 2;
	return min(ma, mx);
}

template <class T, class Allocator>
void
__cdeque<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
__cdeque<T, Allocator>::size_type
__cdeque<T, Allocator>::capacity() const
{
	return alloc_.m_;
}

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

template <class T, class Allocator>
void
__cdeque<T, Allocator>::reserve(size_type n)
{
	if (n > max_size())
		#ifdef MSIPL_EXCEPT
			throw length_error("cdeque::reserve length error");
		#else
		{
			fprintf(stderr, "cdeque::reserve length error\n");
			abort();
		}
		#endif
	if (n > capacity())
	{
		pointer newdata = alloc_.allocate(n);
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			if (data_ != 0)
			{
				uninitialized_copy(begin(), end(), newdata);
				tear_down();
			}
			alloc_.m_ = n;
			data_ = newdata;
			start_ = 0;
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			alloc_.deallocate(newdata, n);
			throw;
		}
		#endif
	}
}

template <class T, class Allocator>
__cdeque<T, Allocator>::reference
__cdeque<T, Allocator>::operator[](size_type n)
{
	n += start_;
	if (n >= alloc_.m_)
		n -= alloc_.m_;
	return *(data_ + n);
}

template <class T, class Allocator>
__cdeque<T, Allocator>::const_reference
__cdeque<T, Allocator>::operator[](size_type n) const
{
	n += start_;
	if (n >= alloc_.m_)
		n -= alloc_.m_;
	return *(data_ + n);
}

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

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

template <class T, class Allocator>
inline
__cdeque<T, Allocator>::reference
__cdeque<T, Allocator>::front()
{
	return *(data_ + start_);
}

template <class T, class Allocator>
inline
__cdeque<T, Allocator>::const_reference
__cdeque<T, Allocator>::front() const
{
	return *(data_ + start_);
}

template <class T, class Allocator>
inline
__cdeque<T, Allocator>::reference
__cdeque<T, Allocator>::back()
{
	return (*this)[size_ - 1];
}

template <class T, class Allocator>
inline
__cdeque<T, Allocator>::const_reference
__cdeque<T, Allocator>::back() const
{
	return (*this)[size_ - 1];
}

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

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

template <class T, class Allocator>
void
__cdeque<T, Allocator>::pop_front()
{	
	alloc_.destroy(data_ + start_);
	--size_;
	++start_;
	if (start_ >= alloc_.m_)
		start_ -= alloc_.m_;
}

template <class T, class Allocator>
void
__cdeque<T, Allocator>::pop_back()
{	
	alloc_.destroy(&*(end() - 1));
	--size_;
}

template <class T, class Allocator>
inline
__cdeque<T, Allocator>::iterator
__cdeque<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
__cdeque<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("cdeque::insert length error");
		#else
		{
			fprintf(stderr, "cdeque::insert length error\n");
			abort();
		}
		#endif
	if (size_ + n <= capacity())
	{
		size_type pb = size_type(position - begin());
		size_type pe = size_type(end() - position);
		if (pb < pe)
		{
			size_type oldstart = start_;
			if (start_ >= n)
				start_ -= n;
			else
				start_ = alloc_.m_ - (n - start_);
			#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);
					#ifdef MSIPL_EXCEPT
					}
					catch (...)
					{
						destroy(begin(), begin() + difference_type(done));
						throw;
					}
					#endif
				}
				size_ += n;
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				start_ = oldstart;
				throw;
			}
			#endif
		}
		else // pos >= size_ / 2
		{
			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;
		}
	}
	else // size_ + n > capacity()
	{
		size_type newsize = size_ + n;
		size_type newcap = max(alloc_.m_, size_type(1));
		while (newsize > newcap)
			newcap *= 2;
		size_type pos = size_type(position - begin());
		pointer newdata = alloc_.allocate(newcap);
		size_type done = 0;
		#ifdef MSIPL_EXCEPT
		try
		{
		#endif
			if (pos > 0)
			{
				uninitialized_copy(begin(), position, newdata);
				done = pos;
			}
			uninitialized_fill_n(newdata + pos, n, x);
			done += n;
			if (pos < size_)
				uninitialized_copy(position, end(), newdata + pos + n);
			tear_down();
			data_ = newdata;
			size_ = newsize;
			alloc_.m_ = newcap;
			start_ = 0;
		#ifdef MSIPL_EXCEPT
		}
		catch (...)
		{
			_STD::destroy(newdata, newdata + done);
			alloc_.deallocate(newdata, newcap);
			throw;
		}
		#endif
	}
}

#ifndef MSIPL_MEMBER_TEMPLATE

	template <class T, class Allocator>
	void
	__cdeque<T, Allocator>::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("cdeque::insert length error");
			#else
			{
				fprintf(stderr, "cdeque::insert length error\n");
				abort();
			}
			#endif
		if (size_ + n <= capacity())
		{
			size_type pb = size_type(position - begin());
			size_type pe = size_type(end() - position);
			if (pb < pe)
			{
				size_type oldstart = start_;
				if (start_ >= n)
					start_ -= n;
				else
					start_ = alloc_.m_ - (n - start_);
				#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());
						#ifdef MSIPL_EXCEPT
						try
						{
						#endif
							if (n < pb)
								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() + done);
							throw;
						}
						#endif
					}
					size_ += n;
				#ifdef MSIPL_EXCEPT
				}
				catch (...)
				{
					start_ = oldstart;
					throw;
				}
				#endif
			}
			else // pos >= size_ / 2
			{
				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;
			}
		}
		else // size_ + n > capacity()
		{
			size_type newsize = size_ + n;
			size_type newcap = max(alloc_.m_, 1);
			while (newsize > newcap)
				newcap *= 2;
			size_type pos = size_type(position - data_);
			pointer newdata = alloc_.allocate(newcap);
			size_type done = 0;
			#ifdef MSIPL_EXCEPT
			try
			{
			#endif
				if (pos > 0)
				{
					uninitialized_copy(begin(), position, newdata);
					done = pos;
				}
				uninitialized_copy(first, last, newdata + pos);
				done += n;
				if (pos < size_)
					uninitialized_copy(position, end(), newdata + pos + n);
				tear_down();
				data_ = newdata;
				size_ = newsize;
				alloc_.m_ = newcap;
				start_ = 0;
			#ifdef MSIPL_EXCEPT
			}
			catch (...)
			{
				destroy(newdata, newdata + done);
				alloc_.deallocate(newdata, newcap);
				throw;
			}
			#endif
		}
	}

#endif

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

template <class T, class Allocator>
__cdeque<T, Allocator>::iterator
__cdeque<T, Allocator>::erase(iterator first, iterator last)
{
	if (first == last)
		return first;
	size_type pb = size_type(first - begin());
	size_type pe = size_type(end() - last);
	size_type diff = size_type(last - first);
	if (pb < pe)
	{
		if (pb == 0)  // erase from beginning, no copying necessary
			destroy(first, last);
		else  // erase from beginning, needs copying
		{
			copy_backward(begin(), first, last);
			destroy(begin(), begin() + difference_type(diff));
		}
		start_ += diff;
		if (start_ >= alloc_.m_)
			start_ -= alloc_.m_;
	}
	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());
		}
	}
	size_ -= diff;
	return first;
}

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

template <class T, class Allocator>
void
__cdeque<T, Allocator>::clear()
{
	destroy(begin(), end());
	size_ = start_ = 0;
}

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

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

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

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

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

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

template <class T, class Allocator>
inline
void
swap(__cdeque<T,Allocator>& x, __cdeque<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 __cdeque<void*, Allocator>
	{
		template <bool b> struct chooser {};
	public:
		// types:
		typedef Allocator::reference                  reference;
		typedef 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 (*cdeq_)[pos_];}
			pointer operator -> () const {return &(*cdeq_)[pos_];}
			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 {return (*cdeq_)[pos_ + i];}
			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:
			__cdeque* cdeq_;
			size_type pos_;

			iterator(__cdeque* cdeq, size_type pos)
				: cdeq_(cdeq),
				  pos_(pos)
			{}

			friend class __cdeque;
			friend class __cdeque::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 __cdeque::iterator& rhs) : cdeq_(rhs.cdeq_), pos_(rhs.pos_) {}
			const_reference operator * () const {return (*cdeq_)[pos_];}
			const_pointer operator -> () const {return &(*cdeq_)[pos_];}
			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 {return (*cdeq_)[pos_ + i];}
			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 __cdeque* cdeq_;
			size_type pos_;

			const_iterator(const __cdeque* cdeq, size_type pos)
				: cdeq_(cdeq),
				  pos_(pos)
			{}

			friend class __cdeque;
		};

		// cdeque.cons_ construct/copy/destroy:
		explicit __cdeque(const Allocator& = Allocator());
		explicit __cdeque(size_type n, const value_type& value = 0, const Allocator& = Allocator());
		template <class InputIterator>
			inline
			__cdeque(InputIterator first, InputIterator last, const Allocator& a = Allocator())
				: alloc_(a),
				  size_(0),
				  start_(0),
				  data_(0)
			{
				choose_init(first, last, chooser<numeric_limits<InputIterator>::is_integer>());
			}
		__cdeque(const __cdeque<void*, Allocator>& x);
		~__cdeque();
		__cdeque<void*, Allocator>& operator=(const __cdeque<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& u);
		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;
		// cdeque.capacity_ capacity:
		size_type size() const;
		size_type max_size() const;
		void      resize(size_type sz, value_type c = 0);
		size_type capacity() const;
		bool      empty() const;
		void      reserve(size_type n);

		// element access:
		reference       operator[](size_type n);
		const_reference operator[](size_type n) const;
		const_reference at(size_type n) const;
		reference       at(size_type n);
		reference       front();
		const_reference front() const;
		reference       back();
		const_reference back() const;
		// cdeque.modifiers_ modifiers:
		void push_front(const value_type& x);
		void push_back(const value_type& x);
		void pop_front();
		void pop_back();
		iterator insert(iterator position, const value_type& x);
		void     insert(iterator position, size_type n, const value_type& x);
		template <class InputIterator>
			inline
			void insert(iterator position, InputIterator first, InputIterator last)
			{
				choose_insert(position, first, last, chooser<numeric_limits<InputIterator>::is_integer>());
			}
		iterator erase(iterator position);
		iterator erase(iterator first, iterator last);
		void     swap(__cdeque<void*, Allocator>&);
		void     clear();
	private:
		_EmptyMemberOpt<Allocator, size_type> alloc_;  // m_ is capacity
		size_type size_;
		size_type start_;
		pointer data_;

		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_ = alloc_.m_ = (size_type)distance(first, last);
				if (size_ > max_size())
					#ifdef MSIPL_EXCEPT
						throw length_error("cdeque::construction length error");
					#else
					{
						fprintf(stderr, "cdeque::construction length error\n");
						abort();
					}
					#endif
				if (alloc_.m_ > 0)
				{
					data_ = alloc_.allocate(alloc_.m_);
					copy(first, last, data_);
				}
			}

		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)
			{
				__cdeque temp(first, last, get_allocator());
				const __cdeque& 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("cdeque::assign length error");
					#else
					{
						fprintf(stderr, "cdeque::assign length error\n");
						abort();
					}
					#endif
				if (n <= capacity())
				{
					copy(first, last, data_);
					start_ = 0;
					size_ = n;
				}
				else
				{
					pointer olddata = data_;
					data_ = alloc_.allocate(n);
					copy(first, last, data_);
					if (olddata != 0)
						alloc_.deallocate(olddata, alloc_.m_);
					size_ = alloc_.m_ = n;
					start_ = 0;
				}
			}

		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)
			{
				__cdeque temp(first, last, get_allocator());
				const __cdeque& 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("cdeque::insert length error");
					#else
					{
						fprintf(stderr, "cdeque::insert length error\n");
						abort();
					}
					#endif
				if (size_ + n <= capacity())
				{
					size_type pb = size_type(position - begin());
					size_type pe = size_type(end() - position);
					if (pb < pe)
					{
						if (start_ >= n)
							start_ -= n;
						else
							start_ = alloc_.m_ - (n - start_);
						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));
						}
					}
					else // pos >= size_ / 2
					{
						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;
				}
				else // size_ + n > capacity()
				{
					size_type newsize = size_ + n;
					size_type newcap = max(alloc_.m_, size_type(1));
					while (newsize > newcap)
						newcap *= 2;
					size_type pos = size_type(position - begin());
					pointer newdata = alloc_.allocate(newcap);
					if (pos > 0)
						copy(begin(), position, newdata);
					copy(first, last, newdata + pos);
					if (pos < size_)
						copy(position, end(), newdata + pos + n);
					tear_down();
					data_ = newdata;
					size_ = newsize;
					alloc_.m_ = newcap;
					start_ = 0;
				}
			}

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

	// Implementation __cdeque<void*>

	template <class Allocator>
	inline
	__cdeque<void*, Allocator>::__cdeque(const Allocator& a)
		: alloc_(a),
		  size_(0),
		  start_(0),
		  data_(0)
	{
	}

	template <class Allocator>
	inline
	__cdeque<void*, Allocator>::__cdeque(size_type n, const value_type& value, const Allocator& a)
		: alloc_(a),
		  size_(0),
		  start_(0),
		  data_(0)
	{
		init(n, value);
	}	  

	template <class Allocator>
	__cdeque<void*, Allocator>::__cdeque(const __cdeque<void*,Allocator>& x)
		: alloc_(x.alloc_, x.size_),
		  size_(x.size_),
		  start_(0),
		  data_(0)
	{
		if (alloc_.m_ > 0)
		{
			data_ = alloc_.allocate(alloc_.m_);
			copy(x.begin(), x.end(), data_);
		}
	}

	template <class Allocator>
	void
	__cdeque<void*, Allocator>::init(size_type n, const value_type& value)
	{
		if (n > max_size())
			#ifdef MSIPL_EXCEPT
				throw length_error("cdeque::construction length error");
			#else
			{
				fprintf(stderr, "cdeque::construction length error\n");
				abort();
			}
			#endif
		if (n > 0)
		{
			size_ = alloc_.m_ = n;
			data_ = alloc_.allocate(n);
			fill_n(data_, n, value);
		}
	}

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

	template <class Allocator>
	inline
	void
	__cdeque<void*, Allocator>::tear_down()
	{
		if (data_ != 0)
			alloc_.deallocate(data_, alloc_.m_);
	}

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

	template <class Allocator>
	void
	__cdeque<void*, Allocator>::assign(size_type n, const value_type& u)
	{
		if (n > max_size())
			#ifdef MSIPL_EXCEPT
				throw length_error("cdeque::assign length error");
			#else
			{
				fprintf(stderr, "cdeque::assign length error\n");
				abort();
			}
			#endif
		if (n <= capacity())
		{
			fill_n(data_, n, u);
			size_ = n;
			start_ = 0;
		}
		else
		{
			pointer olddata = data_;
			data_ = alloc_.allocate(n);
			fill_n(data_, n, u);
			if (olddata != 0)
				alloc_.deallocate(olddata, alloc_.m_);
			size_ = alloc_.m_ = n;
			start_ = 0;
		}
	}

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

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

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

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

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

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

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

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

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

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

	template <class Allocator>
	__cdeque<void*, Allocator>::size_type
	__cdeque<void*, Allocator>::max_size() const
	{
		size_type ma = alloc_.max_size();
		size_type mx = numeric_limits<size_type>::max() / 2;
		return min(ma, mx);
	}

	template <class Allocator>
	void
	__cdeque<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
	__cdeque<void*, Allocator>::size_type
	__cdeque<void*, Allocator>::capacity() const
	{
		return alloc_.m_;
	}

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

	template <class Allocator>
	void
	__cdeque<void*, Allocator>::reserve(size_type n)
	{
		if (n > max_size())
			#ifdef MSIPL_EXCEPT
				throw length_error("cdeque::reserve length error");
			#else
			{
				fprintf(stderr, "cdeque::reserve length error\n");
				abort();
			}
			#endif
		if (n > capacity())
		{
			pointer newdata = alloc_.allocate(n);
			if (data_ != 0)
			{
				copy(begin(), end, newdata);
				tear_down();
			}
			alloc_.m_ = n;
			data_ = newdata;
			start_ = 0;
		}
	}

	template <class Allocator>
	__cdeque<void*, Allocator>::reference
	__cdeque<void*, Allocator>::operator[](size_type n)
	{
		n += start_;
		if (n >= alloc_.m_)
			n -= alloc_.m_;
		return *(data_ + n);
	}

	template <class Allocator>
	__cdeque<void*, Allocator>::const_reference
	__cdeque<void*, Allocator>::operator[](size_type n) const
	{
		n += start_;
		if (n >= alloc_.m_)
			n -= alloc_.m_;
		return *(data_ + n);
	}

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

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

	template <class Allocator>
	inline
	__cdeque<void*, Allocator>::reference
	__cdeque<void*, Allocator>::front()
	{
		return *(data_ + start_);
	}

	template <class Allocator>
	inline
	__cdeque<void*, Allocator>::const_reference
	__cdeque<void*, Allocator>::front() const
	{
		return *(data_ + start_);
	}

	template <class Allocator>
	inline
	__cdeque<void*, Allocator>::reference
	__cdeque<void*, Allocator>::back()
	{
		return (*this)[size_ - 1];
	}

	template <class Allocator>
	inline
	__cdeque<void*, Allocator>::const_reference
	__cdeque<void*, Allocator>::back() const
	{
		return (*this)[size_ - 1];
	}

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

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

	template <class Allocator>
	void
	__cdeque<void*, Allocator>::pop_front()
	{	
		--size_;
		++start_;
		if (start_ >= alloc_.m_)
			start_ -= alloc_.m_;
	}

	template <class Allocator>
	inline
	void
	__cdeque<void*, Allocator>::pop_back()
	{	
		--size_;
	}

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

	template <class Allocator>
	void
	__cdeque<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("cdeque::insert length error");
			#else
			{
				fprintf(stderr, "cdeque::insert length error\n");
				abort();
			}
			#endif
		if (size_ + n <= capacity())
		{
			size_type pb = size_type(position - begin());
			size_type pe = size_type(end() - position);
			if (pb < pe)
			{
				if (start_ >= n)
					start_ -= n;
				else
					start_ = alloc_.m_ - (n - start_);
				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);
				}
			}
			else // pos >= size_ / 2
			{
				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;
		}
		else // size_ + n > capacity()
		{
			size_type newsize = size_ + n;
			size_type newcap = max(alloc_.m_, size_type(1));
			while (newsize > newcap)
				newcap *= 2;
			size_type pos = size_type(position - begin());
			pointer newdata = alloc_.allocate(newcap);
			if (pos > 0)
				copy(begin(), position, newdata);
			fill_n(newdata + pos, n, x);
			if (pos < size_)
				copy(position, end(), newdata + pos + n);
			tear_down();
			data_ = newdata;
			size_ = newsize;
			alloc_.m_ = newcap;
			start_ = 0;
		}
	}

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

	template <class Allocator>
	__cdeque<void*, Allocator>::iterator
	__cdeque<void*, Allocator>::erase(iterator first, iterator last)
	{
		if (first == last)
			return first;
		size_type pb = size_type(first - begin());
		size_type pe = size_type(end() - last);
		size_type diff = size_type(last - first);
		if (pb < pe)
		{
			if (pb != 0)  // erase from beginning, needs copying
				copy_backward(begin(), first, last);
			start_ += diff;
			if (start_ >= alloc_.m_)
				start_ -= alloc_.m_;
		}
		else if (pe != 0)  // erase from end, needs copying
			copy(last, end(), first);
		size_ -= diff;
		return first;
	}

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

	template <class Allocator>
	inline
	void
	__cdeque<void*, Allocator>::clear()
	{
		size_ = start_ = 0;
	}

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

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

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

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

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

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

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

	// T*

	template <class T, class Allocator>
	class __cdeque<T*, Allocator>
		: private __cdeque<void*, Allocator::rebind<void*>::other>
	{
		typedef __cdeque<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 __cdeque::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 __cdeque::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_;
		};
		
		// cdeque.cons_ construct/copy/destroy:
		explicit __cdeque(const Allocator& = Allocator());
		explicit __cdeque(size_type n, const value_type& value = 0, const Allocator& = Allocator());
		template <class InputIterator>
			inline
			__cdeque(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& u);
		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;
		// cdeque.capacity_ capacity:
		size_type size() const;
		size_type max_size() const;
		void      resize(size_type sz, value_type c = 0);
		size_type capacity() const;
		bool      empty() const;
		void      reserve(size_type n);

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

	// Implementation __cdeque<T*>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	template <class T, class Allocator>
	inline
	void
	__cdeque<T*, Allocator>::reserve(size_type n)
	{
		base::reserve(n);
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// hh 981005 rewrote
// hh 981208 changed static_cast to reinterpret_cast on the value_type (pointer specialization only)
