#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;
}
I2luY2x1ZGUgPGNzdGRpbz4KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+Y2xhc3MgTGlzdAp7CnB1YmxpYzoKICAgIGNsYXNzIEl0ZW07CnByaXZhdGU6CiAgICBjbGFzcyBOZXh0CiAgICB7CiAgICAgICAgSXRlbSAqbmV4dDsKICAgICAgICBmcmllbmQgY2xhc3MgTGlzdDsKICAgIH07CiAgICBjbGFzcyBQcmV2CiAgICB7CiAgICAgICAgSXRlbSAqcHJldjsKICAgICAgICBmcmllbmQgY2xhc3MgTGlzdDsKICAgIH07CiAgICBOZXh0IHplcm87CiAgICBQcmV2IHN0b3A7CnB1YmxpYzoKICAgIGNsYXNzIEl0ZW0gOiBwdWJsaWMgTmV4dCwgcHVibGljIFByZXYKICAgIHsKICAgICAgICBmcmllbmQgY2xhc3MgTGlzdDsKICAgIHB1YmxpYzoKICAgICAgICBUIGRhdGE7CiAgICAgICAgSXRlbShUIGRhdGEpIDogZGF0YShkYXRhKSB7fQogICAgfTsKICAgIExpc3QoKQogICAgewogICAgICAgIHplcm8ubmV4dCA9IHN0YXRpY19jYXN0PEl0ZW0qPigmc3RvcCk7CiAgICAgICAgc3RvcC5wcmV2ID0gc3RhdGljX2Nhc3Q8SXRlbSo+KCZ6ZXJvKTsKICAgIH0KICAgIEl0ZW0qIHB1c2goVCBkYXRhLCBMaXN0OjpJdGVtICpiZWZvcmUgPSBudWxscHRyKQogICAgewogICAgICAgIGlmICghYmVmb3JlKSBiZWZvcmUgPSBzdGF0aWNfY2FzdDxJdGVtKj4oJnplcm8pOwogICAgICAgIEl0ZW0gKnNlbGYgPSBuZXcgSXRlbShkYXRhKTsKICAgICAgICBiZWZvcmUtPnByZXYtPm5leHQgPSBzZWxmOwogICAgICAgIHNlbGYtPnByZXYgPSBiZWZvcmUtPnByZXY7CiAgICAgICAgYmVmb3JlLT5wcmV2ID0gc2VsZjsKICAgICAgICBzZWxmLT5uZXh0ID0gYmVmb3JlOwogICAgICAgIHJldHVybiBzZWxmOwogICAgfQogICAgdm9pZCBlbnVtZXJhdGUodm9pZChmdW5jKShUIGRhdGEpKQogICAgewogICAgICAgIGZvciAoYXV0byBpdCA9IHplcm8ubmV4dDsgaXQgIT0gc3RhdGljX2Nhc3Q8SXRlbSo+KCZzdG9wKTsgaXQgPSBpdC0+bmV4dCkKICAgICAgICAgICAgZnVuYyhpdC0+ZGF0YSk7CiAgICB9Cn07CgppbnQgbWFpbigpCnsKICAgIExpc3Q8Y29uc3QgY2hhcio+IG1hbjsKICAgIG1hbi5wdXNoKCLQutGA0LXRgdGC0YsiKTsKICAgIGF1dG8gcDEgPSBtYW4ucHVzaCgi0LvRg9GH0YjQuNC5Iik7CiAgICBhdXRvIHAyID0gbWFuLnB1c2goItCyINC80LjRgNC1Iik7CiAgICBtYW4uZW51bWVyYXRlKFtdKGNvbnN0IGNoYXIgKnMpIHsKICAgICAgICBwdXRzKHMpOwogICAgfSk7CiAgICBwdXRzKCIiKTsKICAgIG1hbi5wdXNoKCLRj9C30YvQuiIsIHAyKTsKICAgIG1hbi5wdXNoKCLRgdCw0LzRi9C5IiwgcDEpOwogICAgbWFuLmVudW1lcmF0ZShbXShjb25zdCBjaGFyICpzKSB7CiAgICAgICAgcHV0cyhzKTsKICAgIH0pOwogICAgcmV0dXJuIDA7Cn0K