stack.h 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 <cstddef>
  7. #include <iterator>
  8. #include <vector>
  9. #include "common/check.h"
  10. #include "executable_semantics/interpreter/list_node.h"
  11. namespace Carbon {
  12. // A stack data structure.
  13. template <class T>
  14. struct Stack {
  15. using const_iterator = typename std::vector<T>::const_reverse_iterator;
  16. // Creates an empty instance.
  17. Stack() = default;
  18. // Creates an instance containing just `x`.
  19. // TODO: consider removing this. It's somewhat unconventional, and the
  20. // callsite readability is debatable.
  21. explicit Stack(T x) : Stack() { Push(std::move(x)); }
  22. // Pushes `x` onto the top of the stack.
  23. void Push(T x) { elements.push_back(std::move(x)); }
  24. // Removes and returns the top element of the stack.
  25. //
  26. // - Requires: !this->IsEmpty()
  27. auto Pop() -> T {
  28. CHECK(!IsEmpty()) << "Can't pop from empty stack.";
  29. auto r = std::move(elements.back());
  30. elements.pop_back();
  31. return r;
  32. }
  33. // Removes the top `n` elements of the stack.
  34. //
  35. // - Requires: n >= 0 && n <= Count()
  36. void Pop(int n) {
  37. CHECK(n >= 0) << "Negative pop count disallowed.";
  38. CHECK(static_cast<size_t>(n) <= elements.size())
  39. << "Can only pop as many elements as stack has.";
  40. elements.resize(elements.size() - n);
  41. }
  42. // Returns the top element of the stack.
  43. //
  44. // - Requires: !this->IsEmpty()
  45. auto Top() const -> T {
  46. CHECK(!IsEmpty()) << "Empty stack has no Top().";
  47. return elements.back();
  48. }
  49. // Returns `true` iff `Count() > 0`.
  50. auto IsEmpty() const -> bool { return elements.empty(); }
  51. // Returns the number of elements in `*this`.
  52. auto Count() const -> int { return elements.size(); }
  53. // Iterates over the Stack from top to bottom.
  54. const_iterator begin() const { return elements.crbegin(); }
  55. const_iterator end() const { return elements.crend(); }
  56. private:
  57. std::vector<T> elements;
  58. };
  59. // Explicitly enable CTAD to silence warnings.
  60. // TODO: consider removing this (and perhaps the associated constructor).
  61. template <typename T>
  62. Stack(T x) -> Stack<T>;
  63. } // namespace Carbon
  64. #endif // EXECUTABLE_SEMANTICS_INTERPRETER_CONS_LIST_H_