#include <iostream>

template<class T>
class MyVector
{
    public:
		MyVector()
		{
			// Initialize the variables
			value  = new T[0];
			length = 0;
			cap = 0;
		}
	
		void push_back(T val)
		{
			// Check if the array has enough allocated memory
			// to add another element to it.
			if((cap) >= (length + 1))
			{
				// If it does, add 1 on the length variable, and then 
				// add the element to the array
				length++;
				
				value[length - 1] = val;
			}
			
			else
			{
				// If there isn't enough allocated memory, resize the array
				resize(length + 1);
				push_back(val);     // After the array is resized, call the function again
			}
			
			//std::cout << "Length   : " << length << "\nCapacity : " << cap << "\n";
		}
		
		void pop_back()
		{
			// Check if the vector has any elements
			if(length > 0)
			{
				length--;       // Decrease the length
				T* tmp = value; // Create a temporary array
				
				delete[] value; // Free the class array
				value = new T[length]; // Allocate a new array with one less element
				
				for(unsigned int len = 0; len < length; len++)
				{
					// Now, copy over the values besides the last
					value[len] = tmp[len];
				}
				
				// delete the temporary value
				delete[] tmp;
			}
			
			else
			{
				// If the array has no elements, we display a message
				std::cout << "Vector is already equal to zero\n";
			}
		}
		
		unsigned int size()
		{
			return length; // Return the length of the vector
		}
		
		unsigned int capacity()
		{
			return cap; // Return the capacity of the vector
		}
		
		void reserve(unsigned int amount)
		{
			delete[] value;        // Delete the vector
			value = new T[amount]; // Reserve the requested amount of memory
			
			cap = amount;          // Update the capacity as required
		}
		
		void resize(unsigned int amount)
		{
			T* tmp = value;        // Allocate a pointer that holds the value
		
			delete[] value;        // Delete the class pointer
			value = new T[amount]; // Allocate a new amount
			
			cap = amount;          // Update
			
			for(unsigned int v = 0; v < cap; v++)
			{
				value[v] = tmp[v]; // Copy the vector elements
			}
			delete[] tmp;
		}
		
		// * The [] operator
		T &operator[](unsigned int index)
		{
			if(index > length)
			{
				// If the index points to an element out of the vector's range...
				std::cout << "Vector index out of range.\n";
			}
			
			else
			{
				// Else, we return a reference to the array's element
				return value[index];
			}
		}
		
		~MyVector()
		{
			// In the destructor we free allocated memory
			delete[] value;
		}
	
	private:
		T* value; // The pointer that's used as the 
		
		unsigned int length; // The length of the variable
		unsigned int cap;    // Capacity of the array
};

int main()
{
    MyVector<int> v ;
    for ( unsigned i=0; i<100; ++i)
        v.push_back(i) ;
        
    for ( unsigned i=0; i<100; ++i)
        std::cout << v[i] << ' ' ;
    std::cout << '\n' ;
}
