| 10427 | } |
| 10428 | |
| 10429 | template <class T> xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval, T v) |
| 10430 | { |
| 10431 | const axis_t axis = T::axis; |
| 10432 | const bool axis_reverse = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling); |
| 10433 | const xpath_node_set::type_t axis_type = axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; |
| 10434 | |
| 10435 | bool once = |
| 10436 | (axis == axis_attribute && _test == nodetest_name) || |
| 10437 | (!_right && eval_once(axis_type, eval)) || |
| 10438 | // coverity[mixed_enums] |
| 10439 | (_right && !_right->_next && _right->_test == predicate_constant_one); |
| 10440 | |
| 10441 | xpath_node_set_raw ns; |
| 10442 | ns.set_type(axis_type); |
| 10443 | |
| 10444 | if (_left) |
| 10445 | { |
| 10446 | xpath_node_set_raw s = _left->eval_node_set(c, stack, nodeset_eval_all); |
| 10447 | |
| 10448 | // self axis preserves the original order |
| 10449 | if (axis == axis_self) ns.set_type(s.type()); |
| 10450 | |
| 10451 | for (const xpath_node* it = s.begin(); it != s.end(); ++it) |
| 10452 | { |
| 10453 | size_t size = ns.size(); |
| 10454 | |
| 10455 | // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes |
| 10456 | if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); |
| 10457 | |
| 10458 | step_fill(ns, *it, stack.result, once, v); |
| 10459 | if (_right) apply_predicates(ns, size, stack, eval); |
| 10460 | } |
| 10461 | } |
| 10462 | else |
| 10463 | { |
| 10464 | step_fill(ns, c.n, stack.result, once, v); |
| 10465 | if (_right) apply_predicates(ns, 0, stack, eval); |
| 10466 | } |
| 10467 | |
| 10468 | // child, attribute and self axes always generate unique set of nodes |
| 10469 | // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice |
| 10470 | if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted) |
| 10471 | ns.remove_duplicates(stack.temp); |
| 10472 | |
| 10473 | return ns; |
| 10474 | } |
| 10475 | |
| 10476 | public: |
| 10477 | xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t* value): |
nothing calls this directly
no test coverage detected