part of new nodes storage implementation

This commit is contained in:
dragon 2024-08-15 20:36:55 +03:00
parent 3de131623c
commit d28050ed23
2 changed files with 124 additions and 0 deletions

View 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

View 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