From 0840f434541b57fbd6d3c9d7b2a8b127cc680912 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Wed, 1 Oct 2014 20:30:08 +0200 Subject: Moved child pointers to OperatorNode class * access was restricted by declaring them private and offering member methods such as "hasChildren" * only OperatorNode instances have children, there is no reason for wasting space by keeping empty pointers around in all other instances * this enabled the removal of all nullptr comparisons from tree construction * changed "Tree::addNode" factory method template to return a pointer to the type of the constructed node instance instead of a plain node pointer --- src/tree.cc | 60 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 21 deletions(-) (limited to 'src/tree.cc') diff --git a/src/tree.cc b/src/tree.cc index ab227e4..419a05c 100644 --- a/src/tree.cc +++ b/src/tree.cc @@ -61,13 +61,11 @@ std::string Tree::print() const { << node->print() << "\"]; "; - if ( node->rightChild != nullptr && - node->leftChild != nullptr ) { + if ( node->hasChildren() ) { std::size_t childIndex{}; for ( auto&& child : this->node_collection_ ) { - if ( child.get() == node->leftChild || - child.get() == node->rightChild ) { + if ( node->isParentOf(child.get()) ) { out << "\"node" << nodeIndex << "\" -> \"node" @@ -87,15 +85,20 @@ std::string Tree::print() const { return out.str(); } -template -Node* Tree::addNode(Args&&... args) { +template < + typename Type, + typename... Args +> +typename std::add_pointer::type Tree::addNode(Args&&... args) { this->node_collection_.emplace_back( - std::make_unique( + std::make_unique( std::forward(args)... ) ); - return this->node_collection_.back().get(); + return static_cast::type>( + this->node_collection_.back().get() + ); } Node* Tree::buildTree(const std::string& term) { @@ -129,9 +132,16 @@ Node* Tree::buildTree(const std::string& term) { this->addNode(elementToken) ); } else { - Node*const currOperator = popNode(operators); - currOperator->rightChild = popNode(operands); - currOperator->leftChild = popNode(operands); + OperatorNode*const currOperator( + static_cast( + popNode(operators) + ) + ); + + currOperator->setChildren( + popNode(operands), + popNode(operands) + ); operands.push(currOperator); @@ -147,17 +157,21 @@ Node* Tree::buildTree(const std::string& term) { switch ( determineToken(subElements.front()) ) { case TokenType::VALUE_NUMBER: case TokenType::OPERATOR_MINUS: { - operands.push(this->addNode( - stringToDouble(subElements.front()) - )); + operands.push( + this->addNode( + stringToDouble(subElements.front()) + ) + ); break; } case TokenType::VALUE_IDENTIFIER: { - operands.push(this->addNode( - subElements.front(), - this->constants_ - )); + operands.push( + this->addNode( + subElements.front(), + this->constants_ + ) + ); break; } @@ -175,11 +189,15 @@ Node* Tree::buildTree(const std::string& term) { while ( !operators.empty() ) { OperatorNode*const currOperator( - static_cast(popNode(operators)) + static_cast( + popNode(operators) + ) ); - currOperator->rightChild = popNode(operands); - currOperator->leftChild = popNode(operands); + currOperator->setChildren( + popNode(operands), + popNode(operands) + ); operands.push(currOperator); } -- cgit v1.2.3