Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/rtl/stringutils.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 */
9
10
/*
11
 * This file is part of LibreOffice published API.
12
 */
13
14
#ifndef INCLUDED_RTL_STRINGUTILS_HXX
15
#define INCLUDED_RTL_STRINGUTILS_HXX
16
17
#include "sal/config.h"
18
19
#include <cassert>
20
#include <cstddef>
21
22
#if defined LIBO_INTERNAL_ONLY
23
#include <limits>
24
#include <new>
25
#include <type_traits>
26
#endif
27
28
#include "sal/types.h"
29
30
// The unittest uses slightly different code to help check that the proper
31
// calls are made. The class is put into a different namespace to make
32
// sure the compiler generates a different (if generating also non-inline)
33
// copy of the function and does not merge them together. The class
34
// is "brought" into the proper rtl namespace by a typedef below.
35
#ifdef RTL_STRING_UNITTEST
36
#define rtl rtlunittest
37
#endif
38
39
namespace rtl
40
{
41
42
#ifdef RTL_STRING_UNITTEST
43
#undef rtl
44
#endif
45
46
#if defined LIBO_INTERNAL_ONLY
47
/// @cond INTERNAL
48
49
// A simple wrapper around a single char.  Can be useful in string concatenation contexts, like in
50
//
51
//  OString s = ...;
52
//  char c = ...;
53
//  s += OStringChar(c);
54
//
55
struct SAL_WARN_UNUSED OStringChar {
56
2.34M
    constexpr OStringChar(char theC): c(theC) {}
57
    template<typename T> OStringChar(
58
        T, std::enable_if_t<std::is_arithmetic_v<T> || std::is_enum_v<T>, int> = 0) = delete;
59
2.17M
    constexpr operator std::string_view() const { return {&c, 1}; }
60
    char const c;
61
};
62
63
/** A simple wrapper around a single sal_Unicode character.
64
65
    Can be useful to pass a sal_Unicode constant into an OUString-related
66
    function that is optimized for UTF-16 string literal arguments.  That is,
67
    instead of
68
69
      sal_Unicode const WILDCARD = '%';
70
      ...
71
      if (s[i] == WILDCARD) ...
72
      ...
73
      if (s.endsWith(OUString(WILDCARD))) ...
74
75
    use
76
77
      sal_Unicode const WILDCARD = '%';
78
      ...
79
      if (s[i] == WILDCARD) ...
80
      ...
81
      if (s.endsWith(OUStringChar(WILDCARD))) ...
82
83
    to avoid creating a temporary OUString instance, and instead pick the
84
    endsWith overload actually designed to take an argument of type
85
    sal_Unicode const[N].
86
87
    (Because of the above use case,
88
    instances of OUStringChar need to be const, as those literal-optimized
89
    functions take the literal argument by non-const lvalue reference, for
90
    technical reasons.
91
92
    For actual arrays, it is important to distinguish string literals from other char or sal_Unicode
93
    arrays, which may contain junk after the first NUL character or may be non-ASCII in the case of
94
    char arrays.  This is not so much a concern for single char and sal_Unicode values, where NUL is
95
    assumed to always be meant as an actual character.)
96
97
    Can also be useful in string concatenation contexts, like in
98
99
      sal_Unicode const * s = ...;
100
      sal_Unicode c = ...;
101
      OUString t = s + OUStringChar(c);
102
103
    @since LibreOffice 5.0
104
*/
105
struct SAL_WARN_UNUSED OUStringChar_ {
106
165M
    constexpr OUStringChar_(sal_Unicode theC): c(theC) {}
107
1.33M
    constexpr OUStringChar_(char theC): c(theC) { assert(c <= 0x7F); }
108
    template<typename T> OUStringChar_(
109
        T, std::enable_if_t<std::is_arithmetic_v<T> || std::is_enum_v<T>, int> = 0) = delete;
110
4.56k
    constexpr operator std::u16string_view() const { return {&c, 1}; }
111
    sal_Unicode const c;
112
};
113
using OUStringChar = OUStringChar_ const;
114
115
/// @endcond
116
#endif
117
118
namespace libreoffice_internal
119
{
120
#if defined LIBO_INTERNAL_ONLY
121
template <typename I, std::enable_if_t<
122
    std::is_integral_v<I> && std::is_signed_v<I>,
123
    int> = 0>
124
constexpr bool IsValidStrLen(I i, sal_Int32 margin = 0)
125
{
126
    assert(margin >= 0);
127
    constexpr sal_uInt32 maxLen = std::numeric_limits<sal_Int32>::max();
128
    return i >= 0 && static_cast<std::make_unsigned_t<I>>(i) <= maxLen - margin;
129
}
130
131
template <typename I, std::enable_if_t<
132
    std::is_integral_v<I> && std::is_unsigned_v<I>,
133
    int> = 0>
134
constexpr bool IsValidStrLen(I i, sal_Int32 margin = 0)
135
102M
{
136
102M
    assert(margin >= 0);
137
102M
    constexpr sal_uInt32 maxLen = std::numeric_limits<sal_Int32>::max();
138
102M
    return i <= maxLen - margin;
139
102M
}
140
141
template <typename I, std::enable_if_t<std::is_integral_v<I>, int> = 0>
142
sal_Int32 ThrowIfInvalidStrLen(I i, sal_Int32 margin = 0)
143
102M
{
144
102M
    if (!IsValidStrLen(i, margin))
145
0
        throw std::bad_alloc();
146
102M
    return i;
147
102M
}
148
#endif
149
150
/*
151
These templates use SFINAE (Substitution failure is not an error) to help distinguish the various
152
plain C string types: char*, const char*, char[N], const char[N], char[] and const char[].
153
There are 2 cases:
154
1) Only string literal (i.e. const char[N]) is wanted, not any of the others.
155
    In this case it is necessary to distinguish between const char[N] and char[N], as the latter
156
    would be automatically converted to the const variant, which is not wanted (not a string literal
157
    with known size of the content). In this case ConstCharArrayDetector is used to ensure the function
158
    is called only with const char[N] arguments. There's no other plain C string type overload.
159
    (Note that OUStringChar is also covered by ConstCharArrayDetector's TypeUtf16 check, but
160
    provides a pointer to a string that is not NUL-terminated, unlike the char16_t const[N] arrays
161
    normally covered by that check, and which are assumed to represent NUL-terminated string
162
    literals.)
163
2) All plain C string types are wanted, and const char[N] needs to be handled differently.
164
    In this case const char[N] would match const char* argument type (not exactly sure why, but it's
165
    consistent in all of gcc, clang and msvc). Using a template with a reference to const of the type
166
    avoids this problem, and CharPtrDetector ensures that the function is called only with char pointer
167
    arguments. The const in the argument is necessary to handle the case when something is explicitly
168
    cast to const char*. Additionally (non-const) char[N] needs to be handled, but with the reference
169
    being const, it would also match const char[N], so another overload with a reference to non-const
170
    and NonConstCharArrayDetector are used to ensure the function is called only with (non-const) char[N].
171
Additionally, char[] and const char[] (i.e. size unknown) are rather tricky. Their usage with 'T&' would
172
mean it would be 'char(&)[]', which seems to be invalid. But gcc and clang somehow manage when it is
173
a template. while msvc complains about no conversion from char[] to char[1]. And the reference cannot
174
be avoided, because 'const char[]' as argument type would match also 'const char[N]'
175
So char[] and const char[] should always be used with their contents specified (which automatically
176
turns them into char[N] or const char[N]), or char* and const char* should be used.
177
*/
178
struct Dummy {};
179
template< typename T1, typename T2 = void >
180
struct CharPtrDetector
181
{
182
    static const bool ok = false;
183
};
184
template< typename T >
185
struct CharPtrDetector< const char*, T >
186
{
187
    typedef T Type;
188
    static const bool ok = true;
189
};
190
template< typename T >
191
struct CharPtrDetector< char*, T >
192
{
193
    typedef T Type;
194
    static const bool ok = true;
195
};
196
#if defined LIBO_INTERNAL_ONLY
197
template<typename T> struct CharPtrDetector<sal_Unicode *, T> { using TypeUtf16 = T; };
198
template<typename T> struct CharPtrDetector<sal_Unicode const *, T> { using TypeUtf16 = T; };
199
template<typename T> struct CharPtrDetector<sal_Unicode[], T> { using TypeUtf16 = T; };
200
template<typename T> struct CharPtrDetector<sal_Unicode const[], T> { using TypeUtf16 = T; };
201
#endif
202
203
template< typename T1, typename T2 >
204
struct NonConstCharArrayDetector
205
{
206
};
207
template< typename T, int N >
208
struct NonConstCharArrayDetector< char[ N ], T >
209
{
210
    typedef T Type;
211
};
212
#ifdef RTL_STRING_UNITTEST
213
// never use, until all compilers handle this
214
template< typename T >
215
struct NonConstCharArrayDetector< char[], T >
216
{
217
    typedef T Type;
218
};
219
template< typename T >
220
struct NonConstCharArrayDetector< const char[], T >
221
{
222
    typedef T Type;
223
};
224
#endif
225
#if defined LIBO_INTERNAL_ONLY
226
template<typename T, std::size_t N> struct NonConstCharArrayDetector<sal_Unicode[N], T> {
227
    using TypeUtf16 = T;
228
};
229
#endif
230
231
template< typename T1, typename T2 = void >
232
struct ConstCharArrayDetector
233
{
234
    static const bool ok = false;
235
};
236
template< std::size_t N, typename T >
237
struct ConstCharArrayDetector< const char[ N ], T >
238
{
239
    typedef T Type;
240
    static const std::size_t length = N - 1;
241
    static const bool ok = true;
242
#if defined LIBO_INTERNAL_ONLY
243
    constexpr
244
#endif
245
    static bool isValid(char const (& literal)[N]) {
246
        for (std::size_t i = 0; i != N - 1; ++i) {
247
            if (literal[i] == '\0') {
248
                return false;
249
            }
250
        }
251
        return literal[N - 1] == '\0';
252
    }
253
#if defined LIBO_INTERNAL_ONLY
254
    constexpr
255
#endif
256
1.07G
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [32], void>::toPointer(char const (&) [32])
Line
Count
Source
256
835k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [40], void>::toPointer(char const (&) [40])
Line
Count
Source
256
642k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [7], void>::toPointer(char const (&) [7])
Line
Count
Source
256
7.48M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [62], void>::toPointer(char const (&) [62])
Line
Count
Source
256
555
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [15], void>::toPointer(char const (&) [15])
Line
Count
Source
256
9.21M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [39], void>::toPointer(char const (&) [39])
Line
Count
Source
256
74.4k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [18], void>::toPointer(char const (&) [18])
Line
Count
Source
256
555k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [27], void>::toPointer(char const (&) [27])
Line
Count
Source
256
494k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [34], void>::toPointer(char const (&) [34])
Line
Count
Source
256
781k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [28], void>::toPointer(char const (&) [28])
Line
Count
Source
256
522M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [55], void>::toPointer(char const (&) [55])
Line
Count
Source
256
14.3k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [17], void>::toPointer(char const (&) [17])
Line
Count
Source
256
5.86M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [10], void>::toPointer(char const (&) [10])
Line
Count
Source
256
3.53M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [6], void>::toPointer(char const (&) [6])
Line
Count
Source
256
7.97M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [68], void>::toPointer(char const (&) [68])
Line
Count
Source
256
9.10k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [9], void>::toPointer(char const (&) [9])
Line
Count
Source
256
9.65M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [65], void>::toPointer(char const (&) [65])
Line
Count
Source
256
490
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [20], void>::toPointer(char const (&) [20])
Line
Count
Source
256
1.76M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [41], void>::toPointer(char const (&) [41])
Line
Count
Source
256
132k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [80], void>::toPointer(char const (&) [80])
Line
Count
Source
256
198
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [67], void>::toPointer(char const (&) [67])
Line
Count
Source
256
228
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [8], void>::toPointer(char const (&) [8])
Line
Count
Source
256
5.65M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [35], void>::toPointer(char const (&) [35])
Line
Count
Source
256
186k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [51], void>::toPointer(char const (&) [51])
Line
Count
Source
256
167k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [54], void>::toPointer(char const (&) [54])
Line
Count
Source
256
919
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [5], void>::toPointer(char const (&) [5])
Line
Count
Source
256
10.7M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [4], void>::toPointer(char const (&) [4])
Line
Count
Source
256
10.1M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [33], void>::toPointer(char const (&) [33])
Line
Count
Source
256
35.9M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [13], void>::toPointer(char const (&) [13])
Line
Count
Source
256
2.38M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [14], void>::toPointer(char const (&) [14])
Line
Count
Source
256
6.12M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [16], void>::toPointer(char const (&) [16])
Line
Count
Source
256
828k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [25], void>::toPointer(char const (&) [25])
Line
Count
Source
256
797k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [23], void>::toPointer(char const (&) [23])
Line
Count
Source
256
292k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [30], void>::toPointer(char const (&) [30])
Line
Count
Source
256
2.67M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [44], void>::toPointer(char const (&) [44])
Line
Count
Source
256
29.7k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [29], void>::toPointer(char const (&) [29])
Line
Count
Source
256
54.8k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [38], void>::toPointer(char const (&) [38])
Line
Count
Source
256
105k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [47], void>::toPointer(char const (&) [47])
Line
Count
Source
256
122k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [50], void>::toPointer(char const (&) [50])
Line
Count
Source
256
128k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [37], void>::toPointer(char const (&) [37])
Line
Count
Source
256
1.10M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [26], void>::toPointer(char const (&) [26])
Line
Count
Source
256
57.9k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [43], void>::toPointer(char const (&) [43])
Line
Count
Source
256
630k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [36], void>::toPointer(char const (&) [36])
Line
Count
Source
256
283k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [42], void>::toPointer(char const (&) [42])
Line
Count
Source
256
664k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [53], void>::toPointer(char const (&) [53])
Line
Count
Source
256
278
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [46], void>::toPointer(char const (&) [46])
Line
Count
Source
256
30.8k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [48], void>::toPointer(char const (&) [48])
Line
Count
Source
256
705
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [31], void>::toPointer(char const (&) [31])
Line
Count
Source
256
666k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [57], void>::toPointer(char const (&) [57])
Line
Count
Source
256
17.1k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [12], void>::toPointer(char const (&) [12])
Line
Count
Source
256
4.74M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [19], void>::toPointer(char const (&) [19])
Line
Count
Source
256
4.01M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [3], void>::toPointer(char const (&) [3])
Line
Count
Source
256
356M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [11], void>::toPointer(char const (&) [11])
Line
Count
Source
256
7.66M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [45], void>::toPointer(char const (&) [45])
Line
Count
Source
256
195k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [2], void>::toPointer(char const (&) [2])
Line
Count
Source
256
50.8M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [1], void>::toPointer(char const (&) [1])
Line
Count
Source
256
693k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [58], void>::toPointer(char const (&) [58])
Line
Count
Source
256
45.9k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [145], void>::toPointer(char const (&) [145])
rtl::libreoffice_internal::ConstCharArrayDetector<char const [49], void>::toPointer(char const (&) [49])
Line
Count
Source
256
1.44k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [61], void>::toPointer(char const (&) [61])
Line
Count
Source
256
292
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [52], void>::toPointer(char const (&) [52])
Line
Count
Source
256
20.1k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [22], void>::toPointer(char const (&) [22])
Line
Count
Source
256
526k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [59], void>::toPointer(char const (&) [59])
Line
Count
Source
256
478
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [56], void>::toPointer(char const (&) [56])
Line
Count
Source
256
13.2k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [63], void>::toPointer(char const (&) [63])
Line
Count
Source
256
15.6k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [66], void>::toPointer(char const (&) [66])
Line
Count
Source
256
68.9k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [69], void>::toPointer(char const (&) [69])
Line
Count
Source
256
326
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [64], void>::toPointer(char const (&) [64])
Line
Count
Source
256
58
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [21], void>::toPointer(char const (&) [21])
Line
Count
Source
256
2.29M
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [24], void>::toPointer(char const (&) [24])
Line
Count
Source
256
230k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [137], void>::toPointer(char const (&) [137])
Line
Count
Source
256
13
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [130], void>::toPointer(char const (&) [130])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [162], void>::toPointer(char const (&) [162])
rtl::libreoffice_internal::ConstCharArrayDetector<char const [232], void>::toPointer(char const (&) [232])
Line
Count
Source
256
15.5k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [73], void>::toPointer(char const (&) [73])
Line
Count
Source
256
15.6k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [60], void>::toPointer(char const (&) [60])
Line
Count
Source
256
66
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [140], void>::toPointer(char const (&) [140])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [111], void>::toPointer(char const (&) [111])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [141], void>::toPointer(char const (&) [141])
rtl::libreoffice_internal::ConstCharArrayDetector<char const [70], void>::toPointer(char const (&) [70])
Line
Count
Source
256
396
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [75], void>::toPointer(char const (&) [75])
Line
Count
Source
256
396
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [81], void>::toPointer(char const (&) [81])
Line
Count
Source
256
198
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [92], void>::toPointer(char const (&) [92])
Line
Count
Source
256
198
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [72], void>::toPointer(char const (&) [72])
Line
Count
Source
256
48
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [71], void>::toPointer(char const (&) [71])
Line
Count
Source
256
76
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [78], void>::toPointer(char const (&) [78])
Line
Count
Source
256
69.5k
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [77], void>::toPointer(char const (&) [77])
Line
Count
Source
256
6
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [79], void>::toPointer(char const (&) [79])
rtl::libreoffice_internal::ConstCharArrayDetector<char const [133], void>::toPointer(char const (&) [133])
Line
Count
Source
256
93
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [118], void>::toPointer(char const (&) [118])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [120], void>::toPointer(char const (&) [120])
rtl::libreoffice_internal::ConstCharArrayDetector<char const [74], void>::toPointer(char const (&) [74])
Line
Count
Source
256
14
    static char const * toPointer(char const (& literal)[N]) { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char const [76], void>::toPointer(char const (&) [76])
Line
Count
Source
256
4
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [122], void>::toPointer(char const (&) [122])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [125], void>::toPointer(char const (&) [125])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [131], void>::toPointer(char const (&) [131])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [152], void>::toPointer(char const (&) [152])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [164], void>::toPointer(char const (&) [164])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [96], void>::toPointer(char const (&) [96])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [83], void>::toPointer(char const (&) [83])
rtl::libreoffice_internal::ConstCharArrayDetector<char const [87], void>::toPointer(char const (&) [87])
Line
Count
Source
256
6
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [136], void>::toPointer(char const (&) [136])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [139], void>::toPointer(char const (&) [139])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [773], void>::toPointer(char const (&) [773])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [417], void>::toPointer(char const (&) [417])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [544], void>::toPointer(char const (&) [544])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [537], void>::toPointer(char const (&) [537])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1501], void>::toPointer(char const (&) [1501])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1168], void>::toPointer(char const (&) [1168])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1032], void>::toPointer(char const (&) [1032])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [775], void>::toPointer(char const (&) [775])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [419], void>::toPointer(char const (&) [419])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [546], void>::toPointer(char const (&) [546])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [541], void>::toPointer(char const (&) [541])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [540], void>::toPointer(char const (&) [540])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [627], void>::toPointer(char const (&) [627])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1034], void>::toPointer(char const (&) [1034])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1019], void>::toPointer(char const (&) [1019])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [730], void>::toPointer(char const (&) [730])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1136], void>::toPointer(char const (&) [1136])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1170], void>::toPointer(char const (&) [1170])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1162], void>::toPointer(char const (&) [1162])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [895], void>::toPointer(char const (&) [895])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1487], void>::toPointer(char const (&) [1487])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [859], void>::toPointer(char const (&) [859])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [862], void>::toPointer(char const (&) [862])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [655], void>::toPointer(char const (&) [655])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [651], void>::toPointer(char const (&) [651])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1503], void>::toPointer(char const (&) [1503])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [1873], void>::toPointer(char const (&) [1873])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [552], void>::toPointer(char const (&) [552])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [568], void>::toPointer(char const (&) [568])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [572], void>::toPointer(char const (&) [572])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [579], void>::toPointer(char const (&) [579])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [596], void>::toPointer(char const (&) [596])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [550], void>::toPointer(char const (&) [550])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [497], void>::toPointer(char const (&) [497])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [613], void>::toPointer(char const (&) [613])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [558], void>::toPointer(char const (&) [558])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [556], void>::toPointer(char const (&) [556])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [551], void>::toPointer(char const (&) [551])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [560], void>::toPointer(char const (&) [560])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [573], void>::toPointer(char const (&) [573])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [575], void>::toPointer(char const (&) [575])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [539], void>::toPointer(char const (&) [539])
rtl::libreoffice_internal::ConstCharArrayDetector<char const [84], void>::toPointer(char const (&) [84])
Line
Count
Source
256
6
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [116], void>::toPointer(char const (&) [116])
rtl::libreoffice_internal::ConstCharArrayDetector<char const [135], void>::toPointer(char const (&) [135])
Line
Count
Source
256
3
    static char const * toPointer(char const (& literal)[N]) { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [117], void>::toPointer(char const (&) [117])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [121], void>::toPointer(char const (&) [121])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [165], void>::toPointer(char const (&) [165])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [148], void>::toPointer(char const (&) [148])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [85], void>::toPointer(char const (&) [85])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [90], void>::toPointer(char const (&) [90])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [452], void>::toPointer(char const (&) [452])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [310], void>::toPointer(char const (&) [310])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [212], void>::toPointer(char const (&) [212])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [203], void>::toPointer(char const (&) [203])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char const [224], void>::toPointer(char const (&) [224])
257
};
258
259
#if defined(__COVERITY__) && __COVERITY_MAJOR__ <= 2024
260
//to silence over zealous warnings that the loop is logically dead
261
//for the single char case
262
template< typename T >
263
struct ConstCharArrayDetector< const char[ 1 ], T >
264
{
265
    typedef T Type;
266
    static const std::size_t length = 0;
267
    static const bool ok = true;
268
#if defined LIBO_INTERNAL_ONLY
269
    constexpr
270
#endif
271
    static bool isValid(char const (& literal)[1]) {
272
        return literal[0] == '\0';
273
    }
274
#if defined LIBO_INTERNAL_ONLY
275
    constexpr
276
#endif
277
    static char const * toPointer(char const (& literal)[1]) { return literal; }
278
};
279
#endif
280
281
#if defined LIBO_INTERNAL_ONLY \
282
    && !(defined _MSC_VER && _MSC_VER >= 1930 && _MSC_VER <= 1939 && defined _MANAGED)
