poperdolilo

This commit is contained in:
Сергей Маринкевич
2025-07-21 18:14:27 +07:00
parent 8b60fc0183
commit b2be9b51ca
10 changed files with 230 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include "ifaces/INode.h"
#include "links/LeafLink.h"
#include "links/OneToManyLink.h"
#include <memory>
template <class TFinalNode>
class LazyLinkMixin : public INode {
public:
void linkChild(const NodePtr& childNode) override {
lazyInit();
upgradeLinkIfNeeded();
LinkPtr childLink = childNode->getLink();
childLink->setParent(link_);
link_->addChild(childLink);
}
void unlinkParent() override {
lazyInit();
LinkPtr parentLink = link_->getParent();
if (!parentLink) return;
parentLink->removeChild(this->getLink());
link_->setParent(nullptr);
}
LinkPtr getLink() override {
lazyInit();
return link_;
}
protected:
virtual std::shared_ptr<TFinalNode> getShared() = 0;
NodePtr getSelf() override { return getShared(); }
private:
void lazyInit() {
if (!link_) {
link_ = std::make_shared<LeafLink>(getSelf());
}
}
void upgradeLinkIfNeeded() {
if (!std::dynamic_pointer_cast<LeafLink>(link_)) return;
auto newLink = std::make_shared<OneToManyLink>(getSelf());
if (auto parentLink = link_->getParent()) {
parentLink->removeChild(link_);
parentLink->addChild(newLink);
}
newLink->setParent(link_->getParent());
link_ = newLink;
}
void downgradeLinkIfPossible() {
if (link_->getChildren().empty() && std::dynamic_pointer_cast<OneToManyLink>(link_)) {
auto newLink = std::make_shared<LeafLink>(getSelf());
if (auto parentLink = link_->getParent()) {
parentLink->removeChild(link_);
parentLink->addChild(newLink);
}
newLink->setParent(link_->getParent());
link_ = newLink;
}
}
LinkPtr link_;
};