summaryrefslogtreecommitdiffstats
path: root/include/rtl
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2021-09-30 13:54:26 +0200
committerStephan Bergmann <sbergman@redhat.com>2021-10-03 19:50:44 +0200
commitad1557f5d775739230e0e2252c293948977b42a0 (patch)
tree610e2e849d87583888c0c658088044d6dc3966a5 /include/rtl
parentdrop 'using namespace std' in desktop, e*, f* (diff)
downloadcore-ad1557f5d775739230e0e2252c293948977b42a0.tar.gz
core-ad1557f5d775739230e0e2252c293948977b42a0.zip
A more lightweight O[U]StringConcatenation
...compared to a full-blown O[U]String, for temporary objects holding an O[U]StringConcat result that can then be used as a std::[u16]string_view. It's instructive to see how some invocations of operator ==, operator !=, and O[U]StringBuffer::insert with an O[U]StringConcat argument required implicit materialization of an O[U]String temporary, and how that expensive operation has now been made explicit with the explicit O[U]StringConcatenation ctor. (The additional operator == and operator != overloads are necessary because the overloads taking two std::[u16]string_view parameters wouldn't even be found here with ADL. And the OUString-related ones would cause ambiguities in at least sal/qa/rtl/strings/test_oustring_stringliterals.cxx built with RTL_STRING_UNITTEST, so have simply been disabled for that special test-code case.) Change-Id: Id29799fa8da21a09ff9794cbc7cc9b366e6803b8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122890 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'include/rtl')
-rw-r--r--include/rtl/string.hxx12
-rw-r--r--include/rtl/stringconcat.hxx42
-rw-r--r--include/rtl/ustring.hxx12
3 files changed, 66 insertions, 0 deletions
diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx
index 1f3120e7b4e5..cebaa114517d 100644
--- a/include/rtl/string.hxx
+++ b/include/rtl/string.hxx
@@ -2146,6 +2146,17 @@ public:
#endif
};
+#if defined LIBO_INTERNAL_ONLY
+inline bool operator ==(OString const & lhs, OStringConcatenation const & rhs)
+{ return lhs == std::string_view(rhs); }
+inline bool operator !=(OString const & lhs, OStringConcatenation const & rhs)
+{ return lhs != std::string_view(rhs); }
+inline bool operator ==(OStringConcatenation const & lhs, OString const & rhs)
+{ return std::string_view(lhs) == rhs; }
+inline bool operator !=(OStringConcatenation const & lhs, OString const & rhs)
+{ return std::string_view(lhs) != rhs; }
+#endif
+
/* ======================================================================= */
#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
@@ -2249,6 +2260,7 @@ typedef rtlunittest::OString OString;
#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
using ::rtl::OString;
using ::rtl::OStringChar;
+using ::rtl::OStringConcatenation;
using ::rtl::OStringHash;
using ::rtl::OStringLiteral;
#endif
diff --git a/include/rtl/stringconcat.hxx b/include/rtl/stringconcat.hxx
index 554fdd3f4403..51605d0731e9 100644
--- a/include/rtl/stringconcat.hxx
+++ b/include/rtl/stringconcat.hxx
@@ -16,7 +16,9 @@
#include "rtl/string.h"
#include "rtl/ustring.h"
+#include <cassert>
#include <cstddef>
+#include <memory>
#include <string>
#include <string_view>
#include <type_traits>
@@ -353,6 +355,46 @@ int operator+( const StringConcatInvalid&, const T& )
}
#endif
+// Lightweight alternative to OString when a (temporary) object is needed to hold an OStringConcat
+// result that can then be used as a std::string_view:
+class OStringConcatenation {
+public:
+ template<typename T1, typename T2>
+ explicit OStringConcatenation(OStringConcat<T1, T2> const & c):
+ length_(c.length()),
+ buffer_(new char[length_])
+ {
+ auto const end = c.addData(buffer_.get());
+ assert(end == buffer_.get() + length_); (void)end;
+ }
+
+ operator std::string_view() const { return {buffer_.get(), length_}; }
+
+private:
+ std::size_t length_;
+ std::unique_ptr<char[]> buffer_;
+};
+
+// Lightweight alternative to OUString when a (temporary) object is needed to hold an
+// OUStringConcat result that can then be used as a std::u16string_view:
+class OUStringConcatenation {
+public:
+ template<typename T1, typename T2>
+ explicit OUStringConcatenation(OUStringConcat<T1, T2> const & c):
+ length_(c.length()),
+ buffer_(new char16_t[length_])
+ {
+ auto const end = c.addData(buffer_.get());
+ assert(end == buffer_.get() + length_); (void)end;
+ }
+
+ operator std::u16string_view() const { return {buffer_.get(), length_}; }
+
+private:
+ std::size_t length_;
+ std::unique_ptr<char16_t[]> buffer_;
+};
+
/**
@internal
diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx
index 96bb504f77a8..5fbf00d64a6d 100644
--- a/include/rtl/ustring.hxx
+++ b/include/rtl/ustring.hxx
@@ -3393,6 +3393,17 @@ void operator !=(OUString const &, std::nullptr_t) = delete;
void operator !=(std::nullptr_t, OUString const &) = delete;
#endif
+#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
+inline bool operator ==(OUString const & lhs, OUStringConcatenation const & rhs)
+{ return lhs == std::u16string_view(rhs); }
+inline bool operator !=(OUString const & lhs, OUStringConcatenation const & rhs)
+{ return lhs != std::u16string_view(rhs); }
+inline bool operator ==(OUStringConcatenation const & lhs, OUString const & rhs)
+{ return std::u16string_view(lhs) == rhs; }
+inline bool operator !=(OUStringConcatenation const & lhs, OUString const & rhs)
+{ return std::u16string_view(lhs) != rhs; }
+#endif
+
#if defined LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
/// @cond INTERNAL
@@ -3560,6 +3571,7 @@ using ::rtl::OStringToOUString;
using ::rtl::OUStringToOString;
using ::rtl::OUStringLiteral;
using ::rtl::OUStringChar;
+using ::rtl::OUStringConcatenation;
#endif
/// @cond INTERNAL