| 7932 | } |
| 7933 | |
| 7934 | template <class T> xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, T v) |
| 7935 | { |
| 7936 | const axis_t axis = T::axis; |
| 7937 | 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); |
| 7938 | |
| 7939 | xpath_node_set_raw ns; |
| 7940 | 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); |
| 7941 | |
| 7942 | if (_left) |
| 7943 | { |
| 7944 | xpath_node_set_raw s = _left->eval_node_set(c, stack); |
| 7945 | |
| 7946 | // self axis preserves the original order |
| 7947 | if (axis == axis_self) ns.set_type(s.type()); |
| 7948 | |
| 7949 | for (const xpath_node* it = s.begin(); it != s.end(); ++it) |
| 7950 | { |
| 7951 | size_t size = ns.size(); |
| 7952 | |
| 7953 | // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes |
| 7954 | if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); |
| 7955 | |
| 7956 | if (it->node()) |
| 7957 | step_fill(ns, it->node(), stack.result, v); |
| 7958 | else if (attributes) |
| 7959 | step_fill(ns, it->attribute(), it->parent(), stack.result, v); |
| 7960 | |
| 7961 | apply_predicates(ns, size, stack); |
| 7962 | } |
| 7963 | } |
| 7964 | else |
| 7965 | { |
| 7966 | if (c.n.node()) |
| 7967 | step_fill(ns, c.n.node(), stack.result, v); |
| 7968 | else if (attributes) |
| 7969 | step_fill(ns, c.n.attribute(), c.n.parent(), stack.result, v); |
| 7970 | |
| 7971 | apply_predicates(ns, 0, stack); |
| 7972 | } |
| 7973 | |
| 7974 | // child, attribute and self axes always generate unique set of nodes |
| 7975 | // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice |
| 7976 | if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted) |
| 7977 | ns.remove_duplicates(); |
| 7978 | |
| 7979 | return ns; |
| 7980 | } |
| 7981 | |
| 7982 | public: |
| 7983 | xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t* value): |
nothing calls this directly
no test coverage detected