#include <cstdio>

template<typename T>class List
{
public:
    class Item;
private:
    class Next
    {
        Item *next;
        friend class List;
    };
    class Prev
    {
        Item *prev;
        friend class List;
    };
    Next zero;
    Prev stop;
public:
    class Item : public Next, public Prev
    {
        friend class List;
    public:
        T data;
        Item(T data) : data(data) {}
    };
    List()
    {
        zero.next = static_cast<Item*>(&stop);
        stop.prev = static_cast<Item*>(&zero);
    }
    Item* push(T data, List::Item *before = nullptr)
    {
        if (!before) before = static_cast<Item*>(&zero);
        Item *self = new Item(data);
        before->prev->next = self;
        self->prev = before->prev;
        before->prev = self;
        self->next = before;
        return self;
    }
    void enumerate(void(func)(T data))
    {
        for (auto it = zero.next; it != static_cast<Item*>(&stop); it = it->next)
            func(it->data);
    }
};

int main()
{
    List<const char*> man;
    man.push("кресты");
    auto p1 = man.push("лучший");
    auto p2 = man.push("в мире");
    man.enumerate([](const char *s) {
        puts(s);
    });
    puts("");
    man.push("язык", p2);
    man.push("самый", p1);
    man.enumerate([](const char *s) {
        puts(s);
    });
    return 0;
}
