Committing on-the-go work

:
This commit is contained in:
jez 2009-05-12 09:19:37 +01:00
commit ce1e4afbba
7 changed files with 219 additions and 151 deletions

View file

@ -34,3 +34,4 @@ vs9/mangle.sln
*.stackdump *.stackdump
*.lnk *.lnk
spec spec
gmon.out

View file

@ -1,6 +1,7 @@
#ifndef ARABICA_XPATHIC_XPATH_ARITHMETIC_HPP #ifndef ARABICA_XPATHIC_XPATH_ARITHMETIC_HPP
#define ARABICA_XPATHIC_XPATH_ARITHMETIC_HPP #define ARABICA_XPATHIC_XPATH_ARITHMETIC_HPP
#include <functional>
#include "xpath_value.hpp" #include "xpath_value.hpp"
namespace Arabica namespace Arabica
@ -10,12 +11,12 @@ namespace XPath
namespace impl namespace impl
{ {
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor, class Op>
class PlusOperator : public BinaryExpression<string_type, string_adaptor> class ArithmeticOperator : public BinaryExpression<string_type, string_adaptor>
{ {
typedef BinaryExpression<string_type, string_adaptor> baseT; typedef BinaryExpression<string_type, string_adaptor> baseT;
public: public:
PlusOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) : ArithmeticOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) :
BinaryExpression<string_type, string_adaptor>(lhs, rhs) { } BinaryExpression<string_type, string_adaptor>(lhs, rhs) { }
virtual ValueType type() const { return NUMBER; } virtual ValueType type() const { return NUMBER; }
@ -23,81 +24,67 @@ public:
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context, virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const const ExecutionContext<string_type, string_adaptor>& executionContext) const
{ {
return NumericValue<string_type, string_adaptor>::createValue(baseT::lhs()->evaluateAsNumber(context, executionContext) + baseT::rhs()->evaluateAsNumber(context, executionContext)); return NumericValue<string_type, string_adaptor>::createValue(evaluateAsNumber(context, executionContext));
} // evaluate } // evaluate
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return Op()(baseT::lhs()->evaluateAsNumber(context, executionContext),
baseT::rhs()->evaluateAsNumber(context, executionContext));
} // evaluateAsNumber
}; // class ArithmeticOperator
template<class string_type, class string_adaptor>
class PlusOperator : public ArithmeticOperator<string_type, string_adaptor, std::plus<double> >
{
public:
PlusOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) :
ArithmeticOperator<string_type, string_adaptor, std::plus<double> >(lhs, rhs) { }
}; // class PlusOperator }; // class PlusOperator
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
class MinusOperator : public BinaryExpression<string_type, string_adaptor> class MinusOperator : public ArithmeticOperator<string_type, string_adaptor, std::minus<double> >
{ {
typedef BinaryExpression<string_type, string_adaptor> baseT;
public: public:
MinusOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) : MinusOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) :
BinaryExpression<string_type, string_adaptor>(lhs, rhs) { } ArithmeticOperator<string_type, string_adaptor, std::minus<double> >(lhs, rhs) { }
virtual ValueType type() const { return NUMBER; }
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return NumericValue<string_type, string_adaptor>::createValue(baseT::lhs()->evaluateAsNumber(context, executionContext) - baseT::rhs()->evaluateAsNumber(context, executionContext));
} // evaluate
}; // class MinusOperator }; // class MinusOperator
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
class MultiplyOperator : public BinaryExpression<string_type, string_adaptor> class MultiplyOperator : public ArithmeticOperator<string_type, string_adaptor, std::multiplies<double> >
{ {
typedef BinaryExpression<string_type, string_adaptor> baseT;
public: public:
MultiplyOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) : MultiplyOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) :
BinaryExpression<string_type, string_adaptor>(lhs, rhs) { } ArithmeticOperator<string_type, string_adaptor, std::multiplies<double> >(lhs, rhs) { }
virtual ValueType type() const { return NUMBER; }
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return NumericValue<string_type, string_adaptor>::createValue(baseT::lhs()->evaluateAsNumber(context, executionContext) * baseT::rhs()->evaluateAsNumber(context, executionContext));
} // evaluate
}; // class MultiplyOperator }; // class MultiplyOperator
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
class DivideOperator : public BinaryExpression<string_type, string_adaptor> class DivideOperator : public ArithmeticOperator<string_type, string_adaptor, std::divides<double> >
{ {
typedef BinaryExpression<string_type, string_adaptor> baseT;
public: public:
DivideOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) : DivideOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) :
BinaryExpression<string_type, string_adaptor>(lhs, rhs) { } ArithmeticOperator<string_type, string_adaptor, std::divides<double> >(lhs, rhs) { }
virtual ValueType type() const { return NUMBER; }
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return NumericValue<string_type, string_adaptor>::createValue(baseT::lhs()->evaluateAsNumber(context, executionContext) / baseT::rhs()->evaluateAsNumber(context, executionContext));
} // evaluate
}; // class DivideOperator }; // class DivideOperator
struct NaN_aware_modulus
{
double operator()(const double& lhs, const double& rhs) const
{ // apply operator% to operands
if(isNaN(lhs) || isNaN(rhs))
return NaN;
return (static_cast<long>(lhs) % static_cast<long>(rhs));
}
}; // NaN_aware_modulus
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
class ModOperator : public BinaryExpression<string_type, string_adaptor> class ModOperator : public ArithmeticOperator<string_type, string_adaptor, NaN_aware_modulus>
{ {
typedef BinaryExpression<string_type, string_adaptor> baseT; typedef BinaryExpression<string_type, string_adaptor> baseT;
public: public:
ModOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) : ModOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) :
BinaryExpression<string_type, string_adaptor>(lhs, rhs) { } ArithmeticOperator<string_type, string_adaptor, NaN_aware_modulus>(lhs, rhs) { }
virtual ValueType type() const { return NUMBER; }
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
double l = baseT::lhs()->evaluateAsNumber(context, executionContext);
double r = baseT::rhs()->evaluateAsNumber(context, executionContext);
if(isNaN(l) || isNaN(r))
return NumericValue<string_type, string_adaptor>::createValue(NaN);
return NumericValue<string_type, string_adaptor>::createValue(static_cast<long>(l) % static_cast<long>(r));
} // evaluate
}; // class ModOperator }; // class ModOperator
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
@ -113,8 +100,13 @@ public:
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context, virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const const ExecutionContext<string_type, string_adaptor>& executionContext) const
{ {
return NumericValue<string_type, string_adaptor>::createValue(-baseT::expr()->evaluate(context, executionContext).asNumber()); return NumericValue<string_type, string_adaptor>::createValue(evaluateAsNumber(context, executionContext));
} // evaluate } // evaluate
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return -baseT::expr()->evaluateAsNumber(context, executionContext);
} // evaluateAsNumber
}; // class UnaryNegative }; // class UnaryNegative
} // namespace impl } // namespace impl

