#ifndef ARABICA_XPATHIC_XPATH_VALUE_H #define ARABICA_XPATHIC_XPATH_VALUE_H #include #include #include #include #include #include "xpath_object.hpp" #include "xpath_expression.hpp" namespace Arabica { namespace XPath { template > class BoolValue : public XPathValue, public XPathExpression { public: BoolValue(bool value) : value_(value) { } static XPathValuePtr createValue(bool value) { return XPathValuePtr(new BoolValue(value)); } virtual XPathValuePtr evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return XPathValuePtr(new BoolValue(value_)); } // evaluate virtual bool evaluateAsBool(const DOM::Node& context) { return asBool(); } virtual double evaluateAsNumber(const DOM::Node& context) { return asNumber(); } virtual string_type evaluateAsString(const DOM::Node& context) { return asString(); } virtual NodeSet evaluateAsNodeSet(const DOM::Node& context) { return asNodeSet(); } virtual bool asBool() const { return value_; } virtual double asNumber() const { return value_ ? 1 : 0; } virtual string_type asString() const { return string_adaptor::construct_from_utf8(value_ ? "true" : "false"); } virtual const NodeSet& asNodeSet() const { static NodeSet empty; return empty; } virtual ValueType type() const { return BOOL; } private: bool value_; }; // class BoolValue template > class NumericValue : public XPathValue, public XPathExpression { public: NumericValue(double value) : value_(value) { } static XPathValuePtr createValue(double value) { return XPathValuePtr(new NumericValue(value)); } virtual XPathValuePtr evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return createValue(value_); } // evaluate virtual bool evaluateAsBool(const DOM::Node& context) { return asBool(); } virtual double evaluateAsNumber(const DOM::Node& context) { return asNumber(); } virtual string_type evaluateAsString(const DOM::Node& context) { return asString(); } virtual NodeSet evaluateAsNodeSet(const DOM::Node& context) { return asNodeSet(); } virtual bool asBool() const { if(isNaN(value_)) return false; return (value_ != 0.0); } // asBool virtual double asNumber() const { return value_; } virtual string_type asString() const { if(isNaN(value_)) return string_adaptor::construct_from_utf8("NaN"); if(isInfinity(value_)) return string_adaptor::construct_from_utf8("Infinity"); if(isNegativeInfinity(value_)) return string_adaptor::construct_from_utf8("-Infinity"); return string_adaptor::construct_from_utf8(boost::lexical_cast(value_).c_str()); } // asString virtual const NodeSet& asNodeSet() const { static NodeSet empty; return empty; } virtual ValueType type() const { return NUMBER; } private: double value_; }; // class NumberValue template > class StringValue : public XPathValue, public XPathExpression { public: StringValue(const char* value) : value_(string_adaptor::construct_from_utf8(value)) { } StringValue(const string_type& value) : value_(value) { } static XPathValuePtr createValue(const string_type& value) { return XPathValuePtr(new StringValue(value)); } virtual XPathValuePtr evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return XPathValuePtr(new StringValue(value_)); } // evaluate virtual bool evaluateAsBool(const DOM::Node& context) { return asBool(); } virtual double evaluateAsNumber(const DOM::Node& context) { return asNumber(); } virtual string_type evaluateAsString(const DOM::Node& context) { return asString(); } virtual NodeSet evaluateAsNodeSet() const { return asNodeSet(); } virtual bool asBool() const { return !string_adaptor::empty(value_); } virtual double asNumber() const { return impl::stringAsNumber(value_); } // asNumber virtual string_type asString() const { return value_; } virtual const NodeSet& asNodeSet() const { static NodeSet empty; return empty; } virtual ValueType type() const { return STRING; } private: string_type value_; }; // class StringValue template > class NodeSetValue : public XPathValue, public XPathExpression { public: NodeSetValue(const NodeSet& set) : set_(set) { } static XPathValuePtr createValue(const NodeSet& set) { return XPathValuePtr(new NodeSetValue(set)); } // createValue virtual XPathValuePtr evaluate(const DOM::Node& context, const ExecutionContext& executionContext) const { return XPathValuePtr(this); } // evaluate virtual bool evaluateAsBool(const DOM::Node& context) const{ return asBool(); } virtual double evaluateAsNumber(const DOM::Node& context) const { return asNumber(); } virtual string_type evaluateAsString(const DOM::Node& context) const { return asString(); } virtual const NodeSet& evaluateAsNodeSet() const { return asNodeSet(); } virtual bool asBool() const { return !set_.empty(); } // asBool virtual double asNumber() const { return impl::stringAsNumber(asString()); } // asNumber virtual string_type asString() const { if(set_.empty()) return string_adaptor::construct_from_utf8(""); return impl::nodeStringValue(set_.top()); } // asStringx virtual const NodeSet& asNodeSet() const { return set_; } // asNodeSet virtual ValueType type() const { return NODE_SET; } private: mutable NodeSet set_; }; // NodeSetValue } // namespace XPath } // namespace Arabica #endif