Skip to content

Commit

Permalink
Clean up Selector_List::operator==
Browse files Browse the repository at this point in the history
Implements equality for selector lists in a cleaner and more efficient manner.

Related issue: sass#2666 (likely fixed by this change but I haven't verified).
  • Loading branch information
glebm authored and xzyfer committed Nov 21, 2018
1 parent 754b338 commit 122d9f3
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 28 deletions.
37 changes: 10 additions & 27 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,34 +459,17 @@ namespace Sass {

bool Selector_List::operator== (const Selector_List& 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<Complex_Selector_Obj> l_lst = this->elements();
std::vector<Complex_Selector_Obj> 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
Complex_Selector_Obj l = l_lst[i];
Complex_Selector_Obj r = r_lst[n];
// skip nulls
if (!l) ++i;
else if (!r) ++n;
// do the check
else if (*l != *r)
{ return false; }
// advance
++i; ++n;
if (&rhs == this) return true;
if (rhs.length() != length()) return false;
std::unordered_set<const Complex_Selector *, HashPtr, ComparePtrs> lhs_set;
lhs_set.reserve(length());
for (const Complex_Selector_Obj &element : elements()) {
lhs_set.insert(element.ptr());
}
// there is no break?!
for (const Complex_Selector_Obj &element : rhs.elements()) {
if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
}
return true;
}

bool Selector_List::operator< (const Selector& rhs) const
Expand Down
2 changes: 1 addition & 1 deletion src/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2288,7 +2288,7 @@ namespace Sass {
name += ns_ + "|";
return name + name_;
}
size_t hash() const override
virtual size_t hash() const override
{
if (hash_ == 0) {
hash_combine(hash_, std::hash<int>()(SELECTOR));
Expand Down
13 changes: 13 additions & 0 deletions src/ast_fwd_decl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,19 @@ namespace Sass {
}
};

struct HashPtr {
template <class T>
size_t operator() (const T *ref) const {
return ref->hash();
}
};
struct ComparePtrs {
template <class T>
bool operator() (const T *lhs, const T *rhs) const {
return *lhs == *rhs;
}
};

// ###########################################################################
// some often used typedefs
// ###########################################################################
Expand Down

0 comments on commit 122d9f3

Please sign in to comment.