#include #include "Logger.h" #include "nodes/SimpleNode.h" #include "nodes/ComplexNode.h" #include "iterators/Traversal.h" void printNode(INode& node, size_t level) { for (size_t i = level; i > 0; i--) std::cout << " "; std::cout << node.name() << "\n"; } void printTreeBFS(INode& node) { for (auto& child : TraversalBFS(&node)) printNode(*child, 0); } void printTreeList(INode& node) { for (auto& child : TraversalDFS(&node)) printNode(*child, 0); } void printTreeLadder(INode& node) { for (auto& [child, level] : TraversalDFS(&node)) printNode(*child, level); } int main() { Logger::setMinSeverity("MAIN", Logger::Severity::Debug); Logger::suppressCategory("Node"); Logger::suppressCategory("Link"); Logger::suppressCategory("Mixin"); auto& logger = Logger::get("MAIN"); logger.info("Entering main scope..."); { auto root = std::make_shared("ComplexRoot"); auto child1 = std::make_shared("ComplexChild1"); root->linkChild(child1); std::cout << "\nInit tree:\n"; printTreeLadder(*root); std::cout << "\n"; { auto child2 = std::make_shared("ComplexChild2"); root->linkChild(child2); auto subchild2 = std::make_shared("SimpleSubChild2"); child2->linkChild(subchild2); auto child3 = std::make_shared("ComplexChild3"); root->linkChild(child3); auto subchild3 = std::make_shared("SimpleSubChild3"); child3->linkChild(subchild3); { // Негативный сценарий 1: попытка добавить второй SimpleNode к ComplexNode try { auto anotherSimple = std::make_shared("ShouldFail"); child2->linkChild(anotherSimple); logger.err("[ERROR] Не должно было получиться добавить второй SimpleNode к ComplexNode!"); } catch (const std::logic_error& e) { logger.warn(std::string("[Ожидаемое исключение] ") + e.what()); } // Негативный сценарий 2: попытка добавить ComplexNode к SimpleNode // Это допустимо: SimpleNode может иметь ComplexNode в качестве единственного ребёнка auto goodComplex = std::make_shared("GoodComplex"); subchild2->linkChild(goodComplex); logger.info("[OK] ComplexNode успешно добавлен к SimpleNode как единственный ребёнок."); // Негативный сценарий: попытка добавить второго ребёнка к SimpleNode try { auto anotherSimple = std::make_shared("ShouldFail2"); subchild2->linkChild(anotherSimple); logger.err("[ERROR] Не должно было получиться добавить второго ребёнка к SimpleNode!"); } catch (const std::logic_error& e) { logger.warn(std::string("[Ожидаемое исключение] ") + e.what()); } // Негативный сценарий: попытка добавить SimpleNode в ComplexNode, который уже содержит несколько ComplexNode-дочерних try { auto badSimple = std::make_shared("BadSimple"); root->linkChild(badSimple); logger.err("[ERROR] Не должно было получиться добавить SimpleNode в ComplexNode с несколькими ComplexNode-дочерними!"); } catch (const std::logic_error& e) { logger.warn(std::string("[Ожидаемое исключение] ") + e.what()); } } std::cout << "\nAnother tree:\n"; printTreeLadder(*root); std::cout << "\n"; std::cout << "\nList:\n"; printTreeList(*root); std::cout << "\n"; std::cout << "\nBFS:\n"; printTreeBFS(*root); std::cout << "\n"; logger.info("Unlinking ComplexChild2...\n"); child2->unlinkParent(); std::cout << "\nTree after unlink:\n"; printTreeLadder(*root); std::cout << "\n"; logger.info("Put refs of ComplexChild2, ComplexChild3 and its children"); } std::cout << "\nTree after scope out:\n"; printTreeLadder(*root); std::cout << "\n"; logger.info("Unlinking ComplexChild1 and ComplexChild3...\n"); child1->unlinkParent(); for (auto child : root->getLink()->getChildren()) { NodePtr childNode = std::dynamic_pointer_cast(child); if (childNode->name() == "ComplexChild3") { childNode->unlinkParent(); break; } } auto child4 = std::make_shared("SimpleChild4"); root->linkChild(child4); std::cout << "\nTree flush and link SimpleChild4:\n"; printTreeLadder(*root); std::cout << "\n"; } logger.info("Exited main scope. All smart pointers destroyed."); return 0; }