From 2a4935c9ad137bedb1be6690a78995a6714a7e62 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sun, 25 Nov 2018 12:36:18 +0000 Subject: [PATCH] Clean up `Compound_Selector::operator==` Implements equality for `Compound_Selector` in a cleaner and more efficient manner. Similar change for `Selector_List`: #2739 This does not fix the stack overflow reported in #2667, though it does change its location (because we no longer clone any nodes in `operator==`). --- src/ast.cpp | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/ast.cpp b/src/ast.cpp index 385ae8aff..1e3e5b356 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -1012,34 +1012,17 @@ namespace Sass { bool Compound_Selector::operator== (const Compound_Selector& rhs) const { - // for array access - size_t i = 0, n = 0; - size_t iL = length(); - size_t nL = rhs.length(); - // create temporary vectors and sort them - std::vector l_lst = this->elements(); - std::vector r_lst = rhs.elements(); - std::sort(l_lst.begin(), l_lst.end(), OrderNodes()); - std::sort(r_lst.begin(), r_lst.end(), OrderNodes()); - // process loop - while (true) - { - // first check for valid index - if (i == iL) return iL == nL; - else if (n == nL) return iL == nL; - // the access the vector items - Simple_Selector_Obj l = l_lst[i]; - Simple_Selector_Obj r = r_lst[n]; - // skip nulls - if (!l) ++i; - if (!r) ++n; - // do the check now - else if (*l != *r) - { return false; } - // advance now - ++i; ++n; + if (&rhs == this) return true; + if (rhs.length() != length()) return false; + std::unordered_set lhs_set; + lhs_set.reserve(length()); + for (const Simple_Selector_Obj &element : elements()) { + lhs_set.insert(element.ptr()); } - // there is no break?! + for (const Simple_Selector_Obj &element : rhs.elements()) { + if (lhs_set.find(element.ptr()) == lhs_set.end()) return false; + } + return true; } bool Complex_Selector::is_superselector_of(Compound_Selector_Ptr_Const rhs, std::string wrapping) const