View file

@ -48,30 +48,58 @@ public:
XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context) const XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context) const
{ {
ExecutionContext<string_type, string_adaptor> executionContext; return evaluate(context, StaticExecutionContext());
return evaluate(context, executionContext);
} // evaluate } // evaluate
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context) const
{
return evaluateAsBool(context, StaticExecutionContext());
}
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context) const
{
return evaluateAsNumber(context, StaticExecutionContext());
}
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context) const
{
return evaluateAsString(context, StaticExecutionContext());
}
virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet(const DOM::Node<string_type, string_adaptor>& context) const
{
return evaluateAsNodeSet(context, StaticExecutionContext());
}
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context) const { return evaluate(context).asBool(); } virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context) const { return evaluate(context).asNumber(); }
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context) const { return evaluate(context).asString(); }
virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet(const DOM::Node<string_type, string_adaptor>& context) const { return evaluate(context).asNodeSet(); }
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0; const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0;
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context, virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const { return evaluate(context, executionContext).asBool(); } const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return evaluate(context, executionContext).asBool();
}
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context, virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const { return evaluate(context, executionContext).asNumber(); } const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return evaluate(context, executionContext).asNumber();
}
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context, virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const { return evaluate(context, executionContext).asString(); } const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return evaluate(context, executionContext).asString();
}
virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet(const DOM::Node<string_type, string_adaptor>& context, virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const { return evaluate(context, executionContext).asNodeSet(); } const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return evaluate(context, executionContext).asNodeSet();
}
virtual void scan(impl::Expression_scanner<string_type, string_adaptor>& scanner) const { scanner.scan(this); } virtual void scan(impl::Expression_scanner<string_type, string_adaptor>& scanner) const { scanner.scan(this); }
private: private:
static const ExecutionContext<string_type, string_adaptor>& StaticExecutionContext()
{
static ExecutionContext<string_type, string_adaptor> executionContext;
return executionContext;
} // StaticExecutionContext
XPathExpression_impl(const XPathExpression_impl&); XPathExpression_impl(const XPathExpression_impl&);
bool operator==(const XPathExpression_impl&); bool operator==(const XPathExpression_impl&);
XPathExpression_impl& operator=(const XPathExpression_impl&); XPathExpression_impl& operator=(const XPathExpression_impl&);

