Yume
scope_container.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "util.hpp"
4#include <iterator>
5#include <llvm/ADT/STLExtras.h>
6#include <llvm/ADT/StringMap.h>
7#include <ranges>
8#include <vector>
9
10namespace yume {
11template <typename T> class ScopeContainerGuard;
12
13template <typename T> class ScopeContainer {
14 std::deque<llvm::StringMap<T>> m_scopes{};
15
16public:
17 [[nodiscard]] auto all_scopes() const noexcept -> const auto& { return m_scopes; }
18 [[nodiscard]] auto last_scope() const noexcept -> const auto& { return m_scopes.back(); }
19 [[nodiscard]] auto last_scope() noexcept -> auto& { return m_scopes.back(); }
20 [[nodiscard]] auto push_scope_guarded() noexcept -> ScopeContainerGuard<T>;
21 void push_scope() noexcept { m_scopes.emplace_back(); }
22 void pop_scope() noexcept { m_scopes.pop_back(); }
23
24 auto add(std::string_view key, T object) noexcept { return m_scopes.back().try_emplace(key, move(object)); }
25 auto add_to_front(std::string_view key, T object) noexcept { return m_scopes.front().try_emplace(key, move(object)); }
26 [[nodiscard]] auto find(std::string_view key) const noexcept -> nullable<const T*> {
27 for (const auto& scope : llvm::reverse(m_scopes))
28 if (auto lookup = scope.find(key); lookup != scope.end())
29 return &lookup->getValue();
30 return nullptr;
31 }
32 [[nodiscard]] auto find(std::string_view key) noexcept -> nullable<T*> {
33 for (auto& scope : llvm::reverse(m_scopes))
34 if (auto lookup = scope.find(key); lookup != scope.end())
35 return &lookup->getValue();
36 return nullptr;
37 }
38 void clear() noexcept { m_scopes.clear(); }
39 auto size() noexcept -> size_t { return m_scopes.size(); }
40};
41
42template <typename T> class ScopeContainerGuard {
43 ScopeContainer<T>& m_container;
44 size_t m_prev_size;
45
46public:
47 ScopeContainerGuard(ScopeContainer<T>& container, size_t prev_size)
48 : m_container(container), m_prev_size(prev_size) {}
50 YUME_ASSERT(m_container.size() == m_prev_size, "Cannot pop scope when scope is in invalid state");
51 m_container.pop_scope();
52 }
55 auto operator=(const ScopeContainerGuard<T>&) = delete;
57};
58
59template <typename T> auto ScopeContainer<T>::push_scope_guarded() noexcept -> ScopeContainerGuard<T> {
60 push_scope();
61 return {*this, size()};
62}
63} // namespace yume
ScopeContainerGuard(const ScopeContainerGuard< T > &)=delete
ScopeContainerGuard(ScopeContainer< T > &container, size_t prev_size)
ScopeContainerGuard(ScopeContainerGuard< T > &&)=delete
auto operator=(ScopeContainerGuard< T > &&)=delete
auto operator=(const ScopeContainerGuard< T > &)=delete
void push_scope() noexcept
auto last_scope() noexcept -> auto &
auto add(std::string_view key, T object) noexcept
auto push_scope_guarded() noexcept -> ScopeContainerGuard< T >
auto find(std::string_view key) const noexcept -> nullable< const T * >
void pop_scope() noexcept
auto last_scope() const noexcept -> const auto &
auto add_to_front(std::string_view key, T object) noexcept
auto size() noexcept -> size_t
void clear() noexcept
auto all_scopes() const noexcept -> const auto &
auto find(std::string_view key) noexcept -> nullable< T * >
Definition: ast.cpp:8
T nullable
Definition: util.hpp:72
#define YUME_ASSERT(assertion, message)
Definition: util.hpp:81