diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2015-06-24 15:40:44 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2015-06-24 15:48:21 +0200 |
commit | 4d4f3512db0cf0bf47c2ba1b39c3813842903ef7 (patch) | |
tree | d684cbc20bcff5071c0de27ec523b81f991e1823 /include/rtl/stringutils.hxx | |
parent | 892455e72a57d890918f37bd2b32d6c5000ba6ff (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.hxx | 80 |
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 |