// Dónde quedan los elementos en la memoria: distancia de cada uno al primero.
// Las distancias dependen de la biblioteca y de la máquina.
#include <cstdint>
#include <iostream>
#include <vector>

#include "dlist.h"

namespace {

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

void print_offsets(const char* name, const DList<int>& list) {
    std::cout << name << ":";
    std::intptr_t first = address(*list.begin());
    for (const int& value : list) {
        std::cout << " " << address(value) - first;
    }
    std::cout << "\n";
}

}  // namespace

int main() {
    const int n = 6;

    std::vector<int> values(n);
    std::cout << "arreglo:";
    for (const int& value : values) {
        std::cout << " " << address(value) - address(values[0]);
    }
    std::cout << "\n";

    DList<int> list;
    for (int i = 0; i < n; i++) {
        list.push_back(i);
    }
    print_offsets("lista", list);

    // Otras reservas entre nodo y nodo, como en un programa que hace varias cosas a la vez.
    DList<int> mixed;
    std::vector<std::vector<int>> others;
    others.reserve(n);
    for (int i = 0; i < n; i++) {
        mixed.push_back(i);
        others.push_back(std::vector<int>(10 + 10 * i));
    }
    print_offsets("con otras reservas", mixed);

    list.shuffle_nodes(1);
    print_offsets("lista barajada", list);
    return 0;
}
