From 78221946cc826980214e241eedc2a626f9e7b463 Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Mon, 10 Mar 2025 18:55:09 +0100 Subject: [PATCH] Add C array constructor to `Span`. [skip ci] --- core/templates/span.h | 19 +++++++++++++++++++ tests/core/templates/test_span.h | 19 ++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/core/templates/span.h b/core/templates/span.h index c8f8591347..5aa9b3dab1 100644 --- a/core/templates/span.h +++ b/core/templates/span.h @@ -43,10 +43,29 @@ class Span { uint64_t _len = 0; public: + static constexpr bool is_string = std::disjunction_v< + std::is_same, + std::is_same, + std::is_same, + std::is_same + >; + _FORCE_INLINE_ constexpr Span() = default; _FORCE_INLINE_ constexpr Span(const T *p_ptr, uint64_t p_len) : _ptr(p_ptr), _len(p_len) {} + // Allows creating Span directly from C arrays and string literals. + template + _FORCE_INLINE_ constexpr Span(const T (&p_array)[N]) : + _ptr(p_array), _len(N) { + if constexpr (is_string) { + // Cut off the \0 terminator implicitly added to string literals. + if (N > 0 && p_array[N - 1] == '\0') { + _len--; + } + } + } + _FORCE_INLINE_ constexpr uint64_t size() const { return _len; } _FORCE_INLINE_ constexpr bool is_empty() const { return _len == 0; } diff --git a/tests/core/templates/test_span.h b/tests/core/templates/test_span.h index 94ce8183fa..9fe0b03058 100644 --- a/tests/core/templates/test_span.h +++ b/tests/core/templates/test_span.h @@ -48,17 +48,22 @@ TEST_CASE("[Span] Constexpr Validators") { static_assert(span_value.size() == 1); static_assert(!span_value.is_empty()); - constexpr static char32_t array[] = U"122345"; - constexpr Span span_array(array, strlen(array)); - static_assert(span_array.ptr() == &array[0]); + static constexpr int ints[] = { 0, 1, 2, 3, 4, 5 }; + constexpr Span span_array = ints; static_assert(span_array.size() == 6); static_assert(!span_array.is_empty()); - static_assert(span_array[0] == U'1'); - static_assert(span_array[span_array.size() - 1] == U'5'); + static_assert(span_array[0] == 0); + static_assert(span_array[span_array.size() - 1] == 5); + + constexpr Span span_string = U"122345"; + static_assert(span_string.size() == 6); + static_assert(!span_string.is_empty()); + static_assert(span_string[0] == U'1'); + static_assert(span_string[span_string.size() - 1] == U'5'); int idx = 0; - for (const char32_t &chr : span_array) { - CHECK_EQ(chr, span_array[idx++]); + for (const char32_t &chr : span_string) { + CHECK_EQ(chr, span_string[idx++]); } }