// The class DynStack uses dynamic memory allocation.
// Since there is a pointer to a block of allocated memory,
// the copy constructor is needed to properly duplicate the data.

#include <cassert>
#include <cstdlib>

class DynStack {
public:
    const static int INITIAL_STACK_SIZE = 3;
private:
    int* m_ptr_stack_array;
    int m_stack_size;
public:
    DynStack() // constructor
    {
        m_stack_size = INITIAL_STACK_SIZE;
        m_ptr_stack_array = allocate_ints( m_stack_size );
    }

    DynStack( DynStack const& other ) // copy constructor
    {
        m_stack_size = other.m_stack_size;
        m_ptr_stack_array = allocate_ints( m_stack_size );
        copy_data_from( other.m_ptr_stack_array );
    }

    ~DynStack() // destructor returns memory back to the system
    {
        deallocate_ints( m_ptr_stack_array ); // deallocate memory
        // NULL indicates that memory was deallocated:
        m_ptr_stack_array = NULL;
    }

private:
    void copy_data_from( int const* ptr_other_stack_array )
    {
        int idx = 0;
        for ( ; idx < m_stack_size; ++idx ) {
            m_ptr_stack_array[ idx ] = ptr_other_stack_array[ idx ];
        }
    }
public:
    int size()
    {
        return m_stack_size;
    }

    void double_capacity()
    {
        int* new_memory = allocate_ints( m_stack_size * 2 );
        //copy original data to the new area
        int idx = 0;
        for ( ; idx < m_stack_size; ++idx ) {
            new_memory[ idx ] = m_ptr_stack_array[ idx ];
        }
        deallocate_ints( m_ptr_stack_array ); // deallocate old memory
        m_ptr_stack_array = new_memory;
        m_stack_size = m_stack_size * 2;
        //m_stack_size *= 2;
    }
private:
    int* allocate_ints( int how_many )
    {
        int* new_memory = new int[ how_many ];
        return new_memory;
    }
    void deallocate_ints( int* ptr_mem )
    {
        delete[] ptr_mem;
    }
};

int main()
{
    DynStack st1;
    st1.double_capacity();
    const int DBL_INITIAL_SIZE = DynStack::INITIAL_STACK_SIZE * 2;
    assert( st1.size() == DBL_INITIAL_SIZE );
    DynStack st2 = st1; // invokes copy constructor
    assert( st1.size() == st2.size() );
    return 0;
}

