From 4c7d82fa5bfcbd7a9a80004ab0f6d5619897f1d3 Mon Sep 17 00:00:00 2001 From: "arseny.kapoulkine" Date: Thu, 20 May 2010 22:11:19 +0000 Subject: More compare_eq/rel refactoring git-svn-id: http://pugixml.googlecode.com/svn/trunk@439 99668b35-9821-0410-8761-19e4c4f06640 --- src/pugixpath.cpp | 239 ++++++++++++++++++++++++------------------------------ 1 file changed, 106 insertions(+), 133 deletions(-) diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp index 60f65b8..bc51b4d 100644 --- a/src/pugixpath.cpp +++ b/src/pugixpath.cpp @@ -503,33 +503,33 @@ namespace return PUGIXML_TEXT(""); } - template struct equal_to + struct equal_to { - bool operator()(const T& lhs, const T& rhs) const + template bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; } }; - template struct not_equal_to + struct not_equal_to { - bool operator()(const T& lhs, const T& rhs) const + template bool operator()(const T& lhs, const T& rhs) const { return lhs != rhs; } }; - template struct less + struct less { - bool operator()(const T& lhs, const T& rhs) const + template bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } }; - template struct less_equal + struct less_equal { - bool operator()(const T& lhs, const T& rhs) const + template bool operator()(const T& lhs, const T& rhs) const { return lhs <= rhs; } @@ -1296,158 +1296,131 @@ namespace pugi xpath_ast_node(const xpath_ast_node&); xpath_ast_node& operator=(const xpath_ast_node&); - template struct compare_eq + template static bool compare_eq(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const Comp& comp = Comp()) { - static bool run(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c) + xpath_type_t lt = lhs->rettype(), rt = rhs->rettype(); + + if (lt != xpath_type_node_set && rt != xpath_type_node_set) { - if (lhs->rettype() != xpath_type_node_set && rhs->rettype() != xpath_type_node_set) - { - if (lhs->rettype() == xpath_type_boolean || rhs->rettype() == xpath_type_boolean) - return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c)); - else if (lhs->rettype() == xpath_type_number || rhs->rettype() == xpath_type_number) - return Cdouble()(lhs->eval_number(c), rhs->eval_number(c)); - else if (lhs->rettype() == xpath_type_string || rhs->rettype() == xpath_type_string) - return Cstring()(lhs->eval_string(c), rhs->eval_string(c)); - } - else if (lhs->rettype() == xpath_type_node_set && rhs->rettype() == xpath_type_node_set) - { - xpath_node_set ls = lhs->eval_node_set(c); - xpath_node_set rs = rhs->eval_node_set(c); - - for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li) + if (lt == xpath_type_boolean || rt == xpath_type_boolean) + return comp(lhs->eval_boolean(c), rhs->eval_boolean(c)); + else if (lt == xpath_type_number || rt == xpath_type_number) + return comp(lhs->eval_number(c), rhs->eval_number(c)); + else if (lt == xpath_type_string || rt == xpath_type_string) + return comp(lhs->eval_string(c), rhs->eval_string(c)); + } + else if (lt == xpath_type_node_set && rt == xpath_type_node_set) + { + xpath_node_set ls = lhs->eval_node_set(c); + xpath_node_set rs = rhs->eval_node_set(c); + + for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li) for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri) { - if (Cstring()(string_value(*li), string_value(*ri))) + if (comp(string_value(*li), string_value(*ri))) return true; } - - return false; - } - else if (lhs->rettype() != xpath_type_node_set && rhs->rettype() == xpath_type_node_set) - { - if (lhs->rettype() == xpath_type_boolean) - return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c)); - else if (lhs->rettype() == xpath_type_number) - { - double l = lhs->eval_number(c); - xpath_node_set rs = rhs->eval_node_set(c); - - for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri) - { - if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true) - return true; - } - - return false; - } - else if (lhs->rettype() == xpath_type_string) - { - string_t l = lhs->eval_string(c); - xpath_node_set rs = rhs->eval_node_set(c); - - for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri) - { - if (Cstring()(l, string_value(*ri)) == true) - return true; - } - - return false; - } - } - else if (lhs->rettype() == xpath_type_node_set && rhs->rettype() != xpath_type_node_set) - { - if (rhs->rettype() == xpath_type_boolean) - return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c)); - else if (rhs->rettype() == xpath_type_number) - { - xpath_node_set ls = lhs->eval_node_set(c); - double r = rhs->eval_number(c); - - for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li) - { - if (Cdouble()(convert_string_to_number(string_value(*li).c_str()), r) == true) - return true; - } - - return false; - } - else if (rhs->rettype() == xpath_type_string) - { - xpath_node_set ls = lhs->eval_node_set(c); - string_t r = rhs->eval_string(c); - - for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li) - { - if (Cstring()(string_value(*li), r) == true) - return true; - } - - return false; - } - } - assert(!"Wrong types"); return false; } - }; - - template struct compare_rel - { - static bool run(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c) + else { - if (lhs->rettype() != xpath_type_node_set && rhs->rettype() != xpath_type_node_set) - return Cdouble()(lhs->eval_number(c), rhs->eval_number(c)); - else if (lhs->rettype() == xpath_type_node_set && rhs->rettype() == xpath_type_node_set) + if (lt == xpath_type_node_set) + { + std::swap(lhs, rhs); + std::swap(lt, rt); + } + + if (lt == xpath_type_boolean) + return comp(lhs->eval_boolean(c), rhs->eval_boolean(c)); + else if (lt == xpath_type_number) { - xpath_node_set ls = lhs->eval_node_set(c); + double l = lhs->eval_number(c); xpath_node_set rs = rhs->eval_node_set(c); - - for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li) + + for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri) { - double l = convert_string_to_number(string_value(*li).c_str()); - - for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri) - { - if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true) - return true; - } + if (comp(l, convert_string_to_number(string_value(*ri).c_str()))) + return true; } - + return false; } - else if (lhs->rettype() != xpath_type_node_set && rhs->rettype() == xpath_type_node_set) + else if (lt == xpath_type_string) { - double l = lhs->eval_number(c); + string_t l = lhs->eval_string(c); xpath_node_set rs = rhs->eval_node_set(c); - + for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri) { - if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true) + if (comp(l, string_value(*ri))) return true; } - + return false; } - else if (lhs->rettype() == xpath_type_node_set && rhs->rettype() != xpath_type_node_set) + } + + assert(!"Wrong types"); + return false; + } + + template static bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const Comp& comp = Comp()) + { + xpath_type_t lt = lhs->rettype(), rt = rhs->rettype(); + + if (lt != xpath_type_node_set && rt != xpath_type_node_set) + return comp(lhs->eval_number(c), rhs->eval_number(c)); + else if (lt == xpath_type_node_set && rt == xpath_type_node_set) + { + xpath_node_set ls = lhs->eval_node_set(c); + xpath_node_set rs = rhs->eval_node_set(c); + + for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li) { - xpath_node_set ls = lhs->eval_node_set(c); - double r = rhs->eval_number(c); + double l = convert_string_to_number(string_value(*li).c_str()); - for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li) + for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri) { - if (Cdouble()(convert_string_to_number(string_value(*li).c_str()), r) == true) + if (comp(l, convert_string_to_number(string_value(*ri).c_str()))) return true; } - - return false; } - else + + return false; + } + else if (lt != xpath_type_node_set && rt == xpath_type_node_set) + { + double l = lhs->eval_number(c); + xpath_node_set rs = rhs->eval_node_set(c); + + for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri) { - assert(!"Wrong types"); - return false; + if (comp(l, convert_string_to_number(string_value(*ri).c_str()))) + return true; } + + return false; } - }; + else if (lt == xpath_type_node_set && rt != xpath_type_node_set) + { + xpath_node_set ls = lhs->eval_node_set(c); + double r = rhs->eval_number(c); + + for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li) + { + if (comp(convert_string_to_number(string_value(*li).c_str()), r)) + return true; + } + + return false; + } + else + { + assert(!"Wrong types"); + return false; + } + } void apply_predicate(xpath_node_set& ns, size_t first, xpath_ast_node* expr, const xpath_context& context) { @@ -1974,22 +1947,22 @@ namespace pugi else return m_right->eval_boolean(c); case ast_op_equal: - return compare_eq, equal_to, equal_to >::run(m_left, m_right, c); + return compare_eq(m_left, m_right, c, equal_to()); case ast_op_not_equal: - return compare_eq, not_equal_to, not_equal_to >::run(m_left, m_right, c); + return compare_eq(m_left, m_right, c, not_equal_to()); case ast_op_less: - return compare_rel >::run(m_left, m_right, c); + return compare_rel(m_left, m_right, c, less()); case ast_op_greater: - return compare_rel >::run(m_right, m_left, c); + return compare_rel(m_right, m_left, c, less()); case ast_op_less_or_equal: - return compare_rel >::run(m_left, m_right, c); + return compare_rel(m_left, m_right, c, less_equal()); case ast_op_greater_or_equal: - return compare_rel >::run(m_right, m_left, c); + return compare_rel(m_right, m_left, c, less_equal()); case ast_func_starts_with: return starts_with(m_left->eval_string(c).c_str(), m_right->eval_string(c).c_str()); -- cgit v1.2.3