| 7310 | } |
| 7311 | |
| 7312 | template <class T> xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, T v) |
| 7313 | { |
| 7314 | const axis_t axis = T::axis; |
| 7315 | bool attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); |
| 7316 | |
| 7317 | xpath_node_set_raw ns; |
| 7318 | ns.set_type((axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling) ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted); |
| 7319 | |
| 7320 | if (_left) |
| 7321 | { |
| 7322 | xpath_node_set_raw s = _left->eval_node_set(c, stack); |
| 7323 | |
| 7324 | // self axis preserves the original order |
| 7325 | if (axis == axis_self) ns.set_type(s.type()); |
| 7326 | |
| 7327 | for (const xpath_node* it = s.begin(); it != s.end(); ++it) |
| 7328 | { |
| 7329 | size_t size = ns.size(); |
| 7330 | |
| 7331 | // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes |
| 7332 | if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); |
| 7333 | |
| 7334 | if (it->node()) |
| 7335 | step_fill(ns, it->node(), stack.result, v); |
| 7336 | else if (attributes) |
| 7337 | step_fill(ns, it->attribute(), it->parent(), stack.result, v); |
| 7338 | |
| 7339 | apply_predicates(ns, size, stack); |
| 7340 | } |
| 7341 | } |
| 7342 | else |
| 7343 | { |
| 7344 | if (c.n.node()) |
| 7345 | step_fill(ns, c.n.node(), stack.result, v); |
| 7346 | else if (attributes) |
| 7347 | step_fill(ns, c.n.attribute(), c.n.parent(), stack.result, v); |
| 7348 | |
| 7349 | apply_predicates(ns, 0, stack); |
| 7350 | } |
| 7351 | |
| 7352 | // child, attribute and self axes always generate unique set of nodes |
| 7353 | // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice |
| 7354 | if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted) |
| 7355 | ns.remove_duplicates(); |
| 7356 | |
| 7357 | return ns; |
| 7358 | } |
| 7359 | |
| 7360 | public: |
| 7361 | xpath_ast_node(ast_type_t type, xpath_value_type rettype, const char_t* value): |
nothing calls this directly
no test coverage detected