283
template<std::size_t N, typename T>
284
struct ConstCharArrayDetector<char8_t const [N], T> {
285
    using Type = T;
286
    static constexpr bool const ok = true;
287
    static constexpr std::size_t const length = N - 1;
288
    static constexpr bool isValid(char8_t const (& literal)[N]) {
289
        for (std::size_t i = 0; i != N - 1; ++i) {
290
            if (literal[i] == u8'\0') {
291
                return false;
292
            }
293
        }
294
        return literal[N - 1] == u8'\0';
295
    }
296
    static constexpr char const * toPointer(char8_t const (& literal)[N])
297
    { return reinterpret_cast<char const *>(literal); }
298
};
299
#endif
300
301
#if defined LIBO_INTERNAL_ONLY
302
template<std::size_t N, typename T>
303
struct ConstCharArrayDetector<sal_Unicode const [N], T> {
304
    using TypeUtf16 = T;
305
    static constexpr bool const ok = true;
306
    static constexpr std::size_t const length = N - 1;
307
    static constexpr bool isValid(sal_Unicode const (& literal)[N]) {
308
        for (std::size_t i = 0; i != N - 1; ++i) {
309
            if (literal[i] == '\0') {
310
                return false;
311
            }
312
        }
313
        return literal[N - 1] == '\0';
314
    }
315
    static constexpr sal_Unicode const * toPointer(
316
        sal_Unicode const (& literal)[N])
317
113k
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [27], void>::toPointer(char16_t const (&) [27])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [7], void>::toPointer(char16_t const (&) [7])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [5], void>::toPointer(char16_t const (&) [5])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [10], void>::toPointer(char16_t const (&) [10])
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [12], void>::toPointer(char16_t const (&) [12])
Line
Count
Source
317
10.3k
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [11], void>::toPointer(char16_t const (&) [11])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [6], void>::toPointer(char16_t const (&) [6])
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [8], void>::toPointer(char16_t const (&) [8])
Line
Count
Source
317
22.2k
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [9], void>::toPointer(char16_t const (&) [9])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [16], void>::toPointer(char16_t const (&) [16])
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [13], void>::toPointer(char16_t const (&) [13])
Line
Count
Source
317
7.85k
    { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [4], void>::toPointer(char16_t const (&) [4])
Line
Count
Source
317
309
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [88], void>::toPointer(char16_t const (&) [88])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [84], void>::toPointer(char16_t const (&) [84])
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [68], void>::toPointer(char16_t const (&) [68])
Line
Count
Source
317
2
    { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [72], void>::toPointer(char16_t const (&) [72])
Line
Count
Source
317
2
    { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [15], void>::toPointer(char16_t const (&) [15])
Line
Count
Source
317
4.70k
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [25], void>::toPointer(char16_t const (&) [25])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [24], void>::toPointer(char16_t const (&) [24])
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [14], void>::toPointer(char16_t const (&) [14])
Line
Count
Source
317
4.70k
    { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [2], void>::toPointer(char16_t const (&) [2])
Line
Count
Source
317
4
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [19], void>::toPointer(char16_t const (&) [19])
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [29], void>::toPointer(char16_t const (&) [29])
Line
Count
Source
317
4.70k
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [35], void>::toPointer(char16_t const (&) [35])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [45], void>::toPointer(char16_t const (&) [45])
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [17], void>::toPointer(char16_t const (&) [17])
Line
Count
Source
317
4.70k
    { return literal; }
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [31], void>::toPointer(char16_t const (&) [31])
Line
Count
Source
317
48.5k
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [21], void>::toPointer(char16_t const (&) [21])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [20], void>::toPointer(char16_t const (&) [20])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [18], void>::toPointer(char16_t const (&) [18])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [22], void>::toPointer(char16_t const (&) [22])
rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [3], void>::toPointer(char16_t const (&) [3])
Line
Count
Source
317
4.94k
    { return literal; }
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [43], void>::toPointer(char16_t const (&) [43])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [38], void>::toPointer(char16_t const (&) [38])
Unexecuted instantiation: rtl::libreoffice_internal::ConstCharArrayDetector<char16_t const [40], void>::toPointer(char16_t const (&) [40])
318
};
319
320
template<typename T> struct ConstCharArrayDetector<
321
    OUStringChar,
322
    T>
323
{
324
    using TypeUtf16 = T;
325
    static constexpr bool const ok = true;
326
    static constexpr std::size_t const length = 1;
327
    static constexpr bool isValid(OUStringChar) { return true; }
328
    static constexpr sal_Unicode const * toPointer(
329
        OUStringChar_ const & literal)
330
164M
    { return &literal.c; }
331
};
332
#endif
333
334
#if defined LIBO_INTERNAL_ONLY && defined RTL_STRING_UNITTEST
335
336
// this one is used to rule out only const char[N]
337
template< typename T >
338
struct ExceptConstCharArrayDetector
339
{
340
    typedef Dummy Type;
341
};
342
template< int N >
343
struct ExceptConstCharArrayDetector< const char[ N ] >
344
{
345
};
346
template<std::size_t N>
347
struct ExceptConstCharArrayDetector<sal_Unicode const[N]> {};
348
template<> struct ExceptConstCharArrayDetector<
349
    OUStringChar
350
    >
351
{};
352
353
// this one is used to rule out only const char[N]
354
// (const will be brought in by 'const T&' in the function call)
355
// msvc needs const char[N] here (not sure whether gcc or msvc
356
// are right, it doesn't matter).
357
template< typename T >
358
struct ExceptCharArrayDetector
359
{
360
    typedef Dummy Type;
361
};
362
template< int N >
363
struct ExceptCharArrayDetector< char[ N ] >
364
{
365
};
366
template< int N >
367
struct ExceptCharArrayDetector< const char[ N ] >
368
{
369
};
370
template<std::size_t N> struct ExceptCharArrayDetector<sal_Unicode[N]> {};
371
template<std::size_t N> struct ExceptCharArrayDetector<sal_Unicode const[N]> {};
372
template<> struct ExceptCharArrayDetector<OUStringChar_> {};
373
374
#endif
375
376
template< typename T1, typename T2 = void >
377
struct SalUnicodePtrDetector
378
{
379
    static const bool ok = false;
380
};
381
template< typename T >
382
struct SalUnicodePtrDetector< const sal_Unicode*, T >
383
{
384
    typedef T Type;
385
    static const bool ok = true;
386
};
387
template< typename T >
388
struct SalUnicodePtrDetector< sal_Unicode*, T >
389
{
390
    typedef T Type;
391
    static const bool ok = true;
392
};
393
394
// SFINAE helper class
395
template< typename T, bool >
396
struct Enable
397
    {
398
    };
399
400
template< typename T >
401
struct Enable< T, true >
402
    {
403
    typedef T Type;
404
    };
405
406
407
} /* Namespace */
408
409
} /* Namespace */
410
411
#endif // INCLUDED_RTL_STRINGUTILS_HXX
412
413
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */