arena.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  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_COMMON_ARENA_H_
  5. #define EXECUTABLE_SEMANTICS_COMMON_ARENA_H_
  6. #include <memory>
  7. #include <type_traits>
  8. #include <vector>
  9. #include "executable_semantics/common/nonnull.h"
  10. namespace Carbon {
  11. class Arena {
  12. public:
  13. // Allocates an object in the arena, returning a pointer to it.
  14. template <
  15. typename T, typename... Args,
  16. typename std::enable_if_t<std::is_constructible_v<T, Args...>>* = nullptr>
  17. auto New(Args&&... args) -> Nonnull<T*> {
  18. auto smart_ptr =
  19. std::make_unique<ArenaEntryTyped<T>>(std::forward<Args>(args)...);
  20. Nonnull<T*> ptr = smart_ptr->Instance();
  21. arena_.push_back(std::move(smart_ptr));
  22. return ptr;
  23. }
  24. private:
  25. // Virtualizes arena entries so that a single vector can contain many types,
  26. // avoiding templated statics.
  27. class ArenaEntry {
  28. public:
  29. virtual ~ArenaEntry() = default;
  30. };
  31. // Templated destruction of a pointer.
  32. template <typename T>
  33. class ArenaEntryTyped : public ArenaEntry {
  34. public:
  35. template <typename... Args>
  36. explicit ArenaEntryTyped(Args&&... args)
  37. : instance_(std::forward<Args>(args)...) {}
  38. auto Instance() -> Nonnull<T*> { return Nonnull<T*>(&instance_); }
  39. private:
  40. T instance_;
  41. };
  42. // Manages allocations in an arena for destruction at shutdown.
  43. std::vector<std::unique_ptr<ArenaEntry>> arena_;
  44. };
  45. } // namespace Carbon
  46. #endif // EXECUTABLE_SEMANTICS_COMMON_ARENA_H_