View file

@ -1,66 +1,81 @@
#ifndef ARABICA_XPATHIC_XPATH_LOGICAL_HPP #ifndef ARABICA_XPATHIC_XPATH_LOGICAL_HPP
#define ARABICA_XPATHIC_XPATH_LOGICAL_HPP #define ARABICA_XPATHIC_XPATH_LOGICAL_HPP
#include "xpath_value.hpp" #include "xpath_value.hpp"
namespace Arabica namespace Arabica
{ {
namespace XPath namespace XPath
{ {
namespace impl namespace impl
{ {
template<class string_type, class string_adaptor>
class OrOperator : public BinaryExpression<string_type, string_adaptor> template<class string_type, class string_adaptor>
{ class LogicalOperator : public BinaryExpression<string_type, string_adaptor>
typedef BinaryExpression<string_type, string_adaptor> baseT; {
public: public:
OrOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, LogicalOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, XPathExpression_impl<string_type, string_adaptor>* rhs) :
XPathExpression_impl<string_type, string_adaptor>* rhs) : BinaryExpression<string_type, string_adaptor>(lhs, rhs) { }
BinaryExpression<string_type, string_adaptor>(lhs, rhs) { }
virtual ValueType type() const { return BOOL; }
virtual ValueType type() const { return BOOL; }
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context, const ExecutionContext<string_type, string_adaptor>& executionContext) const
const ExecutionContext<string_type, string_adaptor>& executionContext) const {
{ return BoolValue<string_type, string_adaptor>::createValue(evaluateAsBool(context, executionContext));
// From XPath 1.0 Rec, section 3.4 } // evaluate
// An or expression is evaluated by evaluating each operand and converting its value }; // class LogicalOperator
// to a boolean as if by a call to the boolean function. The result is true if either
// value is true and false otherwise. The right operand is not evaluated if the template<class string_type, class string_adaptor>
// left operand evaluates to true. class OrOperator : public LogicalOperator<string_type, string_adaptor>
if(baseT::lhs()->evaluate(context, executionContext).asBool()) {
return BoolValue<string_type, string_adaptor>::createValue(true); typedef LogicalOperator<string_type, string_adaptor> LogicalOperatorT;
return BoolValue<string_type, string_adaptor>::createValue(baseT::rhs()->evaluate(context, executionContext).asBool()); using LogicalOperatorT::lhs;
} // evaluate using LogicalOperatorT::rhs;
}; // class OrOperator public:
OrOperator(XPathExpression_impl<string_type, string_adaptor>* lhs,
template<class string_type, class string_adaptor> XPathExpression_impl<string_type, string_adaptor>* rhs) :
class AndOperator : public BinaryExpression<string_type, string_adaptor> LogicalOperator<string_type, string_adaptor>(lhs, rhs) { }
{
typedef BinaryExpression<string_type, string_adaptor> baseT; virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context,
public: const ExecutionContext<string_type, string_adaptor>& executionContext) const
AndOperator(XPathExpression_impl<string_type, string_adaptor>* lhs, {
XPathExpression_impl<string_type, string_adaptor>* rhs) : // From XPath 1.0 Rec, section 3.4
BinaryExpression<string_type, string_adaptor>(lhs, rhs) { } // An or expression is evaluated by evaluating each operand and converting its value
// to a boolean as if by a call to the boolean function. The result is true if either
virtual ValueType type() const { return BOOL; } // value is true and false otherwise. The right operand is not evaluated if the
// left operand evaluates to true.
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context, return lhs()->evaluate(context, executionContext).asBool() ||
const ExecutionContext<string_type, string_adaptor>& executionContext) const rhs()->evaluate(context, executionContext).asBool();
{ } // evaluateAsBool
// From XPath 1.0 Rec, section 3.4 }; // class OrOperator
// An and expression is evaluated by evaluating each operand and converting its value
// to a boolean as if by a call to the boolean function. The result is true if both template<class string_type, class string_adaptor>
// values are true and false otherwise. The right operand is not evaluated if the left class AndOperator : public LogicalOperator<string_type, string_adaptor>
// operand evaluates to false. {
if(!baseT::lhs()->evaluate(context, executionContext).asBool()) typedef LogicalOperator<string_type, string_adaptor> LogicalOperatorT;
return BoolValue<string_type, string_adaptor>::createValue(false); using LogicalOperatorT::lhs;
return BoolValue<string_type, string_adaptor>::createValue(baseT::rhs()->evaluate(context, executionContext).asBool()); using LogicalOperatorT::rhs;
} // evaluate public:
}; // class AndOperator AndOperator(XPathExpression_impl<string_type, string_adaptor>* lhs,
XPathExpression_impl<string_type, string_adaptor>* rhs) :
} // namespace impl LogicalOperator<string_type, string_adaptor>(lhs, rhs) { }
} // namespace XPath
} // namespace Arabica virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context,
#endif const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
// From XPath 1.0 Rec, section 3.4
// An and expression is evaluated by evaluating each operand and converting its value
// to a boolean as if by a call to the boolean function. The result is true if both
// values are true and false otherwise. The right operand is not evaluated if the left
// operand evaluates to false.
return lhs()->evaluate(context, executionContext).asBool() &&
rhs()->evaluate(context, executionContext).asBool();
} // evaluateAsBool
}; // class AndOperator
} // namespace impl
} // namespace XPath
} // namespace Arabica
#endif

