From d28050ed2369f5d48492dd82b59e8e918505e507 Mon Sep 17 00:00:00 2001 From: dragon Date: Thu, 15 Aug 2024 20:36:55 +0300 Subject: [PATCH] part of new nodes storage implementation --- lang/nodes/include/nodes_storage.hpp | 69 ++++++++++++++++++++++++++++ lang/utils/include/storage.hpp | 55 ++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 lang/nodes/include/nodes_storage.hpp create mode 100644 lang/utils/include/storage.hpp diff --git a/lang/nodes/include/nodes_storage.hpp b/lang/nodes/include/nodes_storage.hpp new file mode 100644 index 0000000..8cc60cb --- /dev/null +++ b/lang/nodes/include/nodes_storage.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include "storage.hpp" + +namespace nodes { + +// FIXME +struct NodeData { + std::variant value; +}; // TODO: union with nodes + +// TODO: replace NodeData with real node +class NodeStorage : public core::Storage { + using Id = storage::Id; + +public: + Id Insert(NodeData &&elem) { + const auto id = NewId(); + utils::Assert(data_.insert({id, std::move(elem)}).second, + std::format("insert failed, id={}", *id)); + return id; + } + +protected: + storage::Id NewId() { return storage::Id{first_unused_id_++}; } + +protected: + size_t first_unused_id_{0}; +}; + +template class NodePart { +public: + NodePart(core::DependentStorage &data) : data_(data) {} + +protected: + core::DependentStorage &data_; +}; + +// TODO: replace all nodes +// Mixins should be NodePart<...> or their children +template class Node_ : public Mixins... { + using Id = storage::Id; + +public: + Node_(Id id, NodeStorage &data, Mixins &&...mixins) + : Mixins(std::move(mixins))..., id_(id), data_(data) {} + + // + + template bool &Has() { return NodePart::data_.Has(id_); } + + // + + template T &part() { return NodePart::data_[id_]; } + + template T &get() { return std::get(data_[id_].value); } + + // + + const NodeData &operator*() const { return data_[id_]; } + + const NodeData *operator->() const { return &data_[id_]; } + +protected: + Id id_; + NodeStorage &data_; +}; + +} // namespace nodes diff --git a/lang/utils/include/storage.hpp b/lang/utils/include/storage.hpp new file mode 100644 index 0000000..b6e10f5 --- /dev/null +++ b/lang/utils/include/storage.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include +#include + +#include "log.hpp" + +namespace storage { + +struct Id { + + size_t operator*() const { return id; } + + const size_t *operator->() const { return &id; } + + size_t id; + + std::strong_ordering operator<=>(const Id &other) const = default; +}; + +} // namespace storage + +namespace core { // TODO: move all important to core + +template class Storage { + using Id = storage::Id; + +public: + bool Has(Id id) const { return data_.count(id) != 0; } + + // + + const T &operator[](Id id) const { return data_.at(id); } + +protected: + std::unordered_map data_ = {}; +}; + +template class DependentStorage : public Storage { + using Id = storage::Id; + +public: + void ForceInsert(Id id, T &&elem) { + utils::Assert(Storage::data_.insert(id, elem).second, + std::format("insert failed, id={}", *id)); + } + + bool Insert(Id id, T &&elem) { + return Storage::data_.insert(id, elem).second; + } +}; + +} // namespace core