array_stack.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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 CARBON_COMMON_ARRAY_STACK_H_
  5. #define CARBON_COMMON_ARRAY_STACK_H_
  6. #include "common/check.h"
  7. #include "llvm/ADT/ArrayRef.h"
  8. #include "llvm/ADT/SmallVector.h"
  9. namespace Carbon {
  10. // Provides a stack of arrays. Only the array at the top of the stack can have
  11. // elements added.
  12. //
  13. // Example usage:
  14. // // Push to start.
  15. // PushArray();
  16. // // Add values.
  17. // AppendToTop(3);
  18. // // Look at values.
  19. // PeekArray();
  20. // // Pop when done.
  21. // PopArray();
  22. //
  23. // By using a single vector for elements, the intent is that as arrays are
  24. // pushed and popped, the same storage will be reused. This should yield
  25. // efficiencies for heap allocations. For example, in the toolchain we
  26. // frequently have an array per scope, and only add to the current scope's
  27. // array; this allows better reuse when entering and leaving scopes.
  28. template <typename ValueT>
  29. class ArrayStack {
  30. public:
  31. // Pushes a new array onto the stack.
  32. auto PushArray() -> void { array_offsets_.push_back(values_.size()); }
  33. // Pops the top array from the stack.
  34. auto PopArray() -> void {
  35. auto region = array_offsets_.pop_back_val();
  36. values_.truncate(region);
  37. }
  38. // Returns the top array from the stack.
  39. auto PeekArray() const -> llvm::ArrayRef<ValueT> {
  40. CARBON_CHECK(!array_offsets_.empty());
  41. return llvm::ArrayRef(values_).slice(array_offsets_.back());
  42. }
  43. // Returns the full set of values on the stack, regardless of whether any
  44. // arrays are pushed.
  45. auto PeekAllValues() const -> llvm::ArrayRef<ValueT> { return values_; }
  46. // Appends a value to the top array on the stack.
  47. auto AppendToTop(ValueT value) -> void {
  48. CARBON_CHECK(!array_offsets_.empty())
  49. << "Must call PushArray before PushValue.";
  50. values_.push_back(value);
  51. }
  52. // Returns the current number of values in all arrays.
  53. auto all_values_size() const -> size_t { return values_.size(); }
  54. private:
  55. // For each pushed array, the start index in elements_.
  56. llvm::SmallVector<int32_t> array_offsets_;
  57. // The full set of elements in all arrays.
  58. llvm::SmallVector<ValueT> values_;
  59. };
  60. } // namespace Carbon
  61. #endif // CARBON_COMMON_ARRAY_STACK_H_