Add Span equality (== and !=) operators.
Exchange duplicate equality iteration implementations across `Vector` and `String` with the `Span` version, for a speed boost.
This commit is contained in:
@ -33,6 +33,24 @@
|
||||
#include "core/error/error_macros.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
template <typename LHS, typename RHS>
|
||||
bool are_spans_equal(const LHS *p_lhs, const RHS *p_rhs, size_t p_size) {
|
||||
if constexpr (std::is_same_v<LHS, RHS> && std::is_fundamental_v<LHS>) {
|
||||
// Optimize trivial type comparison.
|
||||
// is_trivially_equality_comparable would help, but it doesn't exist.
|
||||
return memcmp(p_lhs, p_rhs, p_size * sizeof(LHS)) == 0;
|
||||
} else {
|
||||
// Normal case: Need to iterate the array manually.
|
||||
for (size_t j = 0; j < p_size; j++) {
|
||||
if (p_lhs[j] != p_rhs[j]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Equivalent of std::span.
|
||||
// Represents a view into a contiguous memory space.
|
||||
// DISCLAIMER: This data type does not own the underlying buffer. DO NOT STORE IT.
|
||||
@ -126,14 +144,7 @@ constexpr int64_t Span<T>::find(const T &p_val, uint64_t p_from) const {
|
||||
template <typename T>
|
||||
constexpr int64_t Span<T>::find_sequence(const Span<T> &p_span, uint64_t p_from) const {
|
||||
for (uint64_t i = p_from; i <= size() - p_span.size(); i++) {
|
||||
bool found = true;
|
||||
for (uint64_t j = 0; j < p_span.size(); j++) {
|
||||
if (ptr()[i + j] != p_span.ptr()[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
if (are_spans_equal(ptr() + i, p_span.ptr(), p_span.size())) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -154,14 +165,7 @@ constexpr int64_t Span<T>::rfind(const T &p_val, uint64_t p_from) const {
|
||||
template <typename T>
|
||||
constexpr int64_t Span<T>::rfind_sequence(const Span<T> &p_span, uint64_t p_from) const {
|
||||
for (int64_t i = p_from; i >= 0; i--) {
|
||||
bool found = true;
|
||||
for (uint64_t j = 0; j < p_span.size(); j++) {
|
||||
if (ptr()[i + j] != p_span.ptr()[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
if (are_spans_equal(ptr() + i, p_span.ptr(), p_span.size())) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -219,6 +223,16 @@ constexpr T Span<T>::max() const {
|
||||
return max_val;
|
||||
}
|
||||
|
||||
template <typename LHS, typename RHS>
|
||||
bool operator==(const Span<LHS> &p_lhs, const Span<RHS> &p_rhs) {
|
||||
return p_lhs.size() == p_rhs.size() && are_spans_equal(p_lhs.ptr(), p_rhs.ptr(), p_lhs.size());
|
||||
}
|
||||
|
||||
template <typename LHS, typename RHS>
|
||||
_FORCE_INLINE_ bool operator!=(const Span<LHS> &p_lhs, const Span<RHS> &p_rhs) {
|
||||
return !(p_lhs == p_rhs);
|
||||
}
|
||||
|
||||
// Zero-constructing Span initializes _ptr and _len to 0 (and thus empty).
|
||||
template <typename T>
|
||||
struct is_zero_constructible<Span<T>> : std::true_type {};
|
||||
|
||||
@ -248,31 +248,8 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const Vector<T> &p_arr) const {
|
||||
Size s = size();
|
||||
if (s != p_arr.size()) {
|
||||
return false;
|
||||
}
|
||||
for (Size i = 0; i < s; i++) {
|
||||
if (operator[](i) != p_arr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Vector<T> &p_arr) const {
|
||||
Size s = size();
|
||||
if (s != p_arr.size()) {
|
||||
return true;
|
||||
}
|
||||
for (Size i = 0; i < s; i++) {
|
||||
if (operator[](i) != p_arr[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool operator==(const Vector<T> &p_arr) const { return span() == p_arr.span(); }
|
||||
bool operator!=(const Vector<T> &p_arr) const { return span() != p_arr.span(); }
|
||||
|
||||
struct Iterator {
|
||||
_FORCE_INLINE_ T &operator*() const {
|
||||
|
||||
Reference in New Issue
Block a user