deque

#ifndef __TYPETRAIT__H__
#define __TYPETRAIT__H__
#include <cstddef>
namespace stc{
	class trueType{};
	class falseType{};
	template <typename type>
	class typeTrait{
	public:
		typedef trueType	thisDummyMemberMustBeFirst;
		typedef falseType	hasTrivalDefaultCtor;
		typedef falseType	hasTrivalCopyCtor;
		typedef falseType	hasTrivalAssignmentOperator;
		typedef falseType	hasTrivalDtor;
		typedef falseType	isPODType;
	};
	template <> class typeTrait < signed char > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < unsigned char > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < wchar_t > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < short > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < unsigned short > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < int > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < unsigned int > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < long > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < long long> {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < unsigned long > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < float > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < double > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < long double > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <class type> class typeTrait < type* > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
	template <> class typeTrait < bool > {
	public:
		typedef trueType	hasTrivalDefaultCtor;
		typedef trueType	hasTrivalCopyCtor;
		typedef trueType	hasTrivalAssignmentOperator;
		typedef trueType	hasTrivalDtor;
		typedef trueType	isPODType;
	};
}
#endif

#ifndef __ITERATOR__TRAIT__H__
#define __ITERATOR__TRAIT__H__
#include <cstddef>
namespace stc{
	class inputIteratorTag{};
	class outputIteratorTag{};
	class forwardIteratorTag{};
	class bidirectionalIteratorTag{};
	class randomAccessIteratorTag{};

	template < typename type,
		typename category = forwardIteratorTag,	
		typename distance = std::ptrdiff_t,
		typename pointer = type*,
		typename reference = type& >
	class iterator{
	public:	
		typedef type		valueType;
		typedef category	iteratorCategory;
		typedef distance	differenceType;
		typedef pointer		pointer;
		typedef reference	reference;
	};

	template <typename iterator>
	class iteratorTrait{
	public:
		typedef typename iterator::iteratorCategory
			iteratorCategory;
		typedef typename iterator::valueType
			valueType;
		typedef typename iterator::differenceType
			differenceType;
		typedef typename iterator::pointer
			pointer;
		typedef typename iterator::reference
			reference;
	};

	template <> class iteratorTrait < signed char > {
	public:
		typedef randomAccessIteratorTag	
			iteratorCategory;
		typedef signed char			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef signed char*		pointer;
		typedef signed char&		reference;
	};
	
	template <> class iteratorTrait < const signed char > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const signed char	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const signed char*	pointer;
		typedef const signed char&	reference;
	};

