#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 : traversal::BFS(&node)) printNode(*child, 0); } void printTreeList(INode& node) { for (auto& child : traversal::DFS(&node)) printNode(*child, 0); } void printTreeLadder(INode& node) { for (auto& [child, level] : traversal::DFS(&node)) printNode(*child, level); } int main() { Logger::setMinSeverity("MAIN", Logger::Severity::Debug); Logger::suppressCategory("Node"); Logger::suppressCategory("Link"); Logger::suppressCategory("Mixin"); Logger::suppressCategory("ConDes"); Logger::setMinSeverity("ConDes", Logger::Severity::Info); auto& logger = Logger::get("MAIN"); logger.info("Entering main scope..."); { auto root = ComplexNode::create("ComplexRoot"); auto child1 = ComplexNode::create("ComplexChild1"); root->linkChild(child1); std::cout << "\nInit tree:\n"; printTreeLadder(*root); std::cout << "\n"; { auto child2 = ComplexNode::create("ComplexChild2"); root->linkChild(child2); auto subchild2 = SimpleNode::create("SimpleSubChild2"); child2->linkChild(subchild2); auto child3 = ComplexNode::create("ComplexChild3"); root->linkChild(child3); child3->linkChild(SimpleNode::create("SimpleSubChild3")); { // Негативный сценарий 1: попытка добавить второй SimpleNode к ComplexNode try { child2->linkChild(SimpleNode::create("ShouldFail")); logger.err("[ERROR] Не должно было получиться добавить второй SimpleNode к ComplexNode!"); } catch (const std::logic_error& e) { logger.warn(std::string("[Ожидаемое исключение] ") + e.what()); } // Негативный сценарий 2: попытка добавить ComplexNode к SimpleNode // Это допустимо: SimpleNode может иметь ComplexNode в качестве единственного ребёнка subchild2->linkChild(ComplexNode::create("GoodComplex")); logger.info("[OK] ComplexNode успешно добавлен к SimpleNode как единственный ребёнок."); // Негативный сценарий: попытка добавить второго ребёнка к SimpleNode try { subchild2->linkChild(SimpleNode::create("ShouldFail2")); logger.err("[ERROR] Не должно было получиться добавить второго ребёнка к SimpleNode!"); } catch (const std::logic_error& e) { logger.warn(std::string("[Ожидаемое исключение] ") + e.what()); } // Негативный сценарий: попытка добавить SimpleNode в ComplexNode, который уже содержит несколько ComplexNode-дочерних try { root->linkChild(SimpleNode::create("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; } } root->linkChild(SimpleNode::create("SimpleChild4")); std::cout << "\nTree flush and link SimpleChild4:\n"; printTreeLadder(*root); std::cout << "\n"; } logger.info("Exited main scope. All smart pointers destroyed."); logger.info("(It don't? Check ConDes logger)"); return 0; }