3333#include " core/error/error_macros.h"
3434#include " core/typedefs.h"
3535
36+ template <typename LHS, typename RHS>
37+ bool are_spans_equal (const LHS *p_lhs, const RHS *p_rhs, size_t p_size) {
38+ if constexpr (std::is_same_v<LHS, RHS> && std::is_fundamental_v<LHS>) {
39+ // Optimize trivial type comparison.
40+ // is_trivially_equality_comparable would help, but it doesn't exist.
41+ return memcmp (p_lhs, p_rhs, p_size * sizeof (LHS)) == 0 ;
42+ } else {
43+ // Normal case: Need to iterate the array manually.
44+ for (size_t j = 0 ; j < p_size; j++) {
45+ if (p_lhs[j] != p_rhs[j]) {
46+ return false ;
47+ }
48+ }
49+
50+ return true ;
51+ }
52+ }
53+
3654// Equivalent of std::span.
3755// Represents a view into a contiguous memory space.
3856// 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 {
126144template <typename T>
127145constexpr int64_t Span<T>::find_sequence(const Span<T> &p_span, uint64_t p_from) const {
128146 for (uint64_t i = p_from; i <= size () - p_span.size (); i++) {
129- bool found = true ;
130- for (uint64_t j = 0 ; j < p_span.size (); j++) {
131- if (ptr ()[i + j] != p_span.ptr ()[j]) {
132- found = false ;
133- break ;
134- }
135- }
136- if (found) {
147+ if (are_spans_equal (ptr () + i, p_span.ptr (), p_span.size ())) {
137148 return i;
138149 }
139150 }
@@ -154,14 +165,7 @@ constexpr int64_t Span<T>::rfind(const T &p_val, uint64_t p_from) const {
154165template <typename T>
155166constexpr int64_t Span<T>::rfind_sequence(const Span<T> &p_span, uint64_t p_from) const {
156167 for (int64_t i = p_from; i >= 0 ; i--) {
157- bool found = true ;
158- for (uint64_t j = 0 ; j < p_span.size (); j++) {
159- if (ptr ()[i + j] != p_span.ptr ()[j]) {
160- found = false ;
161- break ;
162- }
163- }
164- if (found) {
168+ if (are_spans_equal (ptr () + i, p_span.ptr (), p_span.size ())) {
165169 return i;
166170 }
167171 }
@@ -219,6 +223,16 @@ constexpr T Span<T>::max() const {
219223 return max_val;
220224}
221225
226+ template <typename LHS, typename RHS>
227+ bool operator ==(const Span<LHS> &p_lhs, const Span<RHS> &p_rhs) {
228+ return p_lhs.size () == p_rhs.size () && are_spans_equal (p_lhs.ptr (), p_rhs.ptr (), p_lhs.size ());
229+ }
230+
231+ template <typename LHS, typename RHS>
232+ _FORCE_INLINE_ bool operator !=(const Span<LHS> &p_lhs, const Span<RHS> &p_rhs) {
233+ return !(p_lhs == p_rhs);
234+ }
235+
222236// Zero-constructing Span initializes _ptr and _len to 0 (and thus empty).
223237template <typename T>
224238struct is_zero_constructible <Span<T>> : std::true_type {};
0 commit comments