// Qué sobrevive a una inserción: en una lista y en un arreglo dinámico.
// Se comparan direcciones guardadas como números: nunca se usa un puntero inválido.
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <vector>

#include "dlist.h"

namespace {

std::intptr_t address(const int& value) {
    return reinterpret_cast<std::intptr_t>(&value);
}

const char* yes_no(bool value) {
    return value ? "sí" : "no";
}

}  // namespace

int main() {
    DList<int> list;
    list.push_back(1);
    int* in_list = &list.front();
    auto it = list.begin();
    for (int i = 0; i < 1000; i++) {
        list.push_back(i);
        list.push_front(i);
    }
    std::cout << "lista: el elemento sigue en la misma dirección: " << yes_no(in_list == &*it) << "\n";
    std::cout << "lista: *it = " << *it << ", *in_list = " << *in_list << "\n";

    std::vector<int> grows;
    grows.push_back(1);
    std::intptr_t before = address(grows[0]);
    std::size_t moved_times = 0;
    for (int i = 0; i < 1000; i++) {
        grows.push_back(i);
        if (address(grows[0]) != before) {
            moved_times++;
            before = address(grows[0]);
        }
    }
    std::cout << "vector sin reserve: el bloque cambió de lugar " << moved_times << " veces\n";

    std::vector<int> reserved;
    reserved.reserve(1001);
    reserved.push_back(1);
    before = address(reserved[0]);
    for (int i = 0; i < 1000; i++) {
        reserved.push_back(i);
    }
    std::cout << "vector con reserve: siguió en la misma dirección: "
              << yes_no(address(reserved[0]) == before) << "\n";
    return 0;
}
