Skip to content

Commit

Permalink
Make (Fixed)Span<T>::data_equals a plain method (not a template) (#30479
Browse files Browse the repository at this point in the history
)

This allows implicit conversion (e.g. from std::array) to take place.
  • Loading branch information
ksperling-apple authored and pull[bot] committed Jan 17, 2024
1 parent 853d4fc commit 3053849
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 20 deletions.
22 changes: 2 additions & 20 deletions src/lib/support/Span.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,10 @@ class Span
reference front() const { return (*this)[0]; }
reference back() const { return (*this)[size() - 1]; }

template <class U, typename = std::enable_if_t<std::is_same<std::remove_const_t<T>, std::remove_const_t<U>>::value>>
bool data_equal(const Span<U> & other) const
bool data_equal(const Span<const T> & other) const
{
return (size() == other.size()) && (empty() || (memcmp(data(), other.data(), size() * sizeof(T)) == 0));
}
template <class U, size_t N, typename = std::enable_if_t<std::is_same<std::remove_const_t<T>, std::remove_const_t<U>>::value>>
inline bool data_equal(const FixedSpan<U, N> & other) const;

Span SubSpan(size_t offset, size_t length) const
{
Expand Down Expand Up @@ -329,15 +326,7 @@ class FixedSpan
reference front() const { return (*this)[0]; }
reference back() const { return (*this)[size() - 1]; }

// Allow data_equal for spans that are over the same type up to const-ness.
template <class U, typename = std::enable_if_t<std::is_same<std::remove_const_t<T>, std::remove_const_t<U>>::value>>
bool data_equal(const FixedSpan<U, N> & other) const
{
return (memcmp(data(), other.data(), N * sizeof(T)) == 0);
}

template <class U, typename = std::enable_if_t<std::is_same<std::remove_const_t<T>, std::remove_const_t<U>>::value>>
bool data_equal(const Span<U> & other) const
bool data_equal(const Span<const T> & other) const
{
return (N == other.size() && memcmp(data(), other.data(), N * sizeof(T)) == 0);
}
Expand All @@ -359,13 +348,6 @@ template <class U, size_t N, typename>
constexpr Span<T>::Span(const FixedSpan<U, N> & other) : mDataBuf(other.data()), mDataLen(other.size())
{}

template <class T>
template <class U, size_t N, typename>
inline bool Span<T>::data_equal(const FixedSpan<U, N> & other) const
{
return other.data_equal(*this);
}

template <typename T>
[[deprecated("Use !empty()")]] inline bool IsSpanUsable(const Span<T> & span)
{
Expand Down
9 changes: 9 additions & 0 deletions src/lib/support/tests/TestSpan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,15 @@ static void TestConversionConstructors(nlTestSuite * inSuite, void * inContext)
([](FixedSpan<const Foo, 3> f) {})(constArray);
([](Span<const Foo> f) {})(constArray);

NL_TEST_ASSERT(inSuite, span10.data_equal(span10));
NL_TEST_ASSERT(inSuite, span10.data_equal(span9));
NL_TEST_ASSERT(inSuite, span10.data_equal(array));
NL_TEST_ASSERT(inSuite, span10.data_equal(constArray));
NL_TEST_ASSERT(inSuite, span9.data_equal(span9));
NL_TEST_ASSERT(inSuite, span9.data_equal(span10));
NL_TEST_ASSERT(inSuite, span9.data_equal(array));
NL_TEST_ASSERT(inSuite, span9.data_equal(constArray));

// The following should not compile
// Span<const Foo> error1 = std::array<Foo, 3>(); // Span would point into a temporary value
}
Expand Down

0 comments on commit 3053849

Please sign in to comment.