View file

@ -14,8 +14,49 @@ namespace Arabica
namespace XPath namespace XPath
{ {
template<class string_type, class string_adaptor>
class Value_base : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression_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:
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(); }
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return asBool();
}
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return asNumber();
}
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
{
return asString();
}
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
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> > template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class BoolValue : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression_impl<string_type, string_adaptor> class BoolValue : public Value_base<string_type, string_adaptor>
{ {
public: public:
BoolValue(bool value) : BoolValue(bool value) :
@ -28,10 +69,6 @@ public:
{ {
return XPathValue<string_type, string_adaptor>(new BoolValue(value_)); return XPathValue<string_type, string_adaptor>(new BoolValue(value_));
} // evaluate } // evaluate
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(); }
virtual bool asBool() const { return value_; } virtual bool asBool() const { return value_; }
virtual double asNumber() const { return value_ ? 1 : 0; } virtual double asNumber() const { return value_ ? 1 : 0; }
@ -45,7 +82,7 @@ private:
}; // class BoolValue }; // class BoolValue
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> > template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class NumericValue : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression_impl<string_type, string_adaptor> class NumericValue : public Value_base<string_type, string_adaptor>
{ {
public: public:
NumericValue(double value) : NumericValue(double value) :
@ -58,10 +95,6 @@ public:
{ {
return createValue(value_); return createValue(value_);
} // evaluate } // evaluate
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(); }
virtual bool asBool() const virtual bool asBool() const
{ {
@ -89,7 +122,7 @@ private:
}; // class NumberValue }; // class NumberValue
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> > template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class StringValue : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression_impl<string_type, string_adaptor> class StringValue : public Value_base<string_type, string_adaptor>
{ {
public: public:
StringValue(const char* value) : StringValue(const char* value) :
@ -104,10 +137,6 @@ public:
{ {
return XPathValue<string_type, string_adaptor>(new StringValue(value_)); return XPathValue<string_type, string_adaptor>(new StringValue(value_));
} // evaluate } // evaluate
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 { return asNodeSet(); }
virtual bool asBool() const { return !string_adaptor::empty(value_); } virtual bool asBool() const { return !string_adaptor::empty(value_); }
virtual double asNumber() const virtual double asNumber() const
@ -124,7 +153,7 @@ private:
}; // class StringValue }; // class StringValue
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> > template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class NodeSetValue : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression_impl<string_type, string_adaptor> class NodeSetValue : public Value_base<string_type, string_adaptor>
{ {
public: public:
NodeSetValue(const NodeSet<string_type, string_adaptor>& set) : set_(set) { } NodeSetValue(const NodeSet<string_type, string_adaptor>& set) : set_(set) { }
@ -139,10 +168,6 @@ public:
{ {
return XPathValue<string_type, string_adaptor>(this); return XPathValue<string_type, string_adaptor>(this);
} // evaluate } // evaluate
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context) const{ return asBool(); }
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context) const { return asNumber(); }
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context) const { return asString(); }
virtual const NodeSet<string_type, string_adaptor>& evaluateAsNodeSet() const { return asNodeSet(); }
virtual bool asBool() const virtual bool asBool() const
{ {

View file

View file

@ -19,3 +19,10 @@ output combining (partially done for cdata-section-elements)
Performance Performance
variable pool
string pool?
use underlying_impl in XPath axis walker
use underlying_impl in XPath functions
short circuit evaluation in functions
only convert to full NodeSet at boundary
use a proxy to return propagate values out of functions