parameterised StepList and StepExpression

This commit is contained in:
jez_higgins 2005-08-18 20:47:01 +00:00
parent f39cb8a140
commit 27ee8fe739
2 changed files with 38 additions and 34 deletions

View file

@ -40,8 +40,10 @@ public:
template<class string_type, class string_adaptor> class CompilationContext;
class StepExpression;
typedef std::vector<StepExpression*> StepList;
template<class string_type, class string_adaptor> class StepExpression;
template<class string_type, class string_adaptor>
class StepList : public std::vector<StepExpression<string_type, string_adaptor>*> { };
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class XPath
@ -169,7 +171,7 @@ private:
static XPathExpression<string_type, string_adaptor>* createUnaryExpression(node_iter_t const& i, CompilationContext<string_type, string_adaptor>& context);
static XPathExpression<string_type, string_adaptor>* createUnaryNegativeExpr(node_iter_t const& i, CompilationContext<string_type, string_adaptor>& context);
static StepList createStepList(node_iter_t const& from, node_iter_t const& to, CompilationContext<string_type, string_adaptor>& context);
static StepList<string_type, string_adaptor> createStepList(node_iter_t const& from, node_iter_t const& to, CompilationContext<string_type, string_adaptor>& context);
typedef XPathExpression<string_type, string_adaptor>* (*compileFn)(node_iter_t const& i, CompilationContext<string_type, string_adaptor>& context);
static std::map<int, compileFn>& factory()
@ -522,11 +524,11 @@ XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>
} // createUnaryNegativeExpr
template<class string_type, class string_adaptor>
StepList XPath<string_type, string_adaptor>::createStepList(node_iter_t const& from,
StepList<string_type, string_adaptor> XPath<string_type, string_adaptor>::createStepList(node_iter_t const& from,
node_iter_t const& to,
CompilationContext<string_type, string_adaptor>& context)
{
StepList steps;
StepList<string_type, string_adaptor> steps;
node_iter_t c = from;
node_iter_t end = to;

View file

@ -17,44 +17,45 @@ namespace Arabica
namespace XPath
{
class StepExpression : public XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >
template<class string_type, class string_adaptor>
class StepExpression : public XPathExpression<string_type, string_adaptor>
{
public:
StepExpression() { }
StepExpression(const std::vector<XPathExpression<std::string, Arabica::default_string_adaptor<std::string> > *>& predicates) : predicates_(predicates) { }
StepExpression(const std::vector<XPathExpression<string_type, string_adaptor> *>& predicates) : predicates_(predicates) { }
virtual ~StepExpression()
{
for(std::vector<XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >*>::iterator p = predicates_.begin(), e = predicates_.end(); p != e; ++p)
for(std::vector<XPathExpression<string_type, string_adaptor>*>::iterator p = predicates_.begin(), e = predicates_.end(); p != e; ++p)
delete *p;
} // ~StepExpression
virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const = 0;
virtual XPathValuePtr<std::string> evaluate(NodeSet<std::string>& context, const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const = 0;
virtual XPathValuePtr<string_type> evaluate(const DOM::Node<string_type>& context, const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0;
virtual XPathValuePtr<string_type> evaluate(NodeSet<string_type>& context, const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0;
bool has_predicates() const { return !predicates_.empty(); }
protected:
NodeSet<std::string> applyPredicates(NodeSet<std::string>& nodes, const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& parentContext) const
NodeSet<string_type> applyPredicates(NodeSet<string_type>& nodes, const ExecutionContext<string_type, string_adaptor>& parentContext) const
{
for(std::vector<XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >*>::const_iterator p = predicates_.begin(), e = predicates_.end();
for(std::vector<XPathExpression<string_type, string_adaptor>*>::const_iterator p = predicates_.begin(), e = predicates_.end();
(p != e) && (!nodes.empty()); ++p)
nodes = applyPredicate(nodes, *p, parentContext);
return nodes;
} // applyPredicates
private:
NodeSet<std::string> applyPredicate(NodeSet<std::string>& nodes,
XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >* predicate,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& parentContext) const
NodeSet<string_type> applyPredicate(NodeSet<string_type>& nodes,
XPathExpression<string_type, string_adaptor>* predicate,
const ExecutionContext<string_type, string_adaptor>& parentContext) const
{
ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> > executionContext(nodes.size(), parentContext);
NodeSet<std::string> results(nodes.forward());
ExecutionContext<string_type, string_adaptor> executionContext(nodes.size(), parentContext);
NodeSet<string_type> results(nodes.forward());
unsigned int position = 1;
for(NodeSet<std::string>::iterator i = nodes.begin(); i != nodes.end(); ++i, ++position)
for(NodeSet<string_type>::iterator i = nodes.begin(); i != nodes.end(); ++i, ++position)
{
executionContext.setPosition(position);
XPathValuePtr<std::string> v = predicate->evaluate(*i, executionContext);
XPathValuePtr<string_type> v = predicate->evaluate(*i, executionContext);
if((v->type() == NUMBER) && (position != v->asNumber()))
continue;
@ -66,14 +67,14 @@ private:
return results;
} // applyPredicate
std::vector<XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >*> predicates_;
std::vector<XPathExpression<string_type, string_adaptor>*> predicates_;
}; // StepExpression
class TestStepExpression : public StepExpression
class TestStepExpression : public StepExpression<std::string, Arabica::default_string_adaptor<std::string> >
{
public:
TestStepExpression(Axis axis, NodeTest<std::string>* test) :
StepExpression(),
StepExpression<std::string, Arabica::default_string_adaptor<std::string> >(),
axis_(axis),
test_(test)
{
@ -81,7 +82,7 @@ public:
TestStepExpression(Axis axis, NodeTest<std::string>* test,
const std::vector<XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >*>& predicates) :
StepExpression(predicates),
StepExpression<std::string, Arabica::default_string_adaptor<std::string> >(predicates),
axis_(axis),
test_(test)
{
@ -139,12 +140,12 @@ private:
NodeTest<std::string>* test_;
}; // class TestStepExpression
class ExprStepExpression : public StepExpression
class ExprStepExpression : public StepExpression<std::string, Arabica::default_string_adaptor<std::string> >
{
public:
ExprStepExpression(XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >* expr,
const std::vector<XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >*>& predicates) :
StepExpression(predicates),
StepExpression<std::string, Arabica::default_string_adaptor<std::string> >(predicates),
expr_(expr)
{
} // ExprStepExpression
@ -177,7 +178,8 @@ private:
class StepFactory
{
public:
static StepExpression* createStep(node_iter_t& node,
static StepExpression<std::string, Arabica::default_string_adaptor<std::string> >*
createStep(node_iter_t& node,
node_iter_t const& end,
CompilationContext<std::string, Arabica::default_string_adaptor<std::string> >& context)
{
@ -205,7 +207,7 @@ public:
return new TestStepExpression(axis, test, preds);
} // createStep
static StepExpression* createStep(node_iter_t& node, CompilationContext<std::string, Arabica::default_string_adaptor<std::string> >& context)
static StepExpression<std::string, Arabica::default_string_adaptor<std::string> >* createStep(node_iter_t& node, CompilationContext<std::string, Arabica::default_string_adaptor<std::string> >& context)
{
Axis axis = getAxis(node);
NodeTest<std::string>* test = getTest(node, context.namespaceContext());
@ -369,12 +371,12 @@ private:
class RelativeLocationPath : public XPathExpression<std::string, Arabica::default_string_adaptor<std::string> >
{
public:
RelativeLocationPath(StepExpression* step) : steps_() { steps_.push_back(step); }
RelativeLocationPath(const StepList& steps) : steps_(steps) { }
RelativeLocationPath(StepExpression<std::string, Arabica::default_string_adaptor<std::string> >* step) : steps_() { steps_.push_back(step); }
RelativeLocationPath(const StepList<std::string, Arabica::default_string_adaptor<std::string> >& steps) : steps_(steps) { }
virtual ~RelativeLocationPath()
{
for(StepList::const_iterator i = steps_.begin(); i != steps_.end(); ++i)
for(StepList<std::string, Arabica::default_string_adaptor<std::string> >::const_iterator i = steps_.begin(); i != steps_.end(); ++i)
delete *i;
} // ~LocationPath
@ -383,7 +385,7 @@ public:
NodeSet<std::string> nodes;
nodes.push_back(context);
for(StepList::const_iterator i = steps_.begin(); i != steps_.end(); ++i)
for(StepList<std::string, Arabica::default_string_adaptor<std::string> >::const_iterator i = steps_.begin(); i != steps_.end(); ++i)
{
XPathValuePtr<std::string> v = (*i)->evaluate(nodes, executionContext);
nodes = v->asNodeSet();
@ -393,14 +395,14 @@ public:
} // do_evaluate
private:
StepList steps_;
StepList<std::string, Arabica::default_string_adaptor<std::string> > steps_;
}; // LocationPath
class AbsoluteLocationPath : public RelativeLocationPath
{
public:
AbsoluteLocationPath(StepExpression* step) : RelativeLocationPath(step) { }
AbsoluteLocationPath(const StepList& steps) : RelativeLocationPath(steps) { }
AbsoluteLocationPath(StepExpression<std::string, Arabica::default_string_adaptor<std::string> >* step) : RelativeLocationPath(step) { }
AbsoluteLocationPath(const StepList<std::string, Arabica::default_string_adaptor<std::string> >& steps) : RelativeLocationPath(steps) { }
virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
{