arabica/include/XPath/impl/xpath_value.hpp

202 lines
7.5 KiB
C++
Raw Normal View History

2005-08-04 22:42:30 +02:00
#ifndef ARABICA_XPATHIC_XPATH_VALUE_H
#define ARABICA_XPATHIC_XPATH_VALUE_H
#include <string>
2007-09-05 00:55:47 +02:00
#include <DOM/Node.hpp>
2005-08-04 22:42:30 +02:00
#include <boost/lexical_cast.hpp>
#include <vector>
#include <Arabica/StringAdaptor.hpp>
2005-08-04 22:42:30 +02:00
#include "xpath_object.hpp"
namespace Arabica
{
namespace XPath
{
template<class string_type, class string_adaptor>
class Value_base :
public XPathExpression_impl<string_type, string_adaptor>,
public XPathValue_impl<string_type, string_adaptor>
{
typedef XPathValue_impl<string_type, string_adaptor> XPathValue_implT;
using XPathValue_implT::asBool;
using XPathValue_implT::asNumber;
using XPathValue_implT::asString;
using XPathValue_implT::asNodeSet;
protected:
Value_base() { }
~Value_base() { }
public:
2010-01-10 21:49:20 +01:00
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& /* context */) { return asBool(); }
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& /* context */) { return asNumber(); }
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& /* context */) { return asString(); }
virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet(const DOM::Node<string_type, string_adaptor>& /* context */) { return asNodeSet(); }
2010-01-10 21:49:20 +01:00
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& /* context */,
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
{
return asBool();
}
2010-01-10 21:49:20 +01:00
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& /* context */,
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
{
return asNumber();
}
2010-01-10 21:49:20 +01:00
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& /* context */,
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
{
return asString();
}
2010-01-10 21:49:20 +01:00
virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet(const DOM::Node<string_type, string_adaptor>& /* context */,
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
{
return asNodeSet();
}
}; // class Value_base
2007-07-19 19:01:31 +02:00
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class BoolValue : public Value_base<string_type, string_adaptor>
2005-08-04 22:42:30 +02:00
{
public:
BoolValue(bool value) :
value_(value) { }
static XPathValue<string_type, string_adaptor> createValue(bool value) { return XPathValue<string_type, string_adaptor>(new BoolValue(value)); }
2005-08-04 22:42:30 +02:00
2010-01-10 21:49:20 +01:00
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& /* context */,
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
2005-08-04 22:42:30 +02:00
{
return XPathValue<string_type, string_adaptor>(new BoolValue(value_));
2005-08-04 22:42:30 +02:00
} // evaluate
virtual bool asBool() const { return value_; }
virtual double asNumber() const { return value_ ? 1 : 0; }
2005-09-30 23:36:11 +02:00
virtual string_type asString() const { return string_adaptor::construct_from_utf8(value_ ? "true" : "false"); }
virtual const NodeSet<string_type, string_adaptor>& asNodeSet() const { static NodeSet<string_type, string_adaptor> empty; return empty; }
2005-08-04 22:42:30 +02:00
virtual ValueType type() const { return BOOL; }
private:
bool value_;
}; // class BoolValue
2007-07-19 19:01:31 +02:00
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class NumericValue : public Value_base<string_type, string_adaptor>
2005-08-04 22:42:30 +02:00
{
public:
NumericValue(double value) :
value_(value) { }
static XPathValue<string_type, string_adaptor> createValue(double value) { return XPathValue<string_type, string_adaptor>(new NumericValue(value)); }
2005-08-04 22:42:30 +02:00
2010-01-10 21:49:20 +01:00
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& /* context */,
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
2005-08-04 22:42:30 +02:00
{
return createValue(value_);
} // evaluate
2007-07-19 19:01:31 +02:00
virtual bool asBool() const
{
if(isNaN(value_))
return false;
return (value_ != 0.0);
} // asBool
2005-08-04 22:42:30 +02:00
virtual double asNumber() const { return value_; }
2005-08-17 09:01:27 +02:00
virtual string_type asString() const
2005-08-04 22:42:30 +02:00
{
if(isNaN(value_))
2005-09-30 23:36:11 +02:00
return string_adaptor::construct_from_utf8("NaN");
2005-08-04 22:42:30 +02:00
if(isInfinity(value_))
2005-09-30 23:36:11 +02:00
return string_adaptor::construct_from_utf8("Infinity");
2005-08-04 22:42:30 +02:00
if(isNegativeInfinity(value_))
2005-09-30 23:36:11 +02:00
return string_adaptor::construct_from_utf8("-Infinity");
return string_adaptor::construct_from_utf8(boost::lexical_cast<std::string>(value_).c_str());
2005-08-04 22:42:30 +02:00
} // asString
virtual const NodeSet<string_type, string_adaptor>& asNodeSet() const { static NodeSet<string_type, string_adaptor> empty; return empty; }
2005-08-04 22:42:30 +02:00
virtual ValueType type() const { return NUMBER; }
private:
double value_;
}; // class NumberValue
2007-07-19 19:01:31 +02:00
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class StringValue : public Value_base<string_type, string_adaptor>
2005-08-04 22:42:30 +02:00
{
public:
StringValue(const char* value) :
2005-09-30 23:36:11 +02:00
value_(string_adaptor::construct_from_utf8(value)) { }
StringValue(const string_type& value) :
2005-08-04 22:42:30 +02:00
value_(value) { }
static XPathValue<string_type, string_adaptor> createValue(const string_type& value) { return XPathValue<string_type, string_adaptor>(new StringValue(value)); }
2007-07-19 19:01:31 +02:00
2010-01-10 21:49:20 +01:00
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& /* context */,
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
2005-08-04 22:42:30 +02:00
{
return XPathValue<string_type, string_adaptor>(new StringValue(value_));
2005-08-04 22:42:30 +02:00
} // evaluate
virtual bool asBool() const { return !string_adaptor::empty(value_); }
2005-08-04 22:42:30 +02:00
virtual double asNumber() const
{
2007-07-19 19:01:31 +02:00
return impl::stringAsNumber<string_type, string_adaptor>(value_);
2005-08-04 22:42:30 +02:00
} // asNumber
virtual string_type asString() const { return value_; }
virtual const NodeSet<string_type, string_adaptor>& asNodeSet() const { static NodeSet<string_type, string_adaptor> empty; return empty; }
2005-08-04 22:42:30 +02:00
virtual ValueType type() const { return STRING; }
private:
string_type value_;
2005-08-04 22:42:30 +02:00
}; // class StringValue
2007-07-19 19:01:31 +02:00
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class NodeSetValue : public Value_base<string_type, string_adaptor>
2005-08-04 22:42:30 +02:00
{
public:
NodeSetValue(const NodeSet<string_type, string_adaptor>& set) : set_(set) { }
2005-08-04 22:42:30 +02:00
static XPathValue<string_type, string_adaptor> createValue(const NodeSet<string_type, string_adaptor>& set)
2007-07-19 19:01:31 +02:00
{
return XPathValue<string_type, string_adaptor>(new NodeSetValue(set));
2007-07-19 19:01:31 +02:00
} // createValue
2010-01-10 21:49:20 +01:00
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& /* context */,
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
2005-08-04 22:42:30 +02:00
{
return XPathValue<string_type, string_adaptor>(this);
2005-08-04 22:42:30 +02:00
} // evaluate
virtual bool asBool() const
{
return !set_.empty();
} // asBool
virtual double asNumber() const
{
2007-07-19 19:01:31 +02:00
return impl::stringAsNumber<string_type, string_adaptor>(asString());
2005-08-04 22:42:30 +02:00
} // asNumber
2005-08-17 10:31:47 +02:00
virtual string_type asString() const
2005-08-04 22:42:30 +02:00
{
2007-07-19 19:01:31 +02:00
if(set_.empty())
return string_adaptor::construct_from_utf8("");
return impl::nodeStringValue<string_type, string_adaptor>(set_.top());
2005-08-04 22:42:30 +02:00
} // asStringx
virtual const NodeSet<string_type, string_adaptor>& asNodeSet() const
2007-07-19 19:01:31 +02:00
{
return set_;
} // asNodeSet
2005-08-04 22:42:30 +02:00
virtual ValueType type() const { return NODE_SET; }
private:
mutable NodeSet<string_type, string_adaptor> set_;
2005-08-04 22:42:30 +02:00
}; // NodeSetValue
} // namespace XPath
} // namespace Arabica
#endif