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 <sbergman@redhat.com>
diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx
index 091f224..aae291f 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 c4869f4..67275ee 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 ec0faec..8cfc3a6 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 0caa3fc..d2f471b 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);