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