summaryrefslogtreecommitdiff
path: root/include/rtl/stringutils.hxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2015-06-24 15:40:44 +0200
committerStephan Bergmann <sbergman@redhat.com>2015-06-24 15:48:21 +0200
commit4d4f3512db0cf0bf47c2ba1b39c3813842903ef7 (patch)
treed684cbc20bcff5071c0de27ec523b81f991e1823 /include/rtl/stringutils.hxx
parent892455e72a57d890918f37bd2b32d6c5000ba6ff (diff)
Generalize OUStringLiteral1
...by making all places that accept a string literal via ConstCharArrayDetector also accept an OUStringLiteral1 via ConstCharArrayDetector (which required some tweaking of the ConstCharArrayDetector internals). That removes the need for special-purpose OUStringLiteral1 overloads, and will allow OUStringLiteral1 to be used in more places. Change-Id: I370de8480e02f8423cde5677dd38479b81bccdb2
Diffstat (limited to 'include/rtl/stringutils.hxx')
-rw-r--r--include/rtl/stringutils.hxx80
1 files changed, 78 insertions, 2 deletions
diff --git a/include/rtl/stringutils.hxx b/include/rtl/stringutils.hxx
index fb11545569e4..32a57f399d24 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,27 @@ 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<OUStringLiteral1<C>, 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> & literal)
+ { return &literal.c; }
+};
+#endif
// this one is used to rule out only const char[N]
template< typename T >
@@ -137,6 +209,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