| 11087 | } |
| 11088 | |
| 11089 | xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval) |
| 11090 | { |
| 11091 | switch (_type) |
| 11092 | { |
| 11093 | case ast_op_union: |
| 11094 | { |
| 11095 | xpath_allocator_capture cr(stack.temp); |
| 11096 | |
| 11097 | xpath_stack swapped_stack = {stack.temp, stack.result}; |
| 11098 | |
| 11099 | xpath_node_set_raw ls = _left->eval_node_set(c, stack, eval); |
| 11100 | xpath_node_set_raw rs = _right->eval_node_set(c, swapped_stack, eval); |
| 11101 | |
| 11102 | // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother |
| 11103 | ls.set_type(xpath_node_set::type_unsorted); |
| 11104 | |
| 11105 | ls.append(rs.begin(), rs.end(), stack.result); |
| 11106 | ls.remove_duplicates(stack.temp); |
| 11107 | |
| 11108 | return ls; |
| 11109 | } |
| 11110 | |
| 11111 | case ast_filter: |
| 11112 | { |
| 11113 | xpath_node_set_raw set = _left->eval_node_set(c, stack, _test == predicate_constant_one ? nodeset_eval_first : nodeset_eval_all); |
| 11114 | |
| 11115 | // either expression is a number or it contains position() call; sort by document order |
| 11116 | if (_test != predicate_posinv) set.sort_do(); |
| 11117 | |
| 11118 | bool once = eval_once(set.type(), eval); |
| 11119 | |
| 11120 | apply_predicate(set, 0, stack, once); |
| 11121 | |
| 11122 | return set; |
| 11123 | } |
| 11124 | |
| 11125 | case ast_func_id: |
| 11126 | return xpath_node_set_raw(); |
| 11127 | |
| 11128 | case ast_step: |
| 11129 | { |
| 11130 | switch (_axis) |
| 11131 | { |
| 11132 | case axis_ancestor: |
| 11133 | return step_do(c, stack, eval, axis_to_type<axis_ancestor>()); |
| 11134 | |
| 11135 | case axis_ancestor_or_self: |
| 11136 | return step_do(c, stack, eval, axis_to_type<axis_ancestor_or_self>()); |
| 11137 | |
| 11138 | case axis_attribute: |
| 11139 | return step_do(c, stack, eval, axis_to_type<axis_attribute>()); |
| 11140 | |
| 11141 | case axis_child: |
| 11142 | return step_do(c, stack, eval, axis_to_type<axis_child>()); |
| 11143 | |
| 11144 | case axis_descendant: |
| 11145 | return step_do(c, stack, eval, axis_to_type<axis_descendant>()); |
| 11146 |
no test coverage detected