| 7934 | } |
| 7935 | |
| 7936 | xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack) |
| 7937 | { |
| 7938 | switch (_type) |
| 7939 | { |
| 7940 | case ast_op_union: |
| 7941 | { |
| 7942 | xpath_allocator_capture cr(stack.temp); |
| 7943 | |
| 7944 | xpath_stack swapped_stack = {stack.temp, stack.result}; |
| 7945 | |
| 7946 | xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack); |
| 7947 | xpath_node_set_raw rs = _right->eval_node_set(c, stack); |
| 7948 | |
| 7949 | // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother |
| 7950 | rs.set_type(xpath_node_set::type_unsorted); |
| 7951 | |
| 7952 | rs.append(ls.begin(), ls.end(), stack.result); |
| 7953 | rs.remove_duplicates(); |
| 7954 | |
| 7955 | return rs; |
| 7956 | } |
| 7957 | |
| 7958 | case ast_filter: |
| 7959 | case ast_filter_posinv: |
| 7960 | { |
| 7961 | xpath_node_set_raw set = _left->eval_node_set(c, stack); |
| 7962 | |
| 7963 | // either expression is a number or it contains position() call; sort by document order |
| 7964 | if (_type == ast_filter) set.sort_do(); |
| 7965 | |
| 7966 | apply_predicate(set, 0, _right, stack); |
| 7967 | |
| 7968 | return set; |
| 7969 | } |
| 7970 | |
| 7971 | case ast_func_id: |
| 7972 | return xpath_node_set_raw(); |
| 7973 | |
| 7974 | case ast_step: |
| 7975 | { |
| 7976 | switch (_axis) |
| 7977 | { |
| 7978 | case axis_ancestor: |
| 7979 | return step_do(c, stack, axis_to_type<axis_ancestor>()); |
| 7980 | |
| 7981 | case axis_ancestor_or_self: |
| 7982 | return step_do(c, stack, axis_to_type<axis_ancestor_or_self>()); |
| 7983 | |
| 7984 | case axis_attribute: |
| 7985 | return step_do(c, stack, axis_to_type<axis_attribute>()); |
| 7986 | |
| 7987 | case axis_child: |
| 7988 | return step_do(c, stack, axis_to_type<axis_child>()); |
| 7989 | |
| 7990 | case axis_descendant: |
| 7991 | return step_do(c, stack, axis_to_type<axis_descendant>()); |
| 7992 | |
| 7993 | case axis_descendant_or_self: |
no test coverage detected