aboutsummaryrefslogtreecommitdiff
path: root/src/tree.cc
diff options
context:
space:
mode:
authorAdrian Kummerlaender2014-10-01 20:30:08 +0200
committerAdrian Kummerlaender2014-10-01 20:30:08 +0200
commit0840f434541b57fbd6d3c9d7b2a8b127cc680912 (patch)
tree330df31c2083a48c33be95a2bc7d40f8b5d25470 /src/tree.cc
parent6498a968cd34e49e355cc0765ca2dafb842bc12b (diff)
downloadSimpleParser-0840f434541b57fbd6d3c9d7b2a8b127cc680912.tar
SimpleParser-0840f434541b57fbd6d3c9d7b2a8b127cc680912.tar.gz
SimpleParser-0840f434541b57fbd6d3c9d7b2a8b127cc680912.tar.bz2
SimpleParser-0840f434541b57fbd6d3c9d7b2a8b127cc680912.tar.lz
SimpleParser-0840f434541b57fbd6d3c9d7b2a8b127cc680912.tar.xz
SimpleParser-0840f434541b57fbd6d3c9d7b2a8b127cc680912.tar.zst
SimpleParser-0840f434541b57fbd6d3c9d7b2a8b127cc680912.zip
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
Diffstat (limited to 'src/tree.cc')
-rw-r--r--src/tree.cc60
1 files changed, 39 insertions, 21 deletions
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 <typename NodeType, typename... Args>
-Node* Tree::addNode(Args&&... args) {
+template <
+ typename Type,
+ typename... Args
+>
+typename std::add_pointer<Type>::type Tree::addNode(Args&&... args) {
this->node_collection_.emplace_back(
- std::make_unique<NodeType>(
+ std::make_unique<Type>(
std::forward<Args>(args)...
)
);
- return this->node_collection_.back().get();
+ return static_cast<typename std::add_pointer<Type>::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<OperatorNode>(elementToken)
);
} else {
- Node*const currOperator = popNode(operators);
- currOperator->rightChild = popNode(operands);
- currOperator->leftChild = popNode(operands);
+ OperatorNode*const currOperator(
+ static_cast<OperatorNode*const>(
+ 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<OperandNode>(
- stringToDouble(subElements.front())
- ));
+ operands.push(
+ this->addNode<OperandNode>(
+ stringToDouble(subElements.front())
+ )
+ );
break;
}
case TokenType::VALUE_IDENTIFIER: {
- operands.push(this->addNode<ConstantNode>(
- subElements.front(),
- this->constants_
- ));
+ operands.push(
+ this->addNode<ConstantNode>(
+ subElements.front(),
+ this->constants_
+ )
+ );
break;
}
@@ -175,11 +189,15 @@ Node* Tree::buildTree(const std::string& term) {
while ( !operators.empty() ) {
OperatorNode*const currOperator(
- static_cast<OperatorNode*const>(popNode(operators))
+ static_cast<OperatorNode*const>(
+ popNode(operators)
+ )
);
- currOperator->rightChild = popNode(operands);
- currOperator->leftChild = popNode(operands);
+ currOperator->setChildren(
+ popNode(operands),
+ popNode(operands)
+ );
operands.push(currOperator);
}