summaryrefslogtreecommitdiff
path: root/include/rtl/stringutils.hxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2015-06-25 10:15:34 +0200
committerStephan Bergmann <sbergman@redhat.com>2015-06-25 12:38:32 +0200
commit8007417c318140d74b87ec5abcf835f4a2ba9682 (patch)
tree0ea40500853d78008c0d1aa1083a0e415e457e9a /include/rtl/stringutils.hxx
parent707ef3171a096787b2f7a4c221e60962f05e7d01 (diff)
Revert "Revert "Generalize OUStringLiteral1""
This reverts commit 5cba714b4d03ed54debf71534ad8c8edc383a01e, now including a workaround for <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53658> "internal compiler error -- segmentation fault." Change-Id: I31f6d9ddcb0b884134703df2b9dc1800ba0a84be
Diffstat (limited to 'include/rtl/stringutils.hxx')
-rw-r--r--include/rtl/stringutils.hxx87
1 files changed, 85 insertions, 2 deletions
diff --git a/include/rtl/stringutils.hxx b/include/rtl/stringutils.hxx
index fb11545569e4..ff25d4d57b20 100644
--- a/include/rtl/stringutils.hxx
+++ b/include/rtl/stringutils.hxx
@@ -11,6 +11,10 @@
#define INCLUDED_RTL_STRINGUTILS_HXX
#include <sal/config.h>
+
+#include <cstddef>
+#include <cstring>
+
#include <sal/types.h>
// The unittest uses slightly different code to help check that the proper
@@ -29,6 +33,60 @@ namespace rtl
#undef rtl
#endif
+#if defined LIBO_INTERNAL_ONLY
+/// @cond INTERNAL
+
+/** A simple wrapper around an ASCII character literal.
+
+ Can be useful to pass a char constant with ASCII value into a
+ OUString-related function that is optimized for ASCII string literal
+ arguments. That is, instead of
+
+ char const WILDCARD = '%';
+ ...
+ if (s[i] == WILDCARD) ...
+ ...
+ if (s.endsWith(OUString(WILDCARD))) ...
+
+ use
+
+ char const WILDCARD = '%';
+ ...
+ if (s[i] == WILDCARD) ...
+ ...
+ if (s.endsWith(OUStringLiteral1<WILDCARD>())) ...
+
+ to avoid creating a temporary OUString instance, and instead pick the
+ endsWith overload actually designed to take an argument of type
+ char const[N].
+
+ Instances of OUStringLiteral1 need to be const, as those literal-optimized
+ functions take the literal argument by non-const lvalue reference, for
+ technical reasons. Except with MSVC, at least up to Visual Studio 2013:
+ For one, it fails to take that const-ness into account when trying to match
+ "OUStringLiteral1_<C> const" against T in a "T & literal" parameter of a
+ function template. But for another, as a language extension, it allows to
+ bind non-const temporary OUStringLiteral1_ instances to non-const lvalue
+ references, but also with a warning that thus needs to be disabled.
+
+ @since LibreOffice 5.0
+*/
+template<char C> struct SAL_WARN_UNUSED OUStringLiteral1_ {
+ static_assert(
+ static_cast<unsigned char>(C) < 0x80,
+ "non-ASCII character in OUStringLiteral1");
+ char const c = C;
+};
+#if defined _MSC_VER && _MSC_VER <= 1800 // Visual Studio 2013
+template<char C> using OUStringLiteral1 = OUStringLiteral1_<C>;
+#pragma warning(disable: 4239)
+#else
+template<char C> using OUStringLiteral1 = OUStringLiteral1_<C> const;
+#endif
+
+/// @endcond
+#endif
+
namespace libreoffice_internal
{
/*
@@ -102,13 +160,34 @@ struct ConstCharArrayDetector
{
static const bool ok = false;
};
-template< int N, typename T >
+template< std::size_t N, typename T >
struct ConstCharArrayDetector< const char[ N ], T >
{
typedef T Type;
- static const int size = N;
+ static const std::size_t length = N - 1;
static const bool ok = true;
+ static bool isValid(char const (& literal)[N])
+ { return std::strlen(literal) == length; }
+ static char const * toPointer(char const (& literal)[N]) { return literal; }
};
+#if defined LIBO_INTERNAL_ONLY
+template<char C, typename T> struct ConstCharArrayDetector<
+#if defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ <= 8 \
+ && !defined __clang__
+ OUStringLiteral1_<C> const,
+#else
+ OUStringLiteral1<C>,
+#endif
+ T>
+{
+ typedef T Type;
+ static const std::size_t length = 1;
+ static const bool ok = true;
+ static bool isValid(OUStringLiteral1_<C>) { return true; }
+ static char const * toPointer(OUStringLiteral1_<C> const & literal)
+ { return &literal.c; }
+};
+#endif
// this one is used to rule out only const char[N]
template< typename T >
@@ -137,6 +216,10 @@ template< int N >
struct ExceptCharArrayDetector< const char[ N ] >
{
};
+#if defined LIBO_INTERNAL_ONLY && defined _MSC_VER && _MSC_VER <= 1800
+ // Visual Studio 2013
+template<char C> struct ExceptCharArrayDetector<OUStringLiteral1<C>> {};
+#endif
template< typename T1, typename T2 = void >
struct SalUnicodePtrDetector