diff --git a/src/lib/support/Span.h b/src/lib/support/Span.h index 4d8f521eb35c0c..854ee34d1a410f 100644 --- a/src/lib/support/Span.h +++ b/src/lib/support/Span.h @@ -38,7 +38,8 @@ template class Span { public: - using pointer = T *; + using pointer = T *; + using reference = T &; constexpr Span() : mDataBuf(nullptr), mDataLen(0) {} constexpr Span(pointer databuf, size_t datalen) : mDataBuf(databuf), mDataLen(datalen) {} @@ -75,6 +76,18 @@ class Span constexpr pointer begin() const { return data(); } constexpr pointer end() const { return data() + size(); } + // Element accessors, matching the std::span API. + // VerifyOrDie cannot be used inside a constexpr function, because it uses + // "static" on some platforms (e.g. when CHIP_PW_TOKENIZER_LOGGING is true) + // and that's not allowed in constexpr functions. + reference operator[](size_t index) const + { + VerifyOrDie(index < size()); + return data()[index]; + } + reference front() const { return (*this)[0]; } + reference back() const { return (*this)[size() - 1]; } + template , std::remove_const_t>::value>> bool data_equal(const Span & other) const { @@ -142,7 +155,8 @@ template class FixedSpan { public: - using pointer = T *; + using pointer = T *; + using reference = T &; constexpr FixedSpan() : mDataBuf(nullptr) {} @@ -188,6 +202,18 @@ class FixedSpan constexpr pointer begin() const { return mDataBuf; } constexpr pointer end() const { return mDataBuf + N; } + // Element accessors, matching the std::span API. + // VerifyOrDie cannot be used inside a constexpr function, because it uses + // "static" on some platforms (e.g. when CHIP_PW_TOKENIZER_LOGGING is true) + // and that's not allowed in constexpr functions. + reference operator[](size_t index) const + { + VerifyOrDie(index < size()); + return data()[index]; + } + 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 , std::remove_const_t>::value>> bool data_equal(const FixedSpan & other) const diff --git a/src/lib/support/tests/TestSpan.cpp b/src/lib/support/tests/TestSpan.cpp index 06a9a57070bc02..689226225121be 100644 --- a/src/lib/support/tests/TestSpan.cpp +++ b/src/lib/support/tests/TestSpan.cpp @@ -56,6 +56,11 @@ static void TestByteSpan(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, s2.data_equal(s2)); NL_TEST_ASSERT(inSuite, !s2.data_equal(s1)); NL_TEST_ASSERT(inSuite, IsSpanUsable(s2) == true); + NL_TEST_ASSERT(inSuite, s2.front() == 1); + NL_TEST_ASSERT(inSuite, s2.back() == 3); + NL_TEST_ASSERT(inSuite, s2[0] == 1); + NL_TEST_ASSERT(inSuite, s2[1] == 2); + NL_TEST_ASSERT(inSuite, s2[2] == 3); ByteSpan s3 = s2; NL_TEST_ASSERT(inSuite, s3.data() == arr); @@ -175,6 +180,11 @@ static void TestFixedByteSpan(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, s2.data()[2] == 3); NL_TEST_ASSERT(inSuite, !s2.empty()); NL_TEST_ASSERT(inSuite, s2.data_equal(s2)); + NL_TEST_ASSERT(inSuite, s2.front() == 1); + NL_TEST_ASSERT(inSuite, s2.back() == 3); + NL_TEST_ASSERT(inSuite, s2[0] == 1); + NL_TEST_ASSERT(inSuite, s2[1] == 2); + NL_TEST_ASSERT(inSuite, s2[2] == 3); FixedByteSpan<3> s3 = s2; NL_TEST_ASSERT(inSuite, s3.data() == arr);