mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58: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