#include <iostream>
#include <utility>
template<typename T>
class list {
struct list_node;
struct list_node_base;
public:
void reverse() {
std::swap(head.prev, head.next);
for (list_node_base * p = head.prev; p != &head; p = p->prev) {
std::swap(p->prev, p->next);
}
}
bool empty() const {
return &head == head.next;
}
void push_back(T const& value) {
head.insert_before(new list_node(value));
}
template<typename F>
void apply(F f) const {
for (list_node_base * p = head.next; p != &head; p = p->next) {
f(p->get_data());
}
}
~list() {
while (!empty()) {
head.next->erase();
}
}
private:
struct list_node_base {
list_node_base() : prev(this), next(this) {}
void insert_before(list_node_base * const what) {
prev->next = what;
what->prev = prev;
this->prev = what;
what->next = this;
}
void erase() {
prev->next = next;
next->prev = prev;
delete static_cast<list_node *>(this);
}
T & get_data() {
return static_cast<list_node *>(this)->data;
}
T const& get_data() const {
return static_cast<list_node const*>(this)->data;
}
list_node_base * prev;
list_node_base * next;
};
struct list_node : list_node_base {
list_node(T const& data) : data(data) {}
T data;
};
list_node_base head;
};
int main() {
list<int> instance;
for (int i = 0; i != 5; ++i) {
instance.push_back(i);
}
auto const printer = [](int const value) {
std::cout << value << ' ';
};
instance.apply(printer);
std::cout << std::endl;
instance.reverse();
instance.apply(printer);
std::cout << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpjbGFzcyBsaXN0IHsKCiAgIHN0cnVjdCBsaXN0X25vZGU7CiAgIHN0cnVjdCBsaXN0X25vZGVfYmFzZTsKCgpwdWJsaWM6CiAgIHZvaWQgcmV2ZXJzZSgpIHsKICAgCSAgc3RkOjpzd2FwKGhlYWQucHJldiwgaGVhZC5uZXh0KTsKICAgCSAgZm9yIChsaXN0X25vZGVfYmFzZSAqIHAgPSBoZWFkLnByZXY7IHAgIT0gJmhlYWQ7IHAgPSBwLT5wcmV2KSB7CiAgIAkgICAgIHN0ZDo6c3dhcChwLT5wcmV2LCBwLT5uZXh0KTsKICAgCSAgfQogICB9CgogICBib29sIGVtcHR5KCkgY29uc3QgewogICAgICByZXR1cm4gJmhlYWQgPT0gaGVhZC5uZXh0OwogICB9CiAgIAogICB2b2lkIHB1c2hfYmFjayhUIGNvbnN0JiB2YWx1ZSkgewogICAgICBoZWFkLmluc2VydF9iZWZvcmUobmV3IGxpc3Rfbm9kZSh2YWx1ZSkpOwogICB9IAogICAKICAgdGVtcGxhdGU8dHlwZW5hbWUgRj4KICAgdm9pZCBhcHBseShGIGYpIGNvbnN0IHsKICAgICAgZm9yIChsaXN0X25vZGVfYmFzZSAqIHAgPSBoZWFkLm5leHQ7IHAgIT0gJmhlYWQ7IHAgPSBwLT5uZXh0KSB7CiAgICAgICAgIGYocC0+Z2V0X2RhdGEoKSk7CiAgICAgIH0KICAgfQoKICAgfmxpc3QoKSB7CiAgICAgIHdoaWxlICghZW1wdHkoKSkgewogICAgICAgICBoZWFkLm5leHQtPmVyYXNlKCk7CiAgICAgIH0KICAgfQoKCnByaXZhdGU6CiAgIHN0cnVjdCBsaXN0X25vZGVfYmFzZSB7CgogICAgICBsaXN0X25vZGVfYmFzZSgpIDogcHJldih0aGlzKSwgbmV4dCh0aGlzKSB7fQoKICAgICAgdm9pZCBpbnNlcnRfYmVmb3JlKGxpc3Rfbm9kZV9iYXNlICogY29uc3Qgd2hhdCkgewogICAgICAgICBwcmV2LT5uZXh0ID0gd2hhdDsKICAgICAgICAgd2hhdC0+cHJldiA9IHByZXY7CiAgICAgICAgIAogICAgICAgICB0aGlzLT5wcmV2ID0gd2hhdDsKICAgICAgICAgd2hhdC0+bmV4dCA9IHRoaXM7CiAgICAgIH0KCiAgICAgIHZvaWQgZXJhc2UoKSB7CiAgICAgICAgIHByZXYtPm5leHQgPSBuZXh0OwogICAgICAgICBuZXh0LT5wcmV2ID0gcHJldjsKICAgICAgICAgCiAgICAgICAgIGRlbGV0ZSBzdGF0aWNfY2FzdDxsaXN0X25vZGUgKj4odGhpcyk7CiAgICAgIH0KCiAgICAgIFQgJiBnZXRfZGF0YSgpIHsKICAgICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PGxpc3Rfbm9kZSAqPih0aGlzKS0+ZGF0YTsKICAgICAgfQogICAgICBUIGNvbnN0JiBnZXRfZGF0YSgpIGNvbnN0IHsKICAgICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PGxpc3Rfbm9kZSBjb25zdCo+KHRoaXMpLT5kYXRhOwogICAgICB9CgogICAgICBsaXN0X25vZGVfYmFzZSAqIHByZXY7CiAgICAgIGxpc3Rfbm9kZV9iYXNlICogbmV4dDsKICAgfTsKCiAgIHN0cnVjdCBsaXN0X25vZGUgOiBsaXN0X25vZGVfYmFzZSB7CiAgICAKICAgICAgbGlzdF9ub2RlKFQgY29uc3QmIGRhdGEpIDogZGF0YShkYXRhKSB7fQoKICAgICAgVCBkYXRhOwogICB9OwoKICAgbGlzdF9ub2RlX2Jhc2UgaGVhZDsKfTsKCgppbnQgbWFpbigpIHsKICAgbGlzdDxpbnQ+IGluc3RhbmNlOwogICAKICAgZm9yIChpbnQgaSA9IDA7IGkgIT0gNTsgKytpKSB7CiAgICAgIGluc3RhbmNlLnB1c2hfYmFjayhpKTsKICAgfQogICAKICAgYXV0byBjb25zdCBwcmludGVyID0gW10oaW50IGNvbnN0IHZhbHVlKSB7CiAgICAgIHN0ZDo6Y291dCA8PCB2YWx1ZSA8PCAnICc7CiAgIH07CiAgIAogICBpbnN0YW5jZS5hcHBseShwcmludGVyKTsKICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKICAgCiAgIGluc3RhbmNlLnJldmVyc2UoKTsKICAgCiAgIGluc3RhbmNlLmFwcGx5KHByaW50ZXIpOwogICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwp9