include/rtl/string.hxx | 41 +++++++++++++++++++- include/rtl/ustring.hxx | 41 +++++++++++++++++++- sal/qa/rtl/strings/test_ostring_stringliterals.cxx | 10 ++++ sal/qa/rtl/strings/test_oustring_stringliterals.cxx | 10 ++++ 4 files changed, 98 insertions(+), 4 deletions(-)
New commits: commit 27d1f3ac016d77d3c907cebedca558308f366855 Author: Stephan Bergmann <[email protected]> AuthorDate: Fri Jul 14 09:36:59 2023 +0200 Commit: Stephan Bergmann <[email protected]> CommitDate: Fri Jul 14 13:32:46 2023 +0200 O[U]String literals (unusable for now, C++20 only) Change-Id: I0ecd1a8b60a01aefdf0139e3777dc006532764fd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154434 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx index 091f224b25d6..aae291f46053 100644 --- a/include/rtl/string.hxx +++ b/include/rtl/string.hxx @@ -88,8 +88,6 @@ This class is not part of public API and is meant to be used only in LibreOffice template<std::size_t N> class SAL_WARN_UNUSED OStringLiteral { static_assert(N != 0); static_assert(N - 1 <= std::numeric_limits<sal_Int32>::max(), "literal too long"); - friend class OString; - friend class OStringConstExpr; public: #if HAVE_CPP_CONSTEVAL @@ -146,6 +144,9 @@ private: char buffer[N] = {}; //TODO: drop initialization for C++20 (P1331R2) }; +public: + // (Data members must be public so that OStringLiteral is a structural type that can be used as + // a non-type template parameter type for rtl::detail::OStringHolder:) union { rtl_String str; Data more = {}; @@ -2274,6 +2275,18 @@ inline bool operator !=(StringConcatenation<char> const & lhs, OString const & r #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING" +#if __cplusplus >= 202002L + +namespace detail { + +template<OStringLiteral L> struct OStringHolder { + static constexpr auto & literal = L; +}; + +} + +#endif + /** @internal */ @@ -2374,6 +2387,30 @@ using ::rtl::OStringHash; using ::rtl::OStringLiteral; #endif +#if defined LIBO_INTERNAL_ONLY && __cplusplus >= 202002L + +template< +#if defined RTL_STRING_UNITTEST + rtlunittest:: +#endif + OStringLiteral L> +constexpr +#if defined RTL_STRING_UNITTEST + rtlunittest:: +#endif + OString +operator ""_ostr() { + return +#if defined RTL_STRING_UNITTEST + rtlunittest +#else + rtl +#endif + ::detail::OStringHolder<L>::literal; +} + +#endif + /// @cond INTERNAL /** Make OString hashable by default for use in STL containers. diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx index c4869f43a8f0..67275ee07932 100644 --- a/include/rtl/ustring.hxx +++ b/include/rtl/ustring.hxx @@ -86,8 +86,6 @@ This class is not part of public API and is meant to be used only in LibreOffice template<std::size_t N> class SAL_WARN_UNUSED OUStringLiteral { static_assert(N != 0); static_assert(N - 1 <= std::numeric_limits<sal_Int32>::max(), "literal too long"); - friend class OUString; - friend class OUStringConstExpr; public: #if HAVE_CPP_CONSTEVAL @@ -128,6 +126,9 @@ private: sal_Unicode buffer[N] = {}; //TODO: drop initialization for C++20 (P1331R2) }; +public: + // (Data members must be public so that OUStringLiteral is a structural type that can be used as + // a non-type template parameter type for rtl::detail::OUStringHolder:) union { rtl_uString str; Data more = {}; @@ -3413,6 +3414,18 @@ inline bool operator !=(StringConcatenation<char16_t> const & lhs, OUString cons #if defined LIBO_INTERNAL_ONLY // "RTL_FAST_STRING" /// @cond INTERNAL +#if __cplusplus >= 202002L + +namespace detail { + +template<OUStringLiteral L> struct OUStringHolder { + static constexpr auto & literal = L; +}; + +} + +#endif + /** @internal */ @@ -3576,6 +3589,30 @@ using ::rtl::OUStringChar; using ::rtl::Concat2View; #endif +#if defined LIBO_INTERNAL_ONLY && __cplusplus >= 202002L + +template< +#if defined RTL_STRING_UNITTEST + rtlunittest:: +#endif + OUStringLiteral L> +constexpr +#if defined RTL_STRING_UNITTEST + rtlunittest:: +#endif + OUString +operator ""_ostr() { + return +#if defined RTL_STRING_UNITTEST + rtlunittest +#else + rtl +#endif + ::detail::OUStringHolder<L>::literal; +} + +#endif + /// @cond INTERNAL /** Make OUString hashable by default for use in STL containers. diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx index ec0faec94f18..8cfc3a65bdde 100644 --- a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx +++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx @@ -31,6 +31,7 @@ private: void checkUsage(); void checkNonConstUsage(); void checkBuffer(); + void checkOstr(); void testcall( const char str[] ); @@ -46,6 +47,7 @@ CPPUNIT_TEST(checkConstexprCtor); CPPUNIT_TEST(checkUsage); CPPUNIT_TEST(checkNonConstUsage); CPPUNIT_TEST(checkBuffer); +CPPUNIT_TEST(checkOstr); CPPUNIT_TEST_SUITE_END(); }; @@ -273,6 +275,14 @@ void test::ostring::StringLiterals::checkBuffer() CPPUNIT_ASSERT( !rtl_string_unittest_const_literal_function ); } +void test::ostring::StringLiterals::checkOstr() { +#if __cplusplus >= 202002L + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), ""_ostr.getLength()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(6), "foobar"_ostr.getLength()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7), "foo\0bar"_ostr.getLength()); +#endif +} + #undef CONST_CTOR_USED } // namespace diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx index 0caa3fc03579..d2f471ba61fc 100644 --- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx +++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx @@ -41,6 +41,7 @@ private: void checkOUStringChar(); void checkUtf16(); void checkEmbeddedNul(); + void checkOstr(); void testcall( const char str[] ); @@ -56,6 +57,7 @@ CPPUNIT_TEST(checkOUStringLiteral); CPPUNIT_TEST(checkOUStringChar); CPPUNIT_TEST(checkUtf16); CPPUNIT_TEST(checkEmbeddedNul); +CPPUNIT_TEST(checkOstr); CPPUNIT_TEST_SUITE_END(); }; @@ -425,6 +427,14 @@ void test::oustring::StringLiterals::checkEmbeddedNul() { /*TODO*/ } +void test::oustring::StringLiterals::checkOstr() { +#if __cplusplus >= 202002L + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), u""_ostr.getLength()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(6), u"foobar"_ostr.getLength()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7), u"foo\0bar"_ostr.getLength()); +#endif +} + } // namespace CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::StringLiterals);
