/////////////////////////////////////////////////////////////////////// // Math Type Library // $Id: library.tcc,v 1.5 2002/04/29 19:34:30 cparpart Exp $ // (module info here) // // Copyright (c) 2002 by Christian Parpart // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with this library; see the file COPYING.LIB. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. /////////////////////////////////////////////////////////////////////// #include #include #include #include #include namespace math { /////////////////////////////////////////////////////////////////////// // TFunction<> // /////////////////////////////////////////////////////////////////////// template TFunction::TFunction() : FName("f"), FExpression(0) { } template TFunction::TFunction(const TFunction& ACopy) : FName(ACopy.FName), FExpression(ACopy.FExpression->clone()) { } template TFunction::TFunction(const std::string& AName, const std::string& AExprStr) : FName(AName), FExpression(0) { expression(AExprStr); } template TFunction::TFunction(const std::string& AName, const TNode *ACopyOf) : FName(AName), FExpression(ACopyOf->clone()) { } template TFunction::~TFunction() { // FExpression is either 0 or contains valid allocated data // so we may delete it without any check. delete FExpression; } template T TFunction::call(const T& AParam, const TLibrary& ALibrary, unsigned ALimit) const { return TCalculator::calculate(*this, AParam, ALibrary, ALimit); } template void TFunction::name(const std::string& AName) { FName = AName; } template std::string TFunction::name() const { return FName; } template void TFunction::expression(const TNode *ACopyOf) { delete FExpression; FExpression = ACopyOf->clone(); } template void TFunction::expression(const std::string& AExprStr) { delete FExpression; try { FExpression = math::TReader::parse(AExprStr); } catch (...) { // set FExpression to zero if parser has thrown... FExpression = 0; throw; } } template TNode *TFunction::expression() const { return FExpression; } /////////////////////////////////////////////////////////////////////// // TConstant<> // /////////////////////////////////////////////////////////////////////// template TConstant::TConstant() : FName("c"), FValue(1) { } template TConstant::TConstant(const TConstant& ACopyOf) : FName(ACopyOf.FName), FValue(ACopyOf.FValue) { } template TConstant::TConstant(const std::string& AName, const T& AValue) : FName(AName), FValue(AValue) { } template void TConstant::name(const std::string& AName) { FName = AName; } template std::string TConstant::name() const { return FName; } template void TConstant::value(const T& AValue) { FValue = AValue; } template T TConstant::value() const { return FValue; } /////////////////////////////////////////////////////////////////////// // TLibrary<> // /////////////////////////////////////////////////////////////////////// template TLibrary::TLibrary() { } template TLibrary::TLibrary(const TLibrary& ACopyOf) : FFunctions(ACopyOf.FFunctions), FConstants(ACopyOf.FConstants) { } template void TLibrary::removeIf(const std::string& AName, bool AReplaceIfExists) { for (typename TFunctionList::iterator i = FFunctions.begin(); i != FFunctions.end(); ++i) { if (i->name() == AName) { if (AReplaceIfExists) { FFunctions.erase(i); break; } else throw ELibraryLookup("Can't insert multiple elements with same name: " + AName + "."); } } for (typename TConstantList::iterator i = FConstants.begin(); i != FConstants.end(); ++i) { if (i->name() == AName) { if (AReplaceIfExists) { FConstants.erase(i); break; } else throw ELibraryLookup("Can't insert multiple elements with same name: " + AName + "."); } } } template void TLibrary::insert(const TFunction& AFunc, bool AReplaceIfExists) { removeIf(AFunc.name(), AReplaceIfExists); FFunctions.push_back(AFunc); } template void TLibrary::insert(const TConstant& AConst, bool AReplaceIfExists) { removeIf(AConst.name(), AReplaceIfExists); FConstants.push_back(AConst); } template void TLibrary::remove(const std::string& AName) { for (typename TFunctionList::iterator i = FFunctions.begin(); i != FFunctions.end(); ++i) if (i->name() == AName) { FFunctions.erase(i); return; } for (typename TConstantList::iterator i = FConstants.begin(); i != FConstants.end(); ++i) if (i->name() == AName) { FConstants.erase(i); return; } throw ELibraryLookup("No element found in library called: " + AName + "."); } template TFunction TLibrary::function(const std::string& AName) const { for (typename TFunctionList::const_iterator i = FFunctions.begin(); i != FFunctions.end(); ++i) if (i->name() == AName) return *i; throw ELibraryLookup("No function found in library called: " + AName + "."); } template TConstant TLibrary::constant(const std::string& AName) const { for (typename TConstantList::const_iterator i = FConstants.begin(); i != FConstants.end(); ++i) if (i->name() == AName) return *i; throw ELibraryLookup("No constant found in library called: " + AName + "."); } template bool TLibrary::hasFunction(const std::string& AName) const { for (typename TFunctionList::const_iterator i = FFunctions.begin(); i != FFunctions.end(); ++i) if (i->name() == AName) return true; return false; } template bool TLibrary::hasConstant(const std::string& AName) const { for (typename TConstantList::const_iterator i = FConstants.begin(); i != FConstants.end(); ++i) if (i->name() == AName) return true; return false; } template T TLibrary::call(const std::string& AName, const T& AParam) const { for (typename TFunctionList::const_iterator i = FFunctions.begin(); i != FFunctions.end(); ++i) if (i->name() == AName) return i->call(AParam, *this); throw ELibraryLookup("No function found in library called: " + AName + "."); } template T TLibrary::value(const std::string& AName) const { for (typename TConstantList::const_iterator i = FConstants.begin(); i != FConstants.end(); ++i) if (i->name() == AName) return i->value(); throw ELibraryLookup("No constant found in library called: " + AName + "."); } template unsigned TLibrary::functions() const { return FFunctions.size(); } template unsigned TLibrary::constants() const { return FConstants.size(); } } // namespace math template std::ostream& operator<<(std::ostream& AOut, const math::TFunction& AFunc) { AOut << AFunc.name() << "(x)=" << math::TPrinter::print(AFunc.expression()); return AOut; }