| 9136 | } |
| 9137 | |
| 9138 | template <class T> xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval, T v) |
| 9139 | { |
| 9140 | const axis_t axis = T::axis; |
| 9141 | const bool axis_reverse = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling); |
| 9142 | const xpath_node_set::type_t axis_type = axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; |
| 9143 | |
| 9144 | bool once = |
| 9145 | (axis == axis_attribute && _test == nodetest_name) || |
| 9146 | (!_right && eval_once(axis_type, eval)) || |
| 9147 | (_right && !_right->_next && _right->_test == predicate_constant_one); |
| 9148 | |
| 9149 | xpath_node_set_raw ns; |
| 9150 | ns.set_type(axis_type); |
| 9151 | |
| 9152 | if (_left) |
| 9153 | { |
| 9154 | xpath_node_set_raw s = _left->eval_node_set(c, stack, nodeset_eval_all); |
| 9155 | |
| 9156 | // self axis preserves the original order |
| 9157 | if (axis == axis_self) ns.set_type(s.type()); |
| 9158 | |
| 9159 | for (const xpath_node* it = s.begin(); it != s.end(); ++it) |
| 9160 | { |
| 9161 | size_t size = ns.size(); |
| 9162 | |
| 9163 | // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes |
| 9164 | if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); |
| 9165 | |
| 9166 | step_fill(ns, *it, stack.result, once, v); |
| 9167 | if (_right) apply_predicates(ns, size, stack, eval); |
| 9168 | } |
| 9169 | } |
| 9170 | else |
| 9171 | { |
| 9172 | step_fill(ns, c.n, stack.result, once, v); |
| 9173 | if (_right) apply_predicates(ns, 0, stack, eval); |
| 9174 | } |
| 9175 | |
| 9176 | // child, attribute and self axes always generate unique set of nodes |
| 9177 | // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice |
| 9178 | if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted) |
| 9179 | ns.remove_duplicates(); |
| 9180 | |
| 9181 | return ns; |
| 9182 | } |
| 9183 | |
| 9184 | public: |
| 9185 | xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t* value): |
nothing calls this directly
no test coverage detected