	template <> class iteratorTrait < unsigned char > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef unsigned char			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef unsigned char*		pointer;
		typedef unsigned char&		reference;
	};

	template <> class iteratorTrait < const unsigned char > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const unsigned char	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const unsigned char*	pointer;
		typedef const unsigned char&	reference;
	};

	template <> class iteratorTrait < wchar_t > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef wchar_t			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef wchar_t*		pointer;
		typedef wchar_t&		reference;
	};

	template <> class iteratorTrait < const wchar_t > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const wchar_t	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const wchar_t*	pointer;
		typedef const wchar_t&	reference;
	};

	template <> class iteratorTrait < short > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef short			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef short*		pointer;
		typedef short&		reference;
	};

	template <> class iteratorTrait < const short > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const short	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const short*	pointer;
		typedef const short&	reference;
	};

	template <> class iteratorTrait < unsigned short > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef unsigned short			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef unsigned short*		pointer;
		typedef unsigned short&		reference;
	};

	template <> class iteratorTrait < const unsigned short > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const unsigned short	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const unsigned short*	pointer;
		typedef const unsigned short&	reference;
	};

	template <> class iteratorTrait < int > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef int			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef int*		pointer;
		typedef int&		reference;
	};

	template <> class iteratorTrait < const int > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const int	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const int*	pointer;
		typedef const int&	reference;
	};

	template <> class iteratorTrait < unsigned int > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef unsigned int			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef unsigned int*		pointer;
		typedef unsigned int&		reference;
	};

	template <> class iteratorTrait < const unsigned int > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const unsigned int	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const unsigned int*	pointer;
		typedef const unsigned int&	reference;
	};

	template <> class iteratorTrait < long > {
	public:
		typedef randomAccessIteratorTag	
			iteratorCategory;
		typedef long			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef long*		pointer;
		typedef long&		reference;
	};
	
	template <> class iteratorTrait < const long > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const long	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const long*	pointer;
		typedef const long&	reference;
	};

	template <> class iteratorTrait < long long > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef long long 			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef long long *		pointer;
		typedef long long &		reference;
	};

	template <> class iteratorTrait < const long long > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const long long 	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const long long *	pointer;
		typedef const long long &	reference;
	};

	template <> class iteratorTrait < unsigned long > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef unsigned long			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef unsigned long*		pointer;
		typedef unsigned long&		reference;
	};

	template <> class iteratorTrait < const unsigned long > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const unsigned long	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const unsigned long*	pointer;
		typedef const unsigned long&	reference;
	};

	template <> class iteratorTrait < float > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef float			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef float*		pointer;
		typedef float&		reference;
	};

	template <> class iteratorTrait < const float > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const float	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const float*	pointer;
		typedef const float&	reference;
	};

	template <> class iteratorTrait < double > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef double			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef double*		pointer;
		typedef double&		reference;
	};

	template <> class iteratorTrait < const double > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const double	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const double*	pointer;
		typedef const double&	reference;
	};

	template <> class iteratorTrait < long double > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef long double			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef long double*		pointer;
		typedef long double&		reference;
	};

	template <> class iteratorTrait < const long double > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const long double	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const long double*	pointer;
		typedef const long double&	reference;
	};

	template <> class iteratorTrait < bool > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef bool			valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef bool*		pointer;
		typedef bool&		reference;
	};

	template <> class iteratorTrait < const bool > {
	public:
		typedef randomAccessIteratorTag
			iteratorCategory;
		typedef const bool	valueType;
		typedef std::ptrdiff_t		differenceType;
		typedef const bool*	pointer;
		typedef const bool&	reference;
	};
}

#endif

#ifndef __ALGORITHM__H__
#define __ALGORITHM__H__
#include "iteratorTrait.h"
namespace stc{

	template <class bidirIt1,class bidirIt2>
	bidirIt2 copy_backward(bidirIt1 first,bidirIt2 last,bidirIt2 d_last){
		while (first != last)
			*(--d_last) = *(--last);
		return d_last;
	}

	template<class InputIt, class OutputIt>
	OutputIt copy(InputIt first, InputIt last,
		OutputIt d_first){
		while (first != last) {
			*d_first++ = *first++;
		}
		return d_first;
	}

	template<class InputIt, class OutputIt, class UnaryPredicate>
	OutputIt copy_if(InputIt first, InputIt last,
		OutputIt d_first, UnaryPredicate pred){
		while (first != last) {
			if (pred(*first))
				*d_first++ = *first;
			first++;
		}
		return d_first;
	}
}

#endif

#ifndef __DEQUE__H__
#define __DEQUE__H__
#pragma warning(disable : 4996)
#include <cmath>
#include <memory>
#include <string>
#include <cassert>
#include <stdexcept>
#include "Algorithm.h"
#include "typeTrait.h"
#include "iteratorTrait.h"

namespace stc{
	template <typename type,
	class Alloc = std::allocator<type>,
		std::size_t bfSz = 0 > class deque;

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	class dequeIterator{
		typedef type**			mapPointer;
		typedef dequeIterator <type, type&, type*, bfSz>
			iterator;
		typedef iterator		self;
		typedef dequeIterator <type,  const type&, const type*, bfSz>
			const_iter;
		friend class deque <type, std::allocator<type>, bfSz> ;
	public:
		typedef stc::randomAccessIteratorTag
			iteratorCategory;
		typedef type			valueType;
		typedef ptr				pointer;
		typedef ref				reference;
		typedef std::size_t		sizeType;
		typedef std::ptrdiff_t	differenceType;
	public:
		dequeIterator(){ mCurr = mFirst = mLast = NULL; mNode = NULL; }
		reference operator*() const { return *mCurr; }
		pointer operator->() const { return mCurr; }
		const differenceType operator -(self)const;
		self& operator ++();
		self operator ++(int);
		self& operator --();
		self operator --(int);
		self& operator +=(differenceType);
		self& operator -=(differenceType);
		const self operator +(differenceType);
		const self operator -(differenceType);
		reference operator [](differenceType);
		bool operator ==(const self& rhs)const { return mCurr == rhs.mCurr; }
		bool operator !=(const self& rhs)const { return !(*this == rhs); }
		bool operator <(const self& rhs)const {
			return (mNode == rhs.mNode) ?
				(mCurr < rhs.mCurr) :
				(mNode < rhs.mNode);
		}
		void reset() { mCurr = mFirst = mLast = NULL; mNode = NULL; }
	private:
		void setCurr(pointer elem) { mCurr = elem; }
		void setNode(mapPointer);
		static std::size_t buffSize();
	private:
		pointer	mCurr;
		pointer mFirst;
		pointer mLast;
		mapPointer mNode;

	};

