author | Henri Sivonen <hsivonen@hsivonen.fi> |
Sat, 24 Mar 2018 21:36:00 +0200 | |
changeset 411557 | 1fb1569b61d292785497c3f662b8a387c638695a |
parent 411556 | e220521c6ff6ff9a45e19b3917ba95e678fd9932 |
child 411558 | b4f0025c830369df929c2557390e5289affc13fc |
push id | 101686 |
push user | aciure@mozilla.com |
push date | Tue, 03 Apr 2018 21:59:31 +0000 |
treeherder | mozilla-inbound@8d846598d35d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | froydnj |
bugs | 1448591 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
mfbt/Span.h | file | annotate | diff | comparison | revisions | |
mfbt/tests/gtest/TestSpan.cpp | file | annotate | diff | comparison | revisions |
--- a/mfbt/Span.h +++ b/mfbt/Span.h @@ -407,17 +407,18 @@ private: * * In addition to having constructors and MakeSpan() functions that take * various well-known types, a Span for an arbitrary type can be constructed * (via constructor or MakeSpan()) from a pointer and a length or a pointer * and another pointer pointing just past the last element. * * A Span<const char> or Span<const char16_t> can be obtained for const char* * or const char16_t pointing to a zero-terminated string using the - * MakeStringSpan() function. Corresponding implicit constructor does not exist + * MakeStringSpan() function (which treats a nullptr argument equivalently + * to the empty string). Corresponding implicit constructor does not exist * in order to avoid accidental construction in cases where const char* or * const char16_t* do not point to a zero-terminated string. * * Span has methods that follow the Mozilla naming style and methods that * don't. The methods that follow the Mozilla naming style are meant to be * used directly from Mozilla code. The methods that don't are meant for * integration with C++11 range-based loops and with meta-programming that * expects the same methods that are found on the standard-library @@ -1056,30 +1057,38 @@ MakeSpan(const Container& cont) template<class Ptr> Span<typename Ptr::element_type> MakeSpan(Ptr& aPtr, size_t aLength) { return Span<typename Ptr::element_type>(aPtr, aLength); } /** - * Create span from C string. + * Create span from a zero-terminated C string. nullptr is + * treated as the empty string. */ inline Span<const char> MakeStringSpan(const char* aZeroTerminated) { + if (!aZeroTerminated) { + return Span<const char>(); + } return Span<const char>(aZeroTerminated, std::strlen(aZeroTerminated)); } /** - * Create span from UTF-16 C string. + * Create span from a zero-terminated UTF-16 C string. nullptr is + * treated as the empty string. */ inline Span<const char16_t> MakeStringSpan(const char16_t* aZeroTerminated) { + if (!aZeroTerminated) { + return Span<const char16_t>(); + } return Span<const char16_t>(aZeroTerminated, span_details::strlen16(aZeroTerminated)); } } // namespace mozilla #ifdef _MSC_VER #if _MSC_VER < 1910 #undef constexpr
--- a/mfbt/tests/gtest/TestSpan.cpp +++ b/mfbt/tests/gtest/TestSpan.cpp @@ -1190,16 +1190,21 @@ SPAN_TEST(from_xpcom_collections) ASSERT_EQ(s.data(), v.Elements()); ASSERT_EQ(s[2], 3); } } SPAN_TEST(from_cstring) { { + const char* str = nullptr; + auto cs = MakeStringSpan(str); + ASSERT_EQ(cs.size(), 0U); + } + { const char* str = "abc"; auto cs = MakeStringSpan(str); ASSERT_EQ(cs.size(), 3U); ASSERT_EQ(cs.data(), str); ASSERT_EQ(cs[2], 'c'); #ifdef CONFIRM_COMPILATION_ERRORS @@ -1229,16 +1234,21 @@ SPAN_TEST(from_cstring) Span<char> scca(arr); // error Span<const char> sccca(arr); // error Span<const char> scccea; scccea = arr; // error #endif } { + const char16_t* str = nullptr; + auto cs = MakeStringSpan(str); + ASSERT_EQ(cs.size(), 0U); + } + { char16_t arr[4] = {'a', 'b', 'c', 0}; const char16_t* str = arr; auto cs = MakeStringSpan(str); ASSERT_EQ(cs.size(), 3U); ASSERT_EQ(cs.data(), str); ASSERT_EQ(cs[2], 'c');