#ifndef __VECTOR_AMV
#define __VECTOR_AMV
#include <limits>
#include "exception.h"
#include "allocator.h"
#include "iterator.h"
#include "algorithm.h"
#include "memoryAMV.h"
namespace amv {
template <class type, class A=allocator<type> >
class vector {
public:
typedef type * iterator;
typedef const type * const_iterator;
typedef A allocator_type;
typedef A::size_type size_type;
typedef A::difference_type difference_type;
typedef A::pointer pointer;
typedef A::const_pointer const_pointer;
typedef A::reference reference;
typedef A::const_reference const_reference;
typedef A::value_type value_type;
typedef reverse_iterator_pointer<iterator,type> reverse_iterator;
typedef reverse_iterator_pointer<const_iterator, const type> const_reverse_iterator;
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;
reference operator[](size_type subscript);
const_reference operator[](size_type subscript) const;
reference at(size_type subscript);
const_reference at(size_type subscript) const;
reference front();
const_reference front() const;
reference back();
const_reference back() const;
explicit vector(const A &sourceAllocator=A());
explicit vector(size_type sourceSize, const type &sourceValue=type(), const A &sourceAllocator=A());
template <class In>
vector(In itB, In itE):
alloc(), m_size(itE-itB), ptr(alloc.allocate(m_size))
{
uninitialized_copy(itB,itE,ptr,type());
}
vector(const vector<type,A> &v);
~vector();
vector<type,A> &operator=(const vector<type,A> &op2);
template <class In>
void assign(In first, In last)
{
clear();
m_size=last-first; ptr=alloc.allocate(m_size);
uninitialized_copy(first,last,ptr,type());
}
template <class Size, class type2>
void assign(Size n, const type2 &val=type2())
{
clear();
m_size=n;
ptr=alloc.allocate(m_size);
type *pb=ptr, *pe=ptr+m_size;
while(pb!=pe)
{
alloc.construct(pb,val);
++pb;
}
}
void push_back(const type &newObject);
void pop_back();
iterator insert(iterator pos, const type &val=type());
void insert(iterator pos, size_type n, const type &val);
template <class In>
void insert(iterator pos, In first, In last)
{
size_type newSize=m_size+(last-first);
type *pTemp=alloc.allocate(newSize), *pTemp1;
pTemp1=uninitialized_copy(begin(),pos,pTemp,type());
pTemp1=uninitialized_copy(first,last,pTemp1,type());
uninitialized_copy(pos,end(),pTemp1,type());
clear();
m_size=newSize;
ptr=pTemp;
}
iterator erase(iterator pos);
iterator erase(iterator first, iterator last);
void clear();
size_type size() const;
bool empty() const;
size_type max_size() const;
void resize(size_type newSize, const type &pad=type());
size_type capacity() const;
void reserve(size_type n);
void swap(vector<type,A> &v)
{
swap(ptr,v.ptr);
swap(m_size,v.m_size);
}
allocator_type get_allocator() const { return alloc; }
bool operator==(const vector<type,A> &op2) const;
bool operator!=(const vector<type,A> &op2) const;
protected:
A alloc;
size_type m_size;
type *ptr;
};
template <class type, class A>
inline vector<type,A>::iterator vector<type,A>::begin()
{
return ptr;
}
template <class type, class A>
inline vector<type,A>::const_iterator vector<type,A>::begin() const
{
return static_cast<const_iterator>(ptr);
}
template <class type, class A>
inline vector<type,A>::iterator vector<type,A>::end()
{
return ptr+m_size;
}
template <class type, class A>
inline vector<type,A>::const_iterator vector<type,A>::end() const
{
return static_cast<const_iterator>(ptr+m_size);
}
template <class type, class A>
inline vector<type,A>::reverse_iterator vector<type,A>::rbegin()
{
return ptr+m_size;
}
template <class type, class A>
inline vector<type,A>::const_reverse_iterator vector<type,A>::rbegin() const
{
return static_cast<const_iterator>(ptr+m_size);
}
template <class type, class A>
inline vector<type,A>::reverse_iterator vector<type,A>::rend()
{
return ptr;
}
template <class type, class A>
inline vector<type,A>::const_reverse_iterator vector<type,A>::rend() const
{
return static_cast<const_iterator>(ptr);
}
template <class type, class A>
inline vector<type,A>::reference vector<type,A>::operator[](size_type subscript)
{
return ptr[subscript];
}
template <class type, class A>
inline vector<type,A>::const_reference vector<type,A>::operator[](size_type subscript) const
{
return ptr[subscript];
}
template <class type, class A>
inline vector<type,A>::reference vector<type,A>::at(size_type subscript)
{
if(subscript<m_size)
return ptr[subscript];
else
throw out_of_range();
}
template <class type, class A>
inline vector<type,A>::const_reference vector<type,A>::at(size_type subscript) const
{
if(subscript<m_size)
return ptr[subscript];
else
throw out_of_range();
}
template <class type, class A>
inline vector<type,A>::reference vector<type,A>::front()
{
return *ptr;
}
template <class type, class A>
inline vector<type,A>::const_reference vector<type,A>::front() const
{
return *ptr;
}
template <class type, class A>
inline vector<type,A>::reference vector<type,A>::back()
{
return (*(ptr+m_size-1));
}
template <class type, class A>
inline vector<type,A>::const_reference vector<type,A>::back() const
{
return (*(ptr+m_size-1));
}
template <class type, class A>
inline vector<type,A>::vector(const A &sourceAllocator):
alloc(sourceAllocator), m_size(0), ptr(0)
{
}
template <class type, class A>
inline vector<type,A>::vector(size_type sourceSize, const type &sourceValue, const A &sourceAllocator):
alloc(sourceAllocator), m_size(sourceSize), ptr(alloc.allocate(sourceSize))
{
type *pTemp=ptr, *pEnd=ptr+m_size;
while(pTemp!=pEnd)
{
alloc.construct(pTemp++,sourceValue);
}
}
template <class type, class A>
inline vector<type,A>::vector(const vector<type,A> &v):
m_size(v.m_size), ptr(m_size? alloc.allocate(m_size): 0)
{
uninitialized_copy(v.ptr,v.ptr+v.m_size,ptr,type());
}
template <class type, class A>
inline vector<type,A>::~vector()
{
type *pTemp=ptr, *pEnd=ptr+m_size;
while(pTemp!=pEnd)
{
alloc.destroy(pTemp++);
}
alloc.deallocate(ptr);
}
template <class type, class A>
inline vector<type,A> &vector<type,A>::operator=(const vector<type,A> &op2)
{
if(this==&op2)
return *this;
this->~vector<type,A>();
m_size=op2.m_size;
if(!m_size)
{
ptr=0;
return *this;
}
ptr=alloc.allocate(m_size);
uninitialized_copy(op2.ptr,op2.ptr+op2.m_size,ptr,type());
return *this;
}
template <class type, class A>
inline void vector<type,A>::push_back(const type &newObject)
{
type *newPtr=alloc.allocate(m_size+1);
type *pTemp1=newPtr, *pTemp2=ptr, *pEnd=ptr+m_size;
while(pTemp2!=pEnd)
*pTemp1++=*pTemp2++;
*pTemp1=newObject;
alloc.deallocate(ptr);
ptr=newPtr;
++m_size;
}
template <class type, class A>
inline void vector<type,A>::pop_back()
{
type *newPtr=alloc.allocate(--m_size);
type *pTemp1=newPtr, *pTemp2=ptr, *pEnd=newPtr+m_size;
while(pTemp1!=pEnd)
*pTemp1++=*pTemp2++;
alloc.deallocate(ptr);
ptr=newPtr;
}
template <class type, class A>
inline vector<type,A>::iterator insert(vector<type,A>::iterator pos, const type &val)
{
size_type newSize=m_size+1;
type *pTemp=alloc.allocate(newSize), *pTemp1;
pTemp1=uninitialized_copy(begin(),pos,pTemp,type());
alloc.construct(pTemp1,val);
++pTemp1;
uninitialized_copy(pos,end(),pTemp1,type());
clear();
m_size=newSize;
ptr=pTemp;
}
template <class type, class A>
inline void vector<type,A>::insert(vector<type,A>::iterator pos, size_type n, const type &val)
{
size_type newSize=m_size+n;
type *pTemp=alloc.allocate(newSize), *pTemp1;
pTemp1=uninitialized_copy(begin(),pos,pTemp,type());
while(n)
{
alloc.construct(pTemp1,val);
++pTemp1;
--n;
}
uninitialized_copy(pos,end(),pTemp1,type());
clear();
m_size=newSize;
ptr=pTemp;
}
template <class type, class A>
inline vector<type,A>::iterator vector<type,A>::erase(vector<type,A>::iterator pos)
{
size_type newSize=m_size-1;
type *pTemp=alloc.allocate(newSize), *pTemp1;
pTemp1=uninitialized_copy(begin(),pos,pTemp,type());
uninitialized_copy(pos+1,end(),pTemp1,type());
clear();
m_size=newSize;
ptr=pTemp;
}
template <class type, class A>
inline vector<type,A>::iterator vector<type,A>::erase(vector<type,A>::iterator first, vector<type,A>::iterator last)
{
size_type newSize=m_size-(last-first);
type *pTemp=alloc.allocate(newSize), *pTemp1;
pTemp1=uninitialized_copy(begin(),first,pTemp,type());
uninitialized_copy(last,end(),pTemp1,type());
clear();
m_size=newSize;
ptr=pTemp;
}
template <class type, class A>
inline void vector<type,A>::clear()
{
this->~vector<type,A>();
m_size=0;
ptr=0;
}
template <class type, class A>
inline vector<type,A>::size_type vector<type,A>::size() const
{
return m_size;
}
template <class type, class A>
inline bool vector<type,A>::empty() const
{
return m_size==0;
}
template <class type, class A>
inline vector<type,A>::size_type vector<type,A>::max_size() const
{
return (std::numeric_limits<size_type>::max());
}
template <class type, class A>
inline void vector<type,A>::resize(size_type newSize, const type &pad)
{
if(!newSize)
{
alloc.deallocate(ptr); ptr=0;
m_size=0;
return;
}
if(newSize==m_size)
return;
size_type i;
if(!ptr)
{
*this=vector<type,A>(newSize,pad);
return;
}
type *pNewPtr=alloc.allocate(newSize), *pTemp=pNewPtr, *pTemp1=ptr;
if(newSize>m_size)
{
for(i=0; i<m_size; ++i)
{
alloc.construct(pTemp,*pTemp1);
++pTemp;
++pTemp1;
}
for(;i<newSize; ++i)
{
alloc.construct(pTemp,pad);
++pTemp;
}
}
else
{
for(i=0; i<newSize; ++i)
{
alloc.construct(pTemp,*pTemp1);
++pTemp;
++pTemp1;
}
}
alloc.deallocate(ptr);
ptr=pNewPtr;
m_size=newSize;
}
template <class type, class A>
inline vector<type,A>::size_type vector<type,A>::capacity() const
{
return m_size;
}
template <class type, class A>
inline void vector<type,A>::reserve(size_type n)
{
}
template <class type, class A>
inline bool vector<type,A>::operator==(const vector<type,A> &op2) const
{
if(m_size!=op2.m_size)
return false;
for(size_type i=0; i<m_size; ++i)
{
if(ptr[i]!=op2.ptr[i])
return false;
}
return true;
}
template <class type, class A>
inline bool vector<type,A>::operator!=(const vector<type,A> &op2) const
{
return !(*this==op2);
}
}
#endif