#ifndef ARABICA_XPATHIC_XPATH_ARITHMETIC_HPP #define ARABICA_XPATHIC_XPATH_ARITHMETIC_HPP #include "xpath_value.hpp" namespace Arabica { namespace XPath { namespace impl { template class PlusOperator : private BinaryExpression, public XPathExpression { typedef BinaryExpression baseT; public: PlusOperator(XPathExpression* lhs, XPathExpression* rhs) : BinaryExpression(lhs, rhs) { } virtual XPathValue evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return NumericValue::createValue(baseT::lhs()->evaluateAsNumber(context, executionContext) + baseT::rhs()->evaluateAsNumber(context, executionContext)); } // evaluate }; // class PlusOperator template class MinusOperator : private BinaryExpression, public XPathExpression { typedef BinaryExpression baseT; public: MinusOperator(XPathExpression* lhs, XPathExpression* rhs) : BinaryExpression(lhs, rhs) { } virtual XPathValue evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return NumericValue::createValue(baseT::lhs()->evaluateAsNumber(context, executionContext) - baseT::rhs()->evaluateAsNumber(context, executionContext)); } // evaluate }; // class MinusOperator template class MultiplyOperator : private BinaryExpression, public XPathExpression { typedef BinaryExpression baseT; public: MultiplyOperator(XPathExpression* lhs, XPathExpression* rhs) : BinaryExpression(lhs, rhs) { } virtual XPathValue evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return NumericValue::createValue(baseT::lhs()->evaluateAsNumber(context, executionContext) * baseT::rhs()->evaluateAsNumber(context, executionContext)); } // evaluate }; // class MultiplyOperator template class DivideOperator : private BinaryExpression, public XPathExpression { typedef BinaryExpression baseT; public: DivideOperator(XPathExpression* lhs, XPathExpression* rhs) : BinaryExpression(lhs, rhs) { } virtual XPathValue evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return NumericValue::createValue(baseT::lhs()->evaluateAsNumber(context, executionContext) / baseT::rhs()->evaluateAsNumber(context, executionContext)); } // evaluate }; // class DivideOperator template class ModOperator : private BinaryExpression, public XPathExpression { typedef BinaryExpression baseT; public: ModOperator(XPathExpression* lhs, XPathExpression* rhs) : BinaryExpression(lhs, rhs) { } virtual XPathValue evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { double l = baseT::lhs()->evaluateAsNumber(context, executionContext); double r = baseT::rhs()->evaluateAsNumber(context, executionContext); if(isNaN(l) || isNaN(r)) return NumericValue::createValue(NaN); return NumericValue::createValue(static_cast(l) % static_cast(r)); } // evaluate }; // class ModOperator template class UnaryNegative : private UnaryExpression, public XPathExpression { typedef UnaryExpression baseT; public: UnaryNegative(XPathExpression* expr) : UnaryExpression(expr) { } virtual XPathValue evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return NumericValue::createValue(-baseT::expr()->evaluate(context, executionContext).asNumber()); } // evaluate }; // class UnaryNegative } // namespace impl } // namespace XPath } // namespace Arabica #endif