| 8556 | } |
| 8557 | |
| 8558 | xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack) |
| 8559 | { |
| 8560 | switch (_type) |
| 8561 | { |
| 8562 | case ast_op_union: |
| 8563 | { |
| 8564 | xpath_allocator_capture cr(stack.temp); |
| 8565 | |
| 8566 | xpath_stack swapped_stack = {stack.temp, stack.result}; |
| 8567 | |
| 8568 | xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack); |
| 8569 | xpath_node_set_raw rs = _right->eval_node_set(c, stack); |
| 8570 | |
| 8571 | // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother |
| 8572 | rs.set_type(xpath_node_set::type_unsorted); |
| 8573 | |
| 8574 | rs.append(ls.begin(), ls.end(), stack.result); |
| 8575 | rs.remove_duplicates(); |
| 8576 | |
| 8577 | return rs; |
| 8578 | } |
| 8579 | |
| 8580 | case ast_filter: |
| 8581 | case ast_filter_posinv: |
| 8582 | { |
| 8583 | xpath_node_set_raw set = _left->eval_node_set(c, stack); |
| 8584 | |
| 8585 | // either expression is a number or it contains position() call; sort by document order |
| 8586 | if (_type == ast_filter) set.sort_do(); |
| 8587 | |
| 8588 | apply_predicate(set, 0, _right, stack); |
| 8589 | |
| 8590 | return set; |
| 8591 | } |
| 8592 | |
| 8593 | case ast_func_id: |
| 8594 | return xpath_node_set_raw(); |
| 8595 | |
| 8596 | case ast_step: |
| 8597 | { |
| 8598 | switch (_axis) |
| 8599 | { |
| 8600 | case axis_ancestor: |
| 8601 | return step_do(c, stack, axis_to_type<axis_ancestor>()); |
| 8602 | |
| 8603 | case axis_ancestor_or_self: |
| 8604 | return step_do(c, stack, axis_to_type<axis_ancestor_or_self>()); |
| 8605 | |
| 8606 | case axis_attribute: |
| 8607 | return step_do(c, stack, axis_to_type<axis_attribute>()); |
| 8608 | |
| 8609 | case axis_child: |
| 8610 | return step_do(c, stack, axis_to_type<axis_child>()); |
| 8611 | |
| 8612 | case axis_descendant: |
| 8613 | return step_do(c, stack, axis_to_type<axis_descendant>()); |
| 8614 | |
| 8615 | case axis_descendant_or_self: |
no test coverage detected