#include <iostream>
using namespace std;

template <class T>
class DynamicVector
{
    T* array; // pointer to the items 指向分配空间的指针 
    unsigned mallocSize; // number of allocated spaces 分配空间的大小 
    unsigned numofItems; // number of items 向量内已经存储的元素数量 
    int virtualZero; // virtual zero 数组起始下标,C语言中通常数组下标是从0开始, 这个数据属性可以让数组的下标从-10或2等等整数开始 ,让数组更加灵活。

public:
    DynamicVector(int);
    DynamicVector(const DynamicVector&);
    ~DynamicVector();
    inline  void push_back(const T&);
    void push_back(const DynamicVector&);
    T& operator[] (int Vindex);
    unsigned length() const;
    unsigned capacity() const;
    int firstIndex() const;
    bool operator == (const  DynamicVector<T>& dv) const;
    void insert(int Vindex, const T&);
    void remove();   //删除最后一个元素。
    void remove(int Vindex); //删除Vindex号元素。
    void remove(int Vfirst, int Vlast);   //删除[Vindex,Vlast) 号元素。 注意是左闭右开集合,即不删除Vlast元素。
    DynamicVector<T> operator() (int Vfirst, int Vlast) const;
    void swap(DynamicVector<T> & dv);

    DynamicVector& operator=(const DynamicVector& c);

    template <class K>
    friend std::ostream& operator<<(std::ostream& output, const DynamicVector<K>&);

    void try_resize_memory();
    int  calc_index(int Vindex) const { return Vindex - virtualZero; }
    void removeall();
};

template <class T>
void DynamicVector<T>::remove()
{
    if (length()) {
        --numofItems;
    }
}

template <class T>
std::ostream& operator<<(std::ostream& output, const DynamicVector<T>& c)
{
    if (!c.length())
        output << "The arrray is empty.";
    else {
        for (unsigned i = 0; i < c.length(); ++i) {
            output << c.array[i] << ' ';
        }
    }
    return output;
}

template <class T>
void DynamicVector<T>::try_resize_memory()
{
    if (numofItems < mallocSize) return;

    unsigned count = mallocSize * 2 + 1;
    T* temp = new T[count];
    for (unsigned i = mallocSize; i--; temp[i] = array[i]);
    std::swap(temp, array);
    delete[] temp;
    mallocSize = count;
}

template <class T>
void DynamicVector<T>::swap(DynamicVector<T> & dv)
{
    std::swap(array, dv.array);
    std::swap(numofItems, dv.numofItems);
    std::swap(mallocSize, dv.mallocSize);
    std::swap(virtualZero, dv.virtualZero);
}

template <class T>
void DynamicVector<T>::removeall()
{
    if (array) { delete[] array; }
    numofItems = 0;
    mallocSize = 0;
    array = NULL;
}

template <class T>
void DynamicVector<T>::remove(int Vindex)
{
    int index = calc_index(Vindex);
    if (index < numofItems) {
        for (unsigned i = index; i< numofItems; array[i] = array[i + 1], ++i);
        numofItems--;

        if (numofItems == 0) { this->removeall(); }
    }
}

template <class T>
void DynamicVector<T>::remove(int Vfirst, int Vlast)
{
    if (Vfirst >= Vlast) return;
    int index = calc_index(Vfirst);
    if (index < numofItems) {
        int endindex = calc_index(Vlast);
        if (endindex >= numofItems) endindex = numofItems;

        int count = endindex - index;
        for (unsigned i = 0, repcnt = length() - endindex; i < repcnt; array[index + i] = array[index + i + count], ++i);
        numofItems-= count;

        if (numofItems == 0) { this->removeall(); }
    }
}

template <class T>
void DynamicVector<T>::insert(int Vindex, const T& t)
{
    try_resize_memory();
    int index = calc_index(Vindex);
    if (index < numofItems) {
        for (unsigned i = numofItems + 1; i-- > index; array[i] = array[i - 1]);
    }
    array[index] = t;
    ++numofItems;
}

template <class T>
DynamicVector<T> DynamicVector<T>::operator()(int Vfirst, int Vlast) const
{
    DynamicVector<T> temp(Vfirst);
    if (Vfirst >= Vlast) return temp;
    int index = calc_index(Vfirst);
    if (index < length()) {
        for (int i = 0, count = Vlast - Vfirst; i < count; temp.push_back(array[index + i]), ++i);
    }
    return temp;
}

template <class T>
bool DynamicVector<T>::operator==(const DynamicVector<T>& c) const
{
    if (numofItems != c.numofItems) return false;
    for (unsigned i = numofItems; i--;) {
        if (array[i] != c.array[i]) return false;
    }
    return true;
}

