| 8695 | |
| 8696 | template<class T> |
| 8697 | xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, T v) |
| 8698 | { |
| 8699 | const axis_t axis = T::axis; |
| 8700 | bool attributes = |
| 8701 | (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || |
| 8702 | axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); |
| 8703 | |
| 8704 | xpath_node_set_raw ns; |
| 8705 | ns.set_type( |
| 8706 | (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || |
| 8707 | axis == axis_preceding_sibling) |
| 8708 | ? xpath_node_set::type_sorted_reverse |
| 8709 | : xpath_node_set::type_sorted); |
| 8710 | |
| 8711 | if (_left) |
| 8712 | { |
| 8713 | xpath_node_set_raw s = _left->eval_node_set(c, stack); |
| 8714 | |
| 8715 | // self axis preserves the original order |
| 8716 | if (axis == axis_self) |
| 8717 | ns.set_type(s.type()); |
| 8718 | |
| 8719 | for (const xpath_node* it = s.begin(); it != s.end(); ++it) |
| 8720 | { |
| 8721 | size_t size = ns.size(); |
| 8722 | |
| 8723 | // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes |
| 8724 | if (axis != axis_self && size != 0) |
| 8725 | ns.set_type(xpath_node_set::type_unsorted); |
| 8726 | |
| 8727 | if (it->node()) |
| 8728 | step_fill(ns, it->node(), stack.result, v); |
| 8729 | else if (attributes) |
| 8730 | step_fill(ns, it->attribute(), it->parent(), stack.result, v); |
| 8731 | |
| 8732 | apply_predicates(ns, size, stack); |
| 8733 | } |
| 8734 | } |
| 8735 | else |
| 8736 | { |
| 8737 | if (c.n.node()) |
| 8738 | step_fill(ns, c.n.node(), stack.result, v); |
| 8739 | else if (attributes) |
| 8740 | step_fill(ns, c.n.attribute(), c.n.parent(), stack.result, v); |
| 8741 | |
| 8742 | apply_predicates(ns, 0, stack); |
| 8743 | } |
| 8744 | |
| 8745 | // child, attribute and self axes always generate unique set of nodes |
| 8746 | // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice |
| 8747 | if (axis != axis_child && axis != axis_attribute && axis != axis_self && |
| 8748 | ns.type() == xpath_node_set::type_unsorted) |
| 8749 | ns.remove_duplicates(); |
| 8750 | |
| 8751 | return ns; |
| 8752 | } |
| 8753 | |
| 8754 | public: |
nothing calls this directly
no test coverage detected