I have attempted to implement a similar version of the STL Vector; several functions are missing but I'd like a few words of advice on whether I am indeed on the right track or whether I should change my approach.

My objective is to understand how the vector works from behind the scenes and not to replace or use it for my own applications. I would like to eventually continue this process for all the STL containers.

```
namespace mystl
{
template <typename T>
class Vector
{
private:
    std::unique_ptr<T[]> values;
    std::size_t m_size;
    std::size_t m_capacity;
    unsigned int m_capacity_inc;

protected:
    std::unique_ptr<T[]> get_values();
public:
    /* Type definitions */
    typedef T* iterator;
    typedef const T* const const_iterator;

    /* default constructor */
    explicit Vector();
    /* filling constructor*/
    explicit Vector(std::size_t num, const T& val = T());
    /* Copy constructor needs to use move since copy is a deleted function in unique_ptr*/
    explicit Vector(const Vector<T>& v);
    /* Move constructor */
    explicit Vector(Vector<T>&& v);
    /* Initializer list constructor */
    explicit Vector(std::initializer_list<T> l);

    /* iterator functions */
    iterator begin();
    iterator end();

    /* capacity info functions */
    std::size_t size() const;
    std::size_t capacity() const;
    bool empty() const;

    /* modifier functions*/
    void push_back(T t);
    void pop_back();
    void clear();

    void resize(std::size_t new_size);

    /* element access*/
    T& operator[](int index)
    {
        return values[index];
    }
};

/* move constructor */
template <typename T>
Vector<T>::Vector(Vector<T>&& v)
{
    m_capacity = v.capacity();
    m_size = v.size();
    m_capacity_inc = m_capacity / 2;
    values = (v.get_values());

    v.clear();
}

/* initializer list constructor */
template <typename T>
Vector<T>::Vector(std::initializer_list<T> l)
{
    m_size = 0;
    m_capacity = l.size();
    m_capacity_inc = m_size / 2;
    values = std::make_unique<T[]>(m_capacity);
    for (auto val : l)
    {
        push_back(val);
    }
}

/* check is vector is empty */
template <typename T>
bool Vector<T>::empty() const
{
    return m_size == 0;
}

/* returns pointer to first vector element */
template <typename T>
typename Vector<T>::iterator Vector<T>::begin()
{
    return values.get();
}

/* returns pointer to last vector element */
template <typename T>
typename Vector<T>::iterator Vector<T>::end()
{
    return values.get() + m_size;
}

/* size private member getter */
template <typename T>
std::size_t Vector<T>::size() const
{
    return m_size;
}

/* capacity private member getter */
template <typename T>
std::size_t Vector<T>::capacity() const
{
    return m_capacity;
}

/* pushes new value to the end of the vector*/
template <typename T>
void Vector<T>::push_back(T t)
{
    if (m_size >= m_capacity)
    {
        /* size has reached capacity so we must reallocate a new, larger array */
        m_capacity = m_capacity + m_capacity_inc;
        /* double the capacity increase size */
        m_capacity_inc = m_capacity_inc << 1;
        /* allocate the new memory for the vector*/
        std::unique_ptr<T[]> new_vec = std::make_unique<T[]>(m_capacity);
        /* copy the old values to the new array */
        for (std::size_t index = 0; index < m_size; ++index)
        {
            new_vec[index] = values[index];
        }
        /* move ownership of the new array to the current vector pointer */
        values = std::move(new_vec);
    }
    /* input the new value and increase the size; */
    values[m_size++] = t;
}

/* removes the last item and deletes the memory area related to that object and decreases the size. capacity is not affected.*/
template <typename T>
void Vector<T>::pop_back()
{
    (values)[m_size - 1].~T();
    --m_size;
}

/* clear function resets capacity info and deallocates memory.*/
template <typename T>
void Vector<T>::clear()
{
    m_size = 0;
    m_capacity = 0;
    m_capacity_inc = 1;
    values.reset();
}

/* resizes the container to the argument size. if the new size is less than the old size, values after the new_size are set as the default value of the 
type of the template object */
template<typename T>
void Vector<T>::resize(std::size_t new_size)
{
    auto new_array = std::make_unique<T[]>(new_size);
    m_capacity = new_size;
    m_capacity_inc = new_size;
    int array_end = m_size < new_size ? m_size : new_size;

    for (auto i = 0; i < array_end; i++)
    {
        new_array = values[i];
    }

    values = std::move(new_array);
    m_size = new_size;

}

/* a protected function that returns the container array. */
template <typename T>
std::unique_ptr<T[]> Vector<T>::get_values()
{
    /* returns an l value reference */
    return std::move(values);
}

/* default vector constructor, with an empty array allocated of 0 size. */
template <typename T>
Vector<T>::Vector()
{
    m_size = 0;
    m_capacity = 0;
    m_capacity_inc = 1;
    values = std::make_unique<T[]>(m_capacity);
}

/* constructs container with size and capacity of the argument, with all values initiated with the value argument */
template <typename T>
Vector<T>::Vector(std::size_t num, const T& val)
{
    /* allocate memory */
    m_size = m_capacity = num;
    m_capacity_inc = num / 2;
    values = std::make_unique<T[]>(num);

    /* initialize values */
    for (std::size_t i = 0; i < m_size; ++i)
    {
        values[i] = val;
    }
}

/* copy constructor: copies the capacity information and values from the argument vector*/
template <typename T>
Vector<T>::Vector(const Vector<T>& v)
{
    m_capacity = v.m_capacity;
    m_size = v.size();
    m_capacity_inc = m_capacity / 2;
    values = std::make_unique<T[]>(m_capacity);

    for (auto i = 0; i < m_size; ++i)
    {
        values[i] = v.values[i];
    }
}
}

```

I have omitted several functions which I will continue to implement - such as shrink\_to\_fit, reverse iterators, emplacers, operator overlaods.

Allocation in my case is being performed using smart pointers - should I opt to use the same allocator functionality implemented by the native vector or would that be an exercise in futility?