From 2a06b026efd068962c04c515d0ed164783b6945f Mon Sep 17 00:00:00 2001 From: Lenny Maiorani Date: Sun, 15 Nov 2020 09:45:53 -0700 Subject: [PATCH] Vector: C++20 equality operators Problem: - C++20 changes the way equality operators are generated. This results in overload ambiguity as reported by clang. Solution: - Remove `AK::Vector::operator!=` because it will be automatically generated in terms of `AK::Vector::operator==`. - Change `AK::Vector::operator==` to be a function template so that overload resolution is not confused about `a == b` vs `b == a`. - Add tests to ensure the behavior works. Notes: - There is more info available at https://brevzin.github.io/c++/2019/07/28/comparisons-cpp20/ for deeper discussion about overload resolution, operator rewriting, and generated functions. --- AK/Tests/TestVector.cpp | 67 +++++++++++++++++++++++++++++++++++++++++ AK/Vector.h | 12 +++----- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/AK/Tests/TestVector.cpp b/AK/Tests/TestVector.cpp index 59e1cd05444..82782084289 100644 --- a/AK/Tests/TestVector.cpp +++ b/AK/Tests/TestVector.cpp @@ -327,4 +327,71 @@ TEST_CASE(resize_initializes) EXPECT(ints[idx].initialized); } +TEST_CASE(should_compare_vectors_of_same_type) +{ + Vector a {}; + Vector b {}; + + EXPECT(a == b); + EXPECT(!(a != b)); + + a.append(1); + EXPECT(!(a == b)); + EXPECT(a != b); + + b.append(1); + EXPECT(a == b); + EXPECT(!(a != b)); + + a.append(42); + b.append(17); + EXPECT(!(a == b)); + EXPECT(a != b); +} + +TEST_CASE(should_compare_vectors_of_different_inline_capacity) +{ + Vector a {}; + Vector b {}; + + EXPECT(a == b); + EXPECT(!(a != b)); + + a.append(1); + EXPECT(!(a == b)); + EXPECT(a != b); + + b.append(1); + EXPECT(a == b); + EXPECT(!(a != b)); + + a.append(42); + b.append(17); + EXPECT(!(a == b)); + EXPECT(a != b); +} + +TEST_CASE(should_compare_vectors_of_different_sizes) +{ + Vector a {}; + Vector b {}; + + EXPECT(a == b); + EXPECT(!(a != b)); + + // A is longer + a.append(1); + EXPECT(!(a == b)); + EXPECT(a != b); + + b.append(1); + EXPECT(a == b); + EXPECT(!(a != b)); + + // B is longer + b.append(42); + EXPECT(!(a == b)); + EXPECT(a != b); +} + TEST_MAIN(Vector) diff --git a/AK/Vector.h b/AK/Vector.h index 01ed92ee24c..c6c880e901b 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -52,6 +52,8 @@ namespace AK { template class Vector { public: + using value_type = T; + Vector() : m_capacity(inline_capacity) { @@ -147,18 +149,14 @@ public: m_size = 0; } - bool operator==(const Vector& other) const + template + bool operator==(const V& other) const { - if (m_size != other.m_size) + if (m_size != other.size()) return false; return TypedTransfer::compare(data(), other.data(), size()); } - bool operator!=(const Vector& other) const - { - return !(*this == other); - } - operator Span() { return span(); } operator Span() const { return span(); }