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);

Reply via email to