mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-09 16:38:46 +00:00
part of new nodes storage implementation
This commit is contained in:
parent
3de131623c
commit
d28050ed23
2 changed files with 124 additions and 0 deletions
69
lang/nodes/include/nodes_storage.hpp
Normal file
69
lang/nodes/include/nodes_storage.hpp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#pragma once
|
||||
|
||||
#include "storage.hpp"
|
||||
|
||||
namespace nodes {
|
||||
|
||||
// FIXME
|
||||
struct NodeData {
|
||||
std::variant<int, bool> value;
|
||||
}; // TODO: union with nodes
|
||||
|
||||
// TODO: replace NodeData with real node
|
||||
class NodeStorage : public core::Storage<NodeData> {
|
||||
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 <typename T> class NodePart {
|
||||
public:
|
||||
NodePart(core::DependentStorage<T> &data) : data_(data) {}
|
||||
|
||||
protected:
|
||||
core::DependentStorage<T> &data_;
|
||||
};
|
||||
|
||||
// TODO: replace all nodes
|
||||
// Mixins should be NodePart<...> or their children
|
||||
template <typename... Mixins> 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 <typename T> bool &Has() { return NodePart<T>::data_.Has(id_); }
|
||||
|
||||
//
|
||||
|
||||
template <typename T> T &part() { return NodePart<T>::data_[id_]; }
|
||||
|
||||
template <typename T> T &get() { return std::get<T>(data_[id_].value); }
|
||||
|
||||
//
|
||||
|
||||
const NodeData &operator*() const { return data_[id_]; }
|
||||
|
||||
const NodeData *operator->() const { return &data_[id_]; }
|
||||
|
||||
protected:
|
||||
Id id_;
|
||||
NodeStorage &data_;
|
||||
};
|
||||
|
||||
} // namespace nodes
|
||||
55
lang/utils/include/storage.hpp
Normal file
55
lang/utils/include/storage.hpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include <compare>
|
||||
#include <cstddef>
|
||||
#include <format>
|
||||
#include <unordered_map>
|
||||
|
||||
#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 <typename T> 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<Id, T> data_ = {};
|
||||
};
|
||||
|
||||
template <typename T> class DependentStorage : public Storage<T> {
|
||||
using Id = storage::Id;
|
||||
|
||||
public:
|
||||
void ForceInsert(Id id, T &&elem) {
|
||||
utils::Assert(Storage<T>::data_.insert(id, elem).second,
|
||||
std::format("insert failed, id={}", *id));
|
||||
}
|
||||
|
||||
bool Insert(Id id, T &&elem) {
|
||||
return Storage<T>::data_.insert(id, elem).second;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
Loading…
Add table
Add a link
Reference in a new issue