void test_depth_first_iterator::test_dfi() { std::string infix("7-(3+(4-6))+1*8"); CEvaluationTree* pTree = new CEvaluationTree(); pTree->setInfix(infix); std::string s = pTree->getInfix(); CPPUNIT_ASSERT(pTree->getRoot() != NULL); CEvaluationNodeDepthFirstIterator it(pTree->getRoot()); CPPUNIT_ASSERT(it.isValid()); CEvaluationNode* pNode = NULL; CEvaluationNodeNumber* pNumberNode = NULL; CEvaluationNodeOperator* pOperatorNode = NULL; // 7 pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 7) / 7.0) <= std::numeric_limits<double>::min()); // 3 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 3) / 3.0) <= std::numeric_limits<double>::min()); // 4 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 4) / 4.0) <= std::numeric_limits<double>::min()); // 6 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 6) / 6.0) <= std::numeric_limits<double>::min()); // - ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MINUS); // + ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::PLUS); // - ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MINUS); // 1 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 1) / 1.0) <= std::numeric_limits<double>::min()); // 8 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 8) / 8.0) <= std::numeric_limits<double>::min()); // * ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MULTIPLY); // + ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::PLUS); ++it; CPPUNIT_ASSERT(it.isValid() == false); CPPUNIT_ASSERT(*it == NULL); delete pTree; }
bool CEvaluationNodeNormalizer::eliminateMultipleNumbers(CEvaluationNodeOperator::SubType subType, std::vector<CEvaluationNode*>& chainNodes) { // check if there are several numerical values in the operator chain and // evaluate those operations bool changed = false; if (chainNodes.size() > 1) { std::vector<CEvaluationNode*>::iterator it = chainNodes.begin(), endit = chainNodes.end(); if (subType == CEvaluationNodeOperator::MULTIPLY || subType == CEvaluationNodeOperator::PLUS) { double value = (subType == CEvaluationNodeOperator::MULTIPLY) ? 1.0 : 0.0; CEvaluationNodeNumber* pNumberNode = NULL; std::vector<CEvaluationNode*> numbers; while (it != endit) { pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(*it); if (pNumberNode != NULL) { numbers.push_back(pNumberNode); if (subType == CEvaluationNodeOperator::MULTIPLY) { value *= pNumberNode->value(); } else { value += pNumberNode->value(); } } ++it; } if (numbers.size() > 1) { changed = true; it = numbers.begin(), endit = numbers.end(); // don't delete the last one since we reset it's value --endit; while (it != endit) { chainNodes.erase(std::find(chainNodes.begin(), chainNodes.end(), *it)); delete *it; ++it; } std::ostringstream os; os << value; (*it)->setData(os.str()); } } } return changed; }