#include <algorithm>
#include <iostream>

class arreglo_dinamico {
   int cap, tam;
   int* p;

public:
   arreglo_dinamico( ) {
      cap = 1;
      tam = 0;
      p = new int[1];
   }

   arreglo_dinamico(int t, int v) {          // tamaño inicial t, todos los elementos con el valor v (aún se puede mejorar)
      cap = t;
      tam = t;
      p = new int[cap];
      for (int i = 0; i < tam; ++i) {
         p[i] = v;
      }
   }

   arreglo_dinamico(const arreglo_dinamico& v) {
      std::cout << "constructor por copia\n";
      cap = v.tam;
      tam = v.tam;
      p = new int[cap];
      for (int i = 0; i < tam; ++i) {
         p[i] = v.p[i];
      }
   }

   ~arreglo_dinamico( ) {
      std::cout << "destructor\n";
      delete[] p;
   }

   void operator=(const arreglo_dinamico& v) {
      if (p == v.p) {
         return;
      }

      delete[] p;
      cap = v.tam;
      tam = v.tam;
      p = new int[cap];
      for (int i = 0; i < tam; ++i) {
         p[i] = v.p[i];
      }
   }

   int size( ) const {
      return tam;
   }

   int& operator[](int i) {
      return p[i];
   }

   const int& operator[](int i) const {
      return p[i];
   }

   void agrega(int v) {
      if (tam == cap) {
         int* q = new int[2 * cap];
         for (int i = 0; i < tam; ++i) {
            q[i] = p[i];
         }
         delete[] p;
         p = q;
         cap *= 2;
      }

      p[tam] = v;
      tam += 1;
   }

   void quita_ultimo( ) {
      tam -= 1;
   }
};

void imprime(const arreglo_dinamico& a) {
   for (int i = 0; i < a.size( ); ++i) {
      std::cout << a[i] << " ";
   }
   std::cout << "\n";
}

int main( ) {
   arreglo_dinamico a(10, 5);
   imprime(a);
}