	const std::size_t maxBfSz = 128;
	const std::size_t minBfSz = 1;

	inline std::size_t dequeBufSize(std::size_t n, std::size_t Sz){
		return n ? n : (Sz < maxBfSz ? (maxBfSz / Sz) : minBfSz);
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	std::size_t dequeIterator<type, ref, ptr, bfSz>::buffSize(){
		return dequeBufSize(bfSz, sizeof(type));
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	void dequeIterator<type, ref, ptr, bfSz>::
		setNode(mapPointer nNode){
		mNode = nNode;
		mFirst = *mNode;
		mLast = mFirst + (buffSize());
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	const typename dequeIterator<type, ref, ptr, bfSz>::differenceType
		dequeIterator<type, ref, ptr, bfSz>::
			operator -(self rhs)const{
			self lhs = *this;
			if (rhs.mNode < lhs.mNode)
				std::swap(lhs, rhs);
			return rhs.mNode == lhs.mNode ? (
				rhs.mCurr > lhs.mCurr ? rhs.mCurr - lhs.mCurr :
				lhs.mCurr - rhs.mCurr
				):
			differenceType(
				buffSize() * ((rhs.mNode - lhs.mNode) - 1) +
				(lhs.mLast - lhs.mCurr) + (rhs.mCurr - rhs.mFirst)
				);
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	typename dequeIterator<type, ref, ptr, bfSz>::self&
		dequeIterator<type, ref, ptr, bfSz>::
			operator ++(){
			++mCurr;
			if (mCurr == mLast){
				setNode(mNode + 1);
				mCurr = mFirst;
			}
			return *this;
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	typename dequeIterator<type, ref, ptr, bfSz>::self
		dequeIterator<type, ref, ptr, bfSz>::
			operator ++(int){
			self res(*this);
			++(*this);
			return res;
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	typename dequeIterator<type, ref, ptr, bfSz>::self&
		dequeIterator<type, ref, ptr, bfSz>::
			operator --(){
			if (mCurr == mFirst){
				setNode(mNode - 1);
				mCurr = mLast;
			}
			--mCurr;
			return *this;
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	typename dequeIterator<type, ref, ptr, bfSz>::self
		dequeIterator<type, ref, ptr, bfSz>::
			operator --(int){
			self res(*this);
			++(*this);
			return res;
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	typename dequeIterator<type, ref, ptr, bfSz>::self&
		dequeIterator<type, ref, ptr, bfSz>::
			operator +=(differenceType rhs){
			if (rhs <= 0)
				return (*this -= (-rhs));
			differenceType buffSz = buffSize();
			differenceType lSz = mLast - mCurr - 1;
			if (rhs < lSz){
				mCurr += rhs;
			}else{
				rhs -= lSz;
				differenceType nodeOffest =
					rhs / buffSz + 1 +
					(rhs >= buffSz ? 1 : 0);
				setNode(mNode + nodeOffest);
				this->mCurr = mFirst + (rhs % buffSz - 1);
			}
			return *this;
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	typename dequeIterator<type, ref, ptr, bfSz>::self&
		dequeIterator<type, ref, ptr, bfSz>::
			operator -=(differenceType rhs){
		if (rhs == 0)
			return *this;
		else if (rhs < 0)
			return (*this += (-rhs));
		differenceType buffSz = buffSize();
		differenceType lSz = mCurr - mFirst - 1;
		if (rhs < lSz){
			mCurr -= rhs;
		}else{
			rhs -= lSz;
			differenceType nodeOffest =
				rhs / buffSz + 1 +
				(rhs >= buffSz ? 1 : 0);
			setNode(mNode - nodeOffest);
			this->mCurr = (mLast - 1) + (rhs % buffSz - 1) ;
		}
		return *this; 
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	const typename dequeIterator<type, ref, ptr, bfSz>::self
		dequeIterator<type, ref, ptr, bfSz>::
			operator +(differenceType rhs){
			self temp = *this;
			return (temp += rhs);
	}

	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	const typename dequeIterator<type,ref,ptr,bfSz>::self
		dequeIterator<type,ref,ptr,bfSz>::
		operator -(differenceType rhs){
		return (*this + (-rhs));
	}


	template <typename type,
		typename ref,
			typename ptr,
				std::size_t bfSz>
	typename dequeIterator<type, ref, ptr, bfSz>::reference
		dequeIterator<type, ref, ptr, bfSz>::
			operator [](differenceType Sz){
			return *(*this +(Sz));
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	class deque{
	public:
		typedef type			valueType;
		typedef std::size_t		sizeType;
		typedef type*			pointer;
		typedef type&			reference;
		typedef dequeIterator < type, type&, type*, bfSz >
			iterator;
		typedef std::ptrdiff_t  differenceType;
	private:
		typedef pointer*	mapPointer;
		typedef deque<type, Alloc, bfSz> self;
	public:
		deque();
		~deque();
		deque(const self&);
		deque(self&&);
		iterator begin() { return mBegin; }
		iterator end() { return mEnd; }
		reference operator[](differenceType);
		bool empty()const { return mSize ? false : true; }
		reference front();
		reference back();
		sizeType size()const { return mSize; }
		void clear();
		void push_back(const type& val);
		void push_front(const type& val);
		void pop_back();
		void pop_front();
		iterator erase(iterator);
		iterator erase(iterator, iterator);
		iterator insert(iterator, const type&);
		self& operator =(const self&);
		self& operator =(self&&);
		self& memcopy(const self&);
		self& memcopy(self&&);
	private:
		void initialFill(sizeType, const type&);
		void creatMapAndNode(sizeType);
		void clear(trueType);
		void clear(falseType);
		bool isClear()const;
		void pop_back(falseType);
		void pop_back(trueType);
		void pop_front(falseType);
		void pop_front(trueType);
		void push_back(const type&,falseType);
		void push_back(const type&, trueType);
		void push_front(const type&, falseType);
		void push_front(const type&, trueType);
		void pushBackAux();
		void pushFrontAux();
		void reallocMap(const sizeType = 4);
	private:
		iterator		 mBegin;
		iterator		 mEnd;
		mapPointer		 mMap;
		sizeType		 mSize;
		sizeType		 mMapSize;
		std::allocator<type*> mNodeAlloc;
		Alloc			 mAlloc;
	};

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	typename deque<type, Alloc, bfSz>::reference
		deque<type, Alloc, bfSz>::
		operator [](differenceType Sz){
		assert(Sz >= 0 && Sz < differenceType(mSize));
		return mBegin[Sz];
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	inline typename deque<type, Alloc, bfSz>::reference
		deque<type, Alloc, bfSz>::
		front(){
		assert(!empty());
		return *mBegin;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	inline typename deque<type, Alloc, bfSz>::reference
		deque<type, Alloc, bfSz>::
		back(){
		assert(!empty());
		iterator temp(mEnd);
		--temp;
		return *temp;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	deque<type, Alloc, bfSz>::
		deque() :
	mMap(0), mSize(0), mMapSize(0){
		initialFill(0, type());
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
		deque<type, Alloc, bfSz>::
		~deque(){
		clear();
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	deque<type,Alloc,bfSz>::
			deque(const self& rhs):
		mMap(0),mSize(0),mMapSize(0){
			memcopy(rhs);
	}


	template <typename type,
		class Alloc,
			std::size_t bfSz>
	deque<type, Alloc, bfSz>::
			deque(self&& rhs) :
		mMap(0), mSize(0), mMapSize(0){
			memcopy(std::move(rhs));
	}


	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type, Alloc, bfSz>::
		initialFill(sizeType Sz, const type& val){
		creatMapAndNode(Sz);
		sizeType buffSz = iterator::buffSize();
		for (mapPointer i = mBegin.mNode; i != mEnd.mNode; ++i)
			std::uninitialized_fill(*i, *i + (buffSz), val);
		if (mEnd.mFirst != mEnd.mCurr)
			std::uninitialized_fill(mEnd.mFirst, mEnd.mCurr, val);
		mSize += Sz;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type, Alloc, bfSz>::
		creatMapAndNode(sizeType Sz){
		assert(empty());
		sizeType buffSz = iterator::buffSize();
		sizeType nodeSz = Sz / (buffSz) + 1;
		mMapSize = nodeSz + 2;
		mMap = mNodeAlloc.allocate(mMapSize);
		memset(mMap, NULL, sizeof(int*) * mMapSize );
		mapPointer start = mMap + 1;
		mapPointer finish = start + nodeSz - 1;
		try{
			for (mapPointer i = start; i <= finish; ++i)
				*i = mAlloc.allocate(buffSz);
		}catch (...){
			for (mapPointer i = start; i <= finish; ++i)
				if (*i != NULL){
					mAlloc.deallocate(*i,buffSz);
					*i = NULL;
				}
			mNodeAlloc.deallocate(mMap, mMapSize);
			mMapSize = 0;
			mMap = NULL;
			return;
		} 
		mBegin.setNode(start);
		mEnd.setNode(finish);
		mBegin.mCurr = mBegin.mFirst;
		mEnd.mCurr = *finish + (Sz % buffSz);
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type, Alloc, bfSz>::
		clear(){
		if (empty()) return;
		typedef  typename typeTrait<type>::
			isPODType isPODType;
		clear(isPODType());
	}

	template <typename type,
		class Alloc,
			std::size_t  bfSz>
	void deque<type, Alloc, bfSz>::
		clear(falseType){
		differenceType buffSz = iterator::buffSize();
		for (mapPointer i = mBegin.mNode + 1; i < mEnd.mNode; ++i)
			for (differenceType j = 0; j != buffSz; ++j)
				mAlloc.destroy(*i + j);
		for (pointer i = mBegin.mCurr; i != mBegin.mLast; ++i)
			mAlloc.destroy(i);
		for (pointer i = mEnd.mFirst; i != mEnd.mCurr; ++i)
			mAlloc.destroy(i);
		clear(trueType());
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type, Alloc, bfSz>::
		clear(trueType){
		mapPointer pMap = mMap;
		sizeType buffSz = iterator::buffSize();
		for (sizeType i = 0; i != mMapSize; ++i){
			if (*pMap != NULL)
				mAlloc.deallocate(*pMap, buffSz);
			*pMap = NULL;
			++pMap;
		}
		mNodeAlloc.deallocate(mMap, mMapSize);
		mMap = NULL;
		mSize = mMapSize = 0;
		mBegin.reset();
		mEnd.reset();
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	bool deque<type, Alloc, bfSz>::	
		isClear()const{
		if (mMap == NULL)
			return true;
		return false;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type, Alloc, bfSz>::
		push_back(const type& val){
		if (isClear() || mEnd.mCurr == (mEnd.mLast - 1))
			this->pushBackAux();
		typedef typename typeTrait<type>::
			isPODType isPODType;
		this->push_back(val, isPODType());
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type, Alloc, bfSz>::
		push_front(const type& val){
		if (isClear() || mBegin.mCurr == mBegin.mFirst)
			this->pushFrontAux();
		typedef typename typeTrait<type>::
			isPODType isPODType;
		push_front(val, isPODType());
	}
	
	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		push_back(const type& val, falseType){
			mAlloc.construt(mEnd.mCurr, val);
			if (mEnd.mCurr == mEnd.mLast - 1){
				mEnd.setNode(mEnd.mNode + 1);
				mEnd.mCurr = mEnd.mFirst;
			} else ++(mEnd.mCurr);
			++mSize;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		push_back(const type& val, trueType){
			*(mEnd.mCurr) = val;
			if (mEnd.mCurr == mEnd.mLast - 1){
				mEnd.setNode(mEnd.mNode + 1);
				mEnd.mCurr = mEnd.mFirst;
			}else 
				++(mEnd.mCurr);
			++mSize;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		push_front(const type& val, falseType){
			if (mBegin.mCurr != mBegin.mFirst){
				mAlloc.construt(mBegin.mCurr - 1, val);
				--mBegin.mCurr;
			}else{
				mBegin.setNode(mBegin.mNode - 1);
				mBegin.mCurr = mBegin.mLast - 1;
				mAlloc.construct(mBegin.mCurr, val);
			}
			++mSize;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type, Alloc, bfSz>::
		push_front(const type& val, trueType){
			if (mBegin.mCurr != mBegin.mFirst){
				*(mBegin.mCurr - 1) = val;
				--mBegin.mCurr;
			}else{
				mBegin.setNode(mBegin.mNode - 1);
				mBegin.mCurr = mBegin.mLast - 1;
				*(mBegin.mCurr) = val;
			}
			++mSize;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		pushBackAux(){
		if (isClear() ||
			mEnd.mNode == (mMap + mMapSize - 1))
			reallocMap();		
		*(mEnd.mNode + 1) = mAlloc.allocate(iterator::buffSize());
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		pushFrontAux(){
		if (isClear() ||
			mBegin.mNode == mMap)
			reallocMap();
		*(mBegin.mNode - 1) = mAlloc.allocate(iterator::buffSize());
	}

	template <typename type,
			class Alloc,
		std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		reallocMap(const sizeType addSz){
			sizeType oSz = mEnd.mNode - mBegin.mNode + 1;
			sizeType nSz = oSz + addSz;
			sizeType nMapSz = mMapSize + nSz;
			mapPointer nMap = mNodeAlloc.allocate(nMapSz);
			memset(nMap, NULL, sizeof(int*) * nMapSz);
			mapPointer nStart = nMap + (nMapSz - nSz) / 2;
			mapPointer nFinish = nStart + oSz - 1;
			sizeType buffSz = iterator::buffSize();
			mapPointer scan = nStart;	
			sizeType pSz = mSize;
			differenceType obo = mBegin.mCurr - mBegin.mFirst;//Offset begin now
			differenceType oeo = mEnd.mCurr - mEnd.mFirst;//Offset end now
			try{
				for (sizeType i = 0; i != oSz; ++i){
					*scan = mAlloc.allocate(buffSz);
					++scan;
				}
				scan = nStart;
				if (!isClear()){
					std::uninitialized_copy(mBegin.mCurr, mBegin.mLast, *nStart + obo);
					for (mapPointer i = mBegin.mNode + 1; i < mEnd.mNode; ++i,++scan)
						std::uninitialized_copy(*i, *i + buffSz, *scan);
					std::uninitialized_copy(mEnd.mFirst, mEnd.mCurr, *(nStart + (mEnd.mNode - mBegin.mNode)));
				}
			}catch (...){
				for (sizeType i = 0; i != oSz; ++i){
					if (*scan != NULL)
						mAlloc.deallocate(*scan, buffSz);
					++scan;
				}
				mNodeAlloc.deallocate(nMap,nMapSz);
				return;
			}
			scan = nStart;
			clear();
			mSize = pSz;
			mMap = nMap;
			mMapSize = nMapSz;
			mBegin.mCurr = *nStart + obo;
			mEnd.mCurr = *nFinish + oeo;
			mBegin.setNode(nStart);
			mEnd.setNode(nFinish);
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		pop_back(){
			assert(!empty());
			typedef typename typeTrait<type>::
				isPODType isPODType;
			pop_back(isPODType());
			sizeType buffSz = iterator::buffSize();
			if (empty()){
				if (*(mMap + (mBegin.mNode - mMap)))
					mAlloc.deallocate(mBegin.mFirst, buffSz);
				if (*(mMap + (mEnd.mNode - mMap)) && 
					mEnd.mNode != mBegin.mNode)
					mAlloc.deallocate(mEnd.mFirst, buffSz);
				memset(mMap, NULL, sizeof(int*)*mMapSize);
				mBegin.reset();
				mEnd.reset();
				mNodeAlloc.deallocate(mMap, mMapSize);
				mMap = NULL;
				mMapSize = 0;
			}
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		pop_front(){
			assert(!empty());
			typedef typename typeTrait<type>::
				isPODType isPODType;
			pop_front(isPODType());
			sizeType buffSz = iterator::buffSize();
			if (empty()){
				if (*(mMap + (mBegin.mNode - mMap)))
					mAlloc.deallocate(mBegin.mFirst, buffSz);
				if (*(mMap + (mEnd.mNode - mMap)) && 
					mEnd.mNode != mBegin.mNode)
					mAlloc.deallocate(mEnd.mFirst, buffSz);
				memset(mMap, NULL, sizeof(int*)*mMapSize);
				mBegin.reset();
				mEnd.reset();
				mNodeAlloc.deallocate(mMap, mMapSize);
				mMap = NULL;
				mMapSize = 0;
			}
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
			pop_back(trueType){
			assert(!empty());
			if (mEnd.mFirst == mEnd.mCurr && 
				mEnd.mNode != mBegin.mNode){
				mapPointer prev = mEnd.mNode - 1;
				mAlloc.deallocate(mEnd.mFirst,iterator::buffSize());
				*(mMap + (mEnd.mNode - mMap)) = NULL;
				mEnd.setNode(prev);
				mEnd.mCurr = mEnd.mLast;
			}
			--(mEnd.mCurr);
			--mSize;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		pop_back(falseType){
			assert(!empty());
			if (mEnd.mFirst == mEnd.mCurr && 
				mEnd.mNode != mBegin.mNode){
				mapPointer prev = mEnd.mNode - 1;
				mAlloc.deallocate(mEnd.mFirst, iterator::buffSize());
				*(mMap + (mEnd.mNode - mMap)) = NULL;
				mEnd.setNode(prev);
				mEnd.mCurr = mEnd.mLast;
			}
			--(mEnd.mCurr);
			mAlloc.destroy(mEnd.mCurr);
			--mSize;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		pop_front(trueType){
			assert(!empty());
			if (mBegin.mCurr == mBegin.mLast - 1 && 
				mEnd.mNode != mBegin.mNode){
				mapPointer next = mBegin.mNode + 1;
				mAlloc.deallocate(mBegin.mFirst, iterator::buffSize());
				*(mMap + (mBegin.mNode - mMap)) = NULL;
				mBegin.setNode(next);
				mBegin.mCurr = mBegin.mFirst;
				--mSize;
				return;
			}
			++mBegin.mCurr;
			--mSize;
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	void deque<type,Alloc,bfSz>::
		pop_front(falseType){
			assert(!empty());
			mAlloc.destroy(mBegin.mCurr);
			if (mBegin.mCurr == mBegin.mLast - 1 && 
				mEnd.mNode != mBegin.mNode){
				mapPointer next = mBegin.mNode + 1;
				mAlloc.deallocate(mBegin.mFirst, iterator::buffSize());
				*(mMap + (mBegin.mNode - mMap)) = NULL;
				mBegin.setNode(next);
				mBegin.mCurr = mBegin.mFirst;
				--mSize;
				return;
			}
			++mBegin.mCurr;
			--mSize;
		}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	typename deque<type,Alloc,bfSz>::iterator
		deque<type,Alloc,bfSz>::
			erase(iterator pos){
			assert(!empty());
			assert(pos != mEnd);
			iterator temp = pos;
			differenceType index = pos - mBegin;
			if ((index < differenceType(mSize >> 1))){//如果之前的元素少一点
				--temp;//日后我把这里分装成copy copy_backward函数
				for (differenceType i = pos - mBegin; i > 0; --i){
					*pos = *temp;
					--temp;
					--pos;
				}
				this->pop_front();
			}else{//如果后面的元素少一点
				++temp;
				for (differenceType i = mEnd - pos - 1; i > 0; --i){
					*pos = *temp;
					++temp;
					++pos;
				}
				this->pop_back();
			} 
			return (mBegin + index);
	}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	typename deque<type,Alloc,bfSz>::iterator
		deque<type,Alloc,bfSz>::
		erase(iterator first, iterator last){
			assert(!empty());
			assert(first != mEnd);
			assert(first != last);
			if (first == mBegin && last == mEnd){
				this->clear();
				return mEnd;
			}
			differenceType delSz = last - first;
			differenceType index = first - mBegin;
			differenceType prevSz = first - mBegin;
			differenceType nextSz = mEnd - last;
			if (prevSz < nextSz){
				stc::copy_backward(mBegin,first,(--last));
				for (; delSz; --delSz)
					pop_front();
			}else{
				stc::copy(last, mEnd, first);
				for (; delSz; --delSz)
					pop_back();
			}
			return (mBegin + index);
		}

	template <typename type,
		class Alloc,
			std::size_t bfSz>
	typename deque<type,Alloc,bfSz>::iterator
		deque<type,Alloc,bfSz>::
			insert(iterator pos,const type& val){
			if (pos == mBegin){
				this->push_front(val);
				return mBegin;
			}else if (pos == mEnd){
				this->push_back(val);
				return mEnd;
			}
			differenceType index = pos - mBegin;
			iterator tempIt;
			if (index < differenceType(mSize >> 1)){
				this->push_front(val);
				tempIt = mBegin + 1;
				pos = mBegin + (index + 1);
				stc::copy(tempIt, pos, mBegin);
				--pos;
				*pos = val;
			}else {
				this->push_back(val);
				pos = mBegin + index;
				tempIt = mEnd - 1;
				stc::copy_backward(pos, tempIt, mEnd);
				pos = mBegin + index;
				*pos = val;
			}
			return pos;
		}

		template <typename type,
			class Alloc,
				std::size_t bfSz>
		typename deque<type,Alloc,bfSz>::self&
			deque<type,Alloc,bfSz>::
			operator =(const self& rhs){
				return memcopy(rhs);
		}

		template <typename type,
			class Alloc,
				std::size_t bfSz>
		typename deque<type,Alloc,bfSz>::self&
			deque<type,Alloc,bfSz>::
			operator =(self&& rhs){
				return memcopy(std::move(rhs));
		}

		template <typename type,
			class Alloc,
				std::size_t bfSz>
		typename deque<type,Alloc,bfSz>::self&
			deque<type,Alloc,bfSz>::
				memcopy(const self& rhs){
				mapPointer tmpMap = mNodeAlloc.allocate(rhs.mMapSize);
				memset(tmpMap, NULL, sizeof(int*) * rhs.mMapSize);
				sizeType rhsNodeSz = rhs.mEnd.mNode - rhs.mBegin.mNode + 1;
				differenceType rFirIndex = rhs.mBegin.mNode - rhs.mMap;
				sizeType buffSz = iterator::buffSize();
				differenceType bCurrIndex = rhs.mBegin.mCurr - rhs.mBegin.mFirst;
				differenceType eCurrIndex = rhs.mEnd.mCurr - rhs.mEnd.mFirst;
				try{
					for (sizeType i = 0; i != rhsNodeSz; ++i){
						*(tmpMap + i + rFirIndex) = mAlloc.allocate(buffSz);
					}
					mapPointer scan = tmpMap + (rhs.mBegin.mNode - rhs.mMap);
					std::uninitialized_copy(rhs.mBegin.mCurr, rhs.mBegin.mLast, *scan + (bCurrIndex));
					++scan;
					for (mapPointer it = rhs.mBegin.mNode + 1; it < rhs.mEnd.mNode; ++it, ++scan)
						std::uninitialized_copy(*it, *it + buffSz, *scan);
					std::uninitialized_copy(rhs.mEnd.mFirst, rhs.mEnd.mCurr, *(tmpMap + rFirIndex + rhsNodeSz - 1));
				}catch (...){
					for (sizeType i = 0; i != rhs.mMapSize; ++i)
						if (tmpMap[i] != NULL)
							mAlloc.deallocate(tmpMap[i],buffSz);
					mNodeAlloc.deallocate(tmpMap, rhs.mMapSize);
					return *this;
				}
				this->clear();
				mMap = tmpMap;
				mMapSize = rhs.mMapSize;
				mSize = rhs.mSize;
				mBegin.setNode(mMap + rFirIndex);
				mEnd.setNode(mMap + ((rhsNodeSz + rFirIndex) - 1));
				mBegin.mCurr = mBegin.mFirst + bCurrIndex;
				mEnd.mCurr = mEnd.mFirst + eCurrIndex;
				return *this;
		}

		template <typename type,
			class Alloc,
				std::size_t bfSz>
		typename deque<type,Alloc,bfSz>::self&
			deque<type,Alloc,bfSz>::
				memcopy(self&& rhs){
				this->clear();
				this->mBegin = rhs.mBegin;
				this->mEnd -= rhs.mEnd;
				this->mMap = rhs.mMap;
				this->mMapSize = rhs.mMapSize;
				this->mSize = rhs.mSize;
				rhs.mMap = NULL;
				rhs.mMapSize = 0;
				rhs.mSize = 0;
				rhs.mBegin.reset();
				rhs.mEnd.reset();
				return *this;
		}
}

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值