template <class T>
DynamicVector<T>& DynamicVector<T>::operator=(const DynamicVector& c)
{
    if (c.numofItems) {
        array = new T[c.mallocSize];
        for (unsigned i = c.numofItems; i--; array[i] = c.array[i]);
        numofItems = c.numofItems;
        mallocSize = c.mallocSize;// c.mallocSize;
    }
    else {
        removeall();
    }
    virtualZero = c.virtualZero;
    return *this;
}

template <class T>
DynamicVector<T>::DynamicVector(const DynamicVector& c)
{
    if (c.numofItems) {
        array = new T[c.mallocSize];
        for (unsigned i = c.numofItems; i--; array[i] = c.array[i]);
        numofItems = c.numofItems;
        mallocSize = c.mallocSize;// c.mallocSize;
    }
    else {
        array = NULL;
        numofItems = 0;
        mallocSize = 0;
    }
    virtualZero = c.virtualZero;
}

template <class T>
void DynamicVector<T>::push_back(const DynamicVector& c)
{
    if (c.numofItems) {
        for (unsigned i = 0; i< c.numofItems; this->push_back(c.array[i]), ++i);
    }
}

template <class T>
void DynamicVector<T>::push_back(const T& t)
{
    try_resize_memory();
    array[numofItems++] = t;
}

template <class T>
DynamicVector<T>::~DynamicVector()
{
    delete[] array; array = NULL;
}

template <class T>
DynamicVector<T>::DynamicVector(int Vindex)
{
    array = NULL;
    numofItems = 0;
    mallocSize = 0;
    virtualZero = Vindex;
}
template <class T>
T& DynamicVector<T>::operator[] (int Vindex)
{
    int _entry = Vindex - virtualZero;
    if (_entry < 0 || _entry >= numofItems)
    {
        cout << endl << "Out Of Range";
        exit(1);
    }
    return array[_entry];
}
template <class T>
unsigned DynamicVector<T>::length() const
{
    return numofItems;
}
template <class T>
unsigned DynamicVector<T>::capacity() const
{
    return this->mallocSize;
}
template <class T>
int DynamicVector<T>::firstIndex() const
{
    return this->virtualZero;
}

////////++++
////////++++

int main()
{
    DynamicVector<int> ra(-2);


    int i, n;
    cin >> n;

    cout << ra;

    ra.push_back(-3);
    ra.push_back(-2);
    ra.push_back(-1);
    for (i = 0; i < n; i++)
    {
        ra.push_back(i);
    }
    cout << "\n malloSize is " << ra.capacity();
    cout << "\n numofItems is " << ra.length();
    cout << "\n StartIndex is " << ra.firstIndex() << endl;
    for (i = -2; i < n + 1; i++)
    {
        cout << ra[i] << " ";
    }
    cout << endl;
    DynamicVector<int> raCopy(ra);
    cout << "\n malloSize is " << raCopy.capacity();
    cout << "\n numofItems is " << raCopy.length();
    cout << "\n StartIndex is " << raCopy.firstIndex() << endl;
    cout << endl;
    for (i = -2; i < n + 1; i++)
    {
        cout << ++ra[i] << " ";
    }
    cout << endl;
    for (i = -2; i < n + 1; i++)
    {
        cout << raCopy[i] << " ";
    }

    raCopy = ra;
    if (ra == raCopy)  cout << "\n ra == raCopy";
    else cout << "\n ra != raCopy";


    ra[-2] = 100;

    if (ra == raCopy)  cout << "\n ra == raCopy";
    else cout << "\n ra != raCopy";

    raCopy.push_back(ra);
    cout << endl;
    int firstI = raCopy.firstIndex();
    for (i = 0; i < raCopy.length(); i++)
    {
        cout << raCopy[i + firstI] << " ";
    }
    cout << endl;
    raCopy.insert(-2, 6);
    raCopy.insert(-1, 7);
    cout << raCopy;

    raCopy.remove();
    cout << endl;
    cout << raCopy << " remove()";

    raCopy.remove(-1);
    cout << endl;
    cout << raCopy << " remove(-1)";

    raCopy.remove(-1, 1);
    cout << endl;
    cout << raCopy << " remove(-1,1)";

    ra = raCopy(-1, 3);
    cout << endl;
    cout << ra << " raCopy(-1,3)";

    ra.swap(raCopy);
    cout << endl << "ra.swap(raCopy)" << endl;
    cout << ra;
    cout << endl;
    cout << raCopy;

    return 0;
}