fork download
  1. #include <iostream>
  2. #include <utility>
  3.  
  4.  
  5. template<typename T>
  6. class list {
  7.  
  8. struct list_node;
  9. struct list_node_base;
  10.  
  11.  
  12. public:
  13. void reverse() {
  14. std::swap(head.prev, head.next);
  15. for (list_node_base * p = head.prev; p != &head; p = p->prev) {
  16. std::swap(p->prev, p->next);
  17. }
  18. }
  19.  
  20. bool empty() const {
  21. return &head == head.next;
  22. }
  23.  
  24. void push_back(T const& value) {
  25. head.insert_before(new list_node(value));
  26. }
  27.  
  28. template<typename F>
  29. void apply(F f) const {
  30. for (list_node_base * p = head.next; p != &head; p = p->next) {
  31. f(p->get_data());
  32. }
  33. }
  34.  
  35. ~list() {
  36. while (!empty()) {
  37. head.next->erase();
  38. }
  39. }
  40.  
  41.  
  42. private:
  43. struct list_node_base {
  44.  
  45. list_node_base() : prev(this), next(this) {}
  46.  
  47. void insert_before(list_node_base * const what) {
  48. prev->next = what;
  49. what->prev = prev;
  50.  
  51. this->prev = what;
  52. what->next = this;
  53. }
  54.  
  55. void erase() {
  56. prev->next = next;
  57. next->prev = prev;
  58.  
  59. delete static_cast<list_node *>(this);
  60. }
  61.  
  62. T & get_data() {
  63. return static_cast<list_node *>(this)->data;
  64. }
  65. T const& get_data() const {
  66. return static_cast<list_node const*>(this)->data;
  67. }
  68.  
  69. list_node_base * prev;
  70. list_node_base * next;
  71. };
  72.  
  73. struct list_node : list_node_base {
  74.  
  75. list_node(T const& data) : data(data) {}
  76.  
  77. T data;
  78. };
  79.  
  80. list_node_base head;
  81. };
  82.  
  83.  
  84. int main() {
  85. list<int> instance;
  86.  
  87. for (int i = 0; i != 5; ++i) {
  88. instance.push_back(i);
  89. }
  90.  
  91. auto const printer = [](int const value) {
  92. std::cout << value << ' ';
  93. };
  94.  
  95. instance.apply(printer);
  96. std::cout << std::endl;
  97.  
  98. instance.reverse();
  99.  
  100. instance.apply(printer);
  101. std::cout << std::endl;
  102. }
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
0 1 2 3 4 
4 3 2 1 0