ArrayRef: Put back std::equal for operator== with a check for the empty ArrayRefs

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.

llvm-svn: 230920
This commit is contained in:
Benjamin Kramer 2015-03-01 23:35:20 +00:00
parent bc477ddee0
commit 7f360ce5c2
1 changed files with 2 additions and 8 deletions

View 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.