ArrayRef: Put back std::equal for operator== with a check for the empty ArrayRefs
authorBenjamin Kramer <benny.kra@googlemail.com>
Sun, 1 Mar 2015 23:35:20 +0000 (23:35 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sun, 1 Mar 2015 23:35:20 +0000 (23:35 +0000)
This has the nice property of compiling down to memcmp when feasible. An empty
ArrayRef can have a nullptr in its Data field. I didn't find anything in the
standard speaking against std::equal(nullptr, nullptr, nullptr) begin valid but
MSVC asserts. The way libstdc++ lowers std::equal down to memcmp also makes
invoking std::equal with a nullptr undefined behavior so checking is the only
way to be safe.

The extra check doesn't cost us perf either because we're essentially peeling
the loop header away from the rotated loop.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230920 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/ArrayRef.h

index 7f5fa3271ac777dc7390ff75ee2758d6e9d8ca47..e973054daefb7d906451003dfb27aa1358b4f002 100644 (file)
@@ -135,15 +135,9 @@ namespace llvm {
 
     /// equals - Check for element-wise equality.
     bool equals(ArrayRef RHS) const {
-      if (Length != RHS.Length)
+      if (Length != RHS.Length || Length == 0)
         return false;
-      // Don't use std::equal(), since it asserts in MSVC on nullptr iterators.
-      for (auto L = begin(), LE = end(), R = RHS.begin(); L != LE; ++L, ++R)
-        // Match std::equal() in using == (instead of !=) to minimize API
-        // requirements of ArrayRef'ed types.
-        if (!(*L == *R))
-          return false;
-      return true;
+      return std::equal(begin(), end(), RHS.begin());
     }
 
     /// slice(n) - Chop off the first N elements of the array.