diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx index fd65e2dfa477..d9422c696059 100644 --- a/include/rtl/string.hxx +++ b/include/rtl/string.hxx @@ -90,6 +90,7 @@ public: constexpr #endif explicit OStringLiteral(char const (&literal)[N]) { + assertLayout(); assert(literal[N - 1] == '\0'); //TODO: Use C++20 constexpr std::copy_n (P0202R3): for (std::size_t i = 0; i != N; ++i) { @@ -104,6 +105,7 @@ public: constexpr #endif explicit OStringLiteral(char8_t const (&literal)[N]) { + assertLayout(); assert(literal[N - 1] == '\0'); //TODO: Use C++20 constexpr std::copy_n (P0202R3): for (std::size_t i = 0; i != N; ++i) { @@ -116,10 +118,10 @@ public: constexpr char const * getStr() const SAL_RETURNS_NONNULL { return buffer; } - // offsetof needs a complete type, so do not have these static_asserts as class template - // members, but postpone their instantiation to the later non-member static_assert that calls - // detail_assertLayout: - static constexpr bool detail_assertLayout() { +private: + static constexpr void assertLayout() { + // These static_asserts verifying the layout compatibility with rtl_String cannot be class + // member declarations, as offsetof requires a complete type, so defer them to here: static_assert(offsetof(OStringLiteral, refCount) == offsetof(rtl_String, refCount)); static_assert( std::is_same_v); @@ -130,17 +132,13 @@ public: std::is_same_v< std::remove_extent_t, std::remove_extent_t>); - return true; } -private: // Same layout as rtl_String (include/rtl/string.h): oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx) sal_Int32 length = N - 1; char buffer[N] = {}; //TODO: drop initialization for C++20 (P1331R2) }; - -static_assert(OStringLiteral<1>::detail_assertLayout()); #endif /* ======================================================================= */ diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx index f458ac061ea4..707bbf6e66d6 100644 --- a/include/rtl/ustring.hxx +++ b/include/rtl/ustring.hxx @@ -87,6 +87,7 @@ public: constexpr #endif OUStringLiteral(char16_t const (&literal)[N]) { + assertLayout(); assert(literal[N - 1] == '\0'); //TODO: Use C++20 constexpr std::copy_n (P0202R3): for (std::size_t i = 0; i != N; ++i) { @@ -100,10 +101,10 @@ public: constexpr operator std::u16string_view() const { return {buffer, sal_uInt32(length)}; } - // offsetof needs a complete type, so do not have these static_asserts as class template - // members, but postpone their instantiation to the later non-member static_assert that calls - // detail_assertLayout: - static constexpr bool detail_assertLayout() { +private: + static constexpr void assertLayout() { + // These static_asserts verifying the layout compatibility with rtl_uString cannot be class + // member declarations, as offsetof requires a complete type, so defer them to here: static_assert(offsetof(OUStringLiteral, refCount) == offsetof(rtl_uString, refCount)); static_assert(std::is_same_v); static_assert(offsetof(OUStringLiteral, length) == offsetof(rtl_uString, length)); @@ -113,18 +114,14 @@ public: std::is_same_v< std::remove_extent_t, std::remove_extent_t>); - return true; } -private: // Same layout as rtl_uString (include/rtl/ustring.h): oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx) sal_Int32 length = N - 1; sal_Unicode buffer[N] = {}; //TODO: drop initialization for C++20 (P1331R2) }; -static_assert(OUStringLiteral<1>::detail_assertLayout()); - #if defined RTL_STRING_UNITTEST namespace libreoffice_internal { template struct ExceptConstCharArrayDetector> {};