stack.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef EXECUTABLE_SEMANTICS_INTERPRETER_STACK_H_
  5. #define EXECUTABLE_SEMANTICS_INTERPRETER_STACK_H_
  6. #include <cassert>
  7. #include <cstddef>
  8. #include <iterator>
  9. #include "executable_semantics/interpreter/list_node.h"
  10. namespace Carbon {
  11. /// A persistent stack data structure.
  12. ///
  13. /// - Note: this data structure leaks memory.
  14. template <class T>
  15. struct Stack {
  16. /// A forward iterator over elements of a `Stack`.
  17. struct Iterator {
  18. using value_type = T;
  19. using difference_type = std::ptrdiff_t;
  20. using pointer = const T*;
  21. using reference = const T&;
  22. using iterator_category = std::forward_iterator_tag;
  23. Iterator(ListNode<T>* x) : p(x) {}
  24. Iterator(const Iterator& mit) : p(mit.p) {}
  25. Iterator& operator++() {
  26. p = p->next;
  27. return *this;
  28. }
  29. Iterator operator++(int) {
  30. Iterator tmp(*this);
  31. operator++();
  32. return tmp;
  33. }
  34. bool operator==(const Iterator& rhs) const { return p == rhs.p; }
  35. bool operator!=(const Iterator& rhs) const { return p != rhs.p; }
  36. const T& operator*() { return p->curr; }
  37. const T* operator->() { return &p->curr; }
  38. private:
  39. ListNode<T>* p;
  40. };
  41. /// The position of the first/`Top()` element, or `end()` if
  42. /// `this->IsEmpty()`.
  43. auto begin() const -> Iterator { return Iterator(head); }
  44. /// The position one past that of the last element.
  45. auto end() const -> Iterator { return Iterator(nullptr); }
  46. /// Creates an empty instance.
  47. Stack() { head = nullptr; }
  48. /// Creates an instance containing just `x`.
  49. Stack(T x) : Stack() { Push(x); }
  50. /// Pushes `x` onto the top of the stack.
  51. void Push(T x) { head = new ListNode<T>(x, head); }
  52. /// Returns a copy of `*this`, with `x` pushed onto the top.
  53. auto Pushing(T x) const -> Stack {
  54. auto r = *this;
  55. r.Push(x);
  56. return r;
  57. }
  58. /// Removes and returns the top element of the stack.
  59. ///
  60. /// - Requires: !this->IsEmpty()
  61. auto Pop() -> T {
  62. assert(!IsEmpty() && "Can't pop from empty stack.");
  63. auto r = head->curr;
  64. head = head->next;
  65. return r;
  66. }
  67. /// Removes the top `n` elements of the stack.
  68. ///
  69. /// - Requires: n >= 0 && n <= Count()
  70. void Pop(int n) {
  71. assert(n >= 0 && "Negative pop count disallowed.");
  72. while (n--) {
  73. assert(head != nullptr && "Can only pop as many elements as stack has.");
  74. head = head->next;
  75. }
  76. }
  77. /// Returns a copy of `*this`, sans the top element.
  78. ///
  79. /// - Requires: !this->IsEmpty()
  80. auto Popped() const -> Stack {
  81. auto r = *this;
  82. r.Pop();
  83. return r;
  84. }
  85. /// Returns the top element of the stack.
  86. ///
  87. /// - Requires: !this->IsEmpty()
  88. auto Top() const -> T {
  89. assert(!IsEmpty() && "Empty stack has no Top().");
  90. return head->curr;
  91. }
  92. /// Returns `true` iff `Count() > 0`.
  93. auto IsEmpty() const -> bool { return head == nullptr; }
  94. /// Returns `true` iff `Count() > n`.
  95. ///
  96. /// - Complexity: O(`n`)
  97. auto CountExceeds(int n) const -> bool {
  98. if (n < 0)
  99. return true;
  100. for (auto p = head; p != nullptr; p = p->next) {
  101. if (n-- == 0)
  102. return true;
  103. }
  104. return false;
  105. }
  106. /// Returns the number of elements in `*this`.
  107. auto Count() const -> int { return std::distance(begin(), end()); }
  108. private:
  109. /// An linked list of cells containing the elements of self.
  110. ListNode<T>* head;
  111. };
  112. } // namespace Carbon
  113. #endif // EXECUTABLE_SEMANTICS_INTERPRETER_CONS_LIST_H_