arabica/include/XPath/impl/xpath_union.hpp

61 lines
2 KiB
C++
Raw Normal View History

2005-08-04 22:42:30 +02:00
#ifndef ARABICA_XPATHIC_XPATH_UNION_HPP
#define ARABICA_XPATHIC_XPATH_UNION_HPP
#include "xpath_value.hpp"
#include <algorithm>
namespace Arabica
{
namespace XPath
{
namespace impl
{
2005-08-04 22:42:30 +02:00
template<class string_type, class string_adaptor>
class UnionExpression : public BinaryExpression<string_type, string_adaptor>
2005-08-04 22:42:30 +02:00
{
typedef BinaryExpression<string_type, string_adaptor> baseT;
2005-08-04 22:42:30 +02:00
public:
UnionExpression(XPathExpression_impl<string_type, string_adaptor>* lhs,
XPathExpression_impl<string_type, string_adaptor>* rhs) :
BinaryExpression<string_type, string_adaptor>(lhs, rhs) { }
2005-08-04 22:42:30 +02:00
virtual ValueType type() const { return NODE_SET; }
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
{
XPathValue<string_type, string_adaptor> p1 = baseT::lhs()->evaluate(context, executionContext);
if(p1.type() != NODE_SET)
2005-08-04 22:42:30 +02:00
throw RuntimeException("Union operator joins node-sets. First argument is not a node-set.");
XPathValue<string_type, string_adaptor> p2 = baseT::rhs()->evaluate(context, executionContext);
if(p2.type() != NODE_SET)
throw RuntimeException("Union operator joins node-sets. Second argument is not a node-set.");
2005-08-04 22:42:30 +02:00
NodeSet<string_type, string_adaptor> ns1(p1.asNodeSet());
NodeSet<string_type, string_adaptor> ns2(p2.asNodeSet());
2005-08-04 22:42:30 +02:00
// do the obvious optimizations
if(ns1.empty())
return wrap(ns2);
if(ns2.empty())
return wrap(ns1);
2007-07-19 19:01:31 +02:00
ns1.insert(ns1.end()-1, ns2.begin(), ns2.end());
2005-08-04 22:42:30 +02:00
ns1.to_document_order();
2007-07-19 19:01:31 +02:00
return wrap(ns1);
2005-08-04 22:42:30 +02:00
} // evaluate
private:
XPathValue<string_type, string_adaptor> wrap(const NodeSet<string_type, string_adaptor>& ns) const
2005-08-04 22:42:30 +02:00
{
return XPathValue<string_type, string_adaptor>(new NodeSetValue<string_type, string_adaptor>(ns));
2005-08-04 22:42:30 +02:00
} // wrap
}; // UnionExpression
} // namespace impl
2005-08-04 22:42:30 +02:00
} // namespace XPath
} // namespace Arabica
#endif