// Error a propósito: al insertar se olvida actualizar el prev del siguiente nodo.
// La lista se ve bien hacia adelante; check_invariants lo descubre.
#include <cassert>
#include <iostream>

class BrokenList {
    struct Node {
        int value = 0;
        Node* prev = nullptr;
        Node* next = nullptr;
    };

public:
    BrokenList() : sentinel_(new Node) {
        sentinel_->prev = sentinel_;
        sentinel_->next = sentinel_;
    }
    BrokenList(const BrokenList&) = delete;
    BrokenList& operator=(const BrokenList&) = delete;
    ~BrokenList() {
        Node* node = sentinel_->next;
        while (node != sentinel_) {
            Node* next = node->next;
            delete node;
            node = next;
        }
        delete sentinel_;
    }

    void push_front(int value) {
        Node* first = sentinel_->next;
        Node* node = new Node{value, sentinel_, first};
        sentinel_->next = node;
        // falta: first->prev = node;
    }

    void print() const {
        for (const Node* node = sentinel_->next; node != sentinel_; node = node->next) {
            std::cout << node->value << " ";
        }
        std::cout << std::endl;
    }

    void check_invariants() const {
        const Node* node = sentinel_;
        do {
            assert(node->next->prev == node);
            assert(node->prev->next == node);
            node = node->next;
        } while (node != sentinel_);
    }

private:
    Node* sentinel_;
};

int main() {
    BrokenList list;
    list.push_front(2);
    list.push_front(1);
    list.print();
    list.check_invariants();
    return 0;
}
