/Users/buildslave/jenkins/workspace/coverage/llvm-project/libcxx/src/string.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===----------------------------------------------------------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include <__assert> |
10 | | #include <cerrno> |
11 | | #include <charconv> |
12 | | #include <cstdlib> |
13 | | #include <limits> |
14 | | #include <stdexcept> |
15 | | #include <stdio.h> |
16 | | #include <string> |
17 | | |
18 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
19 | | # include <cwchar> |
20 | | #endif |
21 | | |
22 | | _LIBCPP_BEGIN_NAMESPACE_STD |
23 | | |
24 | | #ifndef _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON |
25 | | |
26 | | template <bool> |
27 | | struct __basic_string_common; |
28 | | |
29 | | // The struct isn't declared anymore in the headers. It's only here for ABI compatibility. |
30 | | template <> |
31 | | struct __basic_string_common<true> { |
32 | | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const; |
33 | | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const; |
34 | | }; |
35 | | |
36 | 0 | void __basic_string_common<true>::__throw_length_error() const { |
37 | 0 | std::__throw_length_error("basic_string"); |
38 | 0 | } |
39 | 0 | void __basic_string_common<true>::__throw_out_of_range() const { |
40 | 0 | std::__throw_out_of_range("basic_string"); |
41 | 0 | } |
42 | | |
43 | | #endif // _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON |
44 | | |
45 | | #define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__; |
46 | | #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION |
47 | | _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char) |
48 | | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
49 | | _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t) |
50 | | # endif |
51 | | #else |
52 | | _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char) |
53 | | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
54 | | _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t) |
55 | | # endif |
56 | | #endif |
57 | | #undef _LIBCPP_EXTERN_TEMPLATE_DEFINE |
58 | | |
59 | | template string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); |
60 | | |
61 | | namespace |
62 | | { |
63 | | |
64 | | template<typename T> |
65 | | inline |
66 | | void throw_helper( const string& msg ) |
67 | 0 | { |
68 | 0 | #ifndef _LIBCPP_NO_EXCEPTIONS |
69 | 0 | throw T( msg ); |
70 | | #else |
71 | | fprintf(stderr, "%s\n", msg.c_str()); |
72 | | _VSTD::abort(); |
73 | | #endif |
74 | 0 | } Unexecuted instantiation: string.cpp:void std::__1::(anonymous namespace)::throw_helper<std::invalid_argument>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: string.cpp:void std::__1::(anonymous namespace)::throw_helper<std::out_of_range>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) |
75 | | |
76 | | inline |
77 | | void throw_from_string_out_of_range( const string& func ) |
78 | 0 | { |
79 | 0 | throw_helper<out_of_range>(func + ": out of range"); |
80 | 0 | } |
81 | | |
82 | | inline |
83 | | void throw_from_string_invalid_arg( const string& func ) |
84 | 0 | { |
85 | 0 | throw_helper<invalid_argument>(func + ": no conversion"); |
86 | 0 | } |
87 | | |
88 | | // as_integer |
89 | | |
90 | | template<typename V, typename S, typename F> |
91 | | inline |
92 | | V |
93 | | as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) |
94 | 0 | { |
95 | 0 | typename S::value_type* ptr = nullptr; |
96 | 0 | const typename S::value_type* const p = str.c_str(); |
97 | 0 | typename remove_reference<decltype(errno)>::type errno_save = errno; |
98 | 0 | errno = 0; |
99 | 0 | V r = f(p, &ptr, base); |
100 | 0 | swap(errno, errno_save); |
101 | 0 | if (errno_save == ERANGE) |
102 | 0 | throw_from_string_out_of_range(func); |
103 | 0 | if (ptr == p) |
104 | 0 | throw_from_string_invalid_arg(func); |
105 | 0 | if (idx) |
106 | 0 | *idx = static_cast<size_t>(ptr - p); |
107 | 0 | return r; |
108 | 0 | } Unexecuted instantiation: string.cpp:long std::__1::(anonymous namespace)::as_integer_helper<long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long (*)(char const*, char**, int)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long*, int, long (*)(char const*, char**, int)) Unexecuted instantiation: string.cpp:long std::__1::(anonymous namespace)::as_integer_helper<long, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, long (*)(wchar_t const*, wchar_t**, int)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long*, int, long (*)(wchar_t const*, wchar_t**, int)) Unexecuted instantiation: string.cpp:unsigned long std::__1::(anonymous namespace)::as_integer_helper<unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned long (*)(char const*, char**, int)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long*, int, unsigned long (*)(char const*, char**, int)) Unexecuted instantiation: string.cpp:unsigned long std::__1::(anonymous namespace)::as_integer_helper<unsigned long, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned long (*)(wchar_t const*, wchar_t**, int)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long*, int, unsigned long (*)(wchar_t const*, wchar_t**, int)) Unexecuted instantiation: string.cpp:long long std::__1::(anonymous namespace)::as_integer_helper<long long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long long (*)(char const*, char**, int)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long*, int, long long (*)(char const*, char**, int)) Unexecuted instantiation: string.cpp:long long std::__1::(anonymous namespace)::as_integer_helper<long long, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, long long (*)(wchar_t const*, wchar_t**, int)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long*, int, long long (*)(wchar_t const*, wchar_t**, int)) Unexecuted instantiation: string.cpp:unsigned long long std::__1::(anonymous namespace)::as_integer_helper<unsigned long long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned long long (*)(char const*, char**, int)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long*, int, unsigned long long (*)(char const*, char**, int)) Unexecuted instantiation: string.cpp:unsigned long long std::__1::(anonymous namespace)::as_integer_helper<unsigned long long, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned long long (*)(wchar_t const*, wchar_t**, int)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long*, int, unsigned long long (*)(wchar_t const*, wchar_t**, int)) |
109 | | |
110 | | template<typename V, typename S> |
111 | | inline |
112 | | V |
113 | | as_integer(const string& func, const S& s, size_t* idx, int base); |
114 | | |
115 | | // string |
116 | | template<> |
117 | | inline |
118 | | int |
119 | | as_integer(const string& func, const string& s, size_t* idx, int base ) |
120 | 0 | { |
121 | | // Use long as no Standard string to integer exists. |
122 | 0 | long r = as_integer_helper<long>( func, s, idx, base, strtol ); |
123 | 0 | if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) |
124 | 0 | throw_from_string_out_of_range(func); |
125 | 0 | return static_cast<int>(r); |
126 | 0 | } |
127 | | |
128 | | template<> |
129 | | inline |
130 | | long |
131 | | as_integer(const string& func, const string& s, size_t* idx, int base ) |
132 | 0 | { |
133 | 0 | return as_integer_helper<long>( func, s, idx, base, strtol ); |
134 | 0 | } |
135 | | |
136 | | template<> |
137 | | inline |
138 | | unsigned long |
139 | | as_integer( const string& func, const string& s, size_t* idx, int base ) |
140 | 0 | { |
141 | 0 | return as_integer_helper<unsigned long>( func, s, idx, base, strtoul ); |
142 | 0 | } |
143 | | |
144 | | template<> |
145 | | inline |
146 | | long long |
147 | | as_integer( const string& func, const string& s, size_t* idx, int base ) |
148 | 0 | { |
149 | 0 | return as_integer_helper<long long>( func, s, idx, base, strtoll ); |
150 | 0 | } |
151 | | |
152 | | template<> |
153 | | inline |
154 | | unsigned long long |
155 | | as_integer( const string& func, const string& s, size_t* idx, int base ) |
156 | 0 | { |
157 | 0 | return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull ); |
158 | 0 | } |
159 | | |
160 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
161 | | // wstring |
162 | | template<> |
163 | | inline |
164 | | int |
165 | | as_integer( const string& func, const wstring& s, size_t* idx, int base ) |
166 | 0 | { |
167 | | // Use long as no Stantard string to integer exists. |
168 | 0 | long r = as_integer_helper<long>( func, s, idx, base, wcstol ); |
169 | 0 | if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) |
170 | 0 | throw_from_string_out_of_range(func); |
171 | 0 | return static_cast<int>(r); |
172 | 0 | } |
173 | | |
174 | | template<> |
175 | | inline |
176 | | long |
177 | | as_integer( const string& func, const wstring& s, size_t* idx, int base ) |
178 | 0 | { |
179 | 0 | return as_integer_helper<long>( func, s, idx, base, wcstol ); |
180 | 0 | } |
181 | | |
182 | | template<> |
183 | | inline |
184 | | unsigned long |
185 | | as_integer( const string& func, const wstring& s, size_t* idx, int base ) |
186 | 0 | { |
187 | 0 | return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul ); |
188 | 0 | } |
189 | | |
190 | | template<> |
191 | | inline |
192 | | long long |
193 | | as_integer( const string& func, const wstring& s, size_t* idx, int base ) |
194 | 0 | { |
195 | 0 | return as_integer_helper<long long>( func, s, idx, base, wcstoll ); |
196 | 0 | } |
197 | | |
198 | | template<> |
199 | | inline |
200 | | unsigned long long |
201 | | as_integer( const string& func, const wstring& s, size_t* idx, int base ) |
202 | 0 | { |
203 | 0 | return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull ); |
204 | 0 | } |
205 | | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
206 | | |
207 | | // as_float |
208 | | |
209 | | template<typename V, typename S, typename F> |
210 | | inline |
211 | | V |
212 | | as_float_helper(const string& func, const S& str, size_t* idx, F f ) |
213 | 0 | { |
214 | 0 | typename S::value_type* ptr = nullptr; |
215 | 0 | const typename S::value_type* const p = str.c_str(); |
216 | 0 | typename remove_reference<decltype(errno)>::type errno_save = errno; |
217 | 0 | errno = 0; |
218 | 0 | V r = f(p, &ptr); |
219 | 0 | swap(errno, errno_save); |
220 | 0 | if (errno_save == ERANGE) |
221 | 0 | throw_from_string_out_of_range(func); |
222 | 0 | if (ptr == p) |
223 | 0 | throw_from_string_invalid_arg(func); |
224 | 0 | if (idx) |
225 | 0 | *idx = static_cast<size_t>(ptr - p); |
226 | 0 | return r; |
227 | 0 | } Unexecuted instantiation: string.cpp:float std::__1::(anonymous namespace)::as_float_helper<float, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, float (*)(char const*, char**)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long*, float (*)(char const*, char**)) Unexecuted instantiation: string.cpp:float std::__1::(anonymous namespace)::as_float_helper<float, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, float (*)(wchar_t const*, wchar_t**)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long*, float (*)(wchar_t const*, wchar_t**)) Unexecuted instantiation: string.cpp:double std::__1::(anonymous namespace)::as_float_helper<double, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, double (*)(char const*, char**)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long*, double (*)(char const*, char**)) Unexecuted instantiation: string.cpp:double std::__1::(anonymous namespace)::as_float_helper<double, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, double (*)(wchar_t const*, wchar_t**)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long*, double (*)(wchar_t const*, wchar_t**)) Unexecuted instantiation: string.cpp:long double std::__1::(anonymous namespace)::as_float_helper<long double, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long double (*)(char const*, char**)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long*, long double (*)(char const*, char**)) Unexecuted instantiation: string.cpp:long double std::__1::(anonymous namespace)::as_float_helper<long double, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, long double (*)(wchar_t const*, wchar_t**)>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long*, long double (*)(wchar_t const*, wchar_t**)) |
228 | | |
229 | | template<typename V, typename S> |
230 | | inline |
231 | | V as_float( const string& func, const S& s, size_t* idx = nullptr ); |
232 | | |
233 | | template<> |
234 | | inline |
235 | | float |
236 | | as_float( const string& func, const string& s, size_t* idx ) |
237 | 0 | { |
238 | 0 | return as_float_helper<float>( func, s, idx, strtof ); |
239 | 0 | } |
240 | | |
241 | | template<> |
242 | | inline |
243 | | double |
244 | | as_float(const string& func, const string& s, size_t* idx ) |
245 | 0 | { |
246 | 0 | return as_float_helper<double>( func, s, idx, strtod ); |
247 | 0 | } |
248 | | |
249 | | template<> |
250 | | inline |
251 | | long double |
252 | | as_float( const string& func, const string& s, size_t* idx ) |
253 | 0 | { |
254 | 0 | return as_float_helper<long double>( func, s, idx, strtold ); |
255 | 0 | } |
256 | | |
257 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
258 | | template<> |
259 | | inline |
260 | | float |
261 | | as_float( const string& func, const wstring& s, size_t* idx ) |
262 | 0 | { |
263 | 0 | return as_float_helper<float>( func, s, idx, wcstof ); |
264 | 0 | } |
265 | | |
266 | | template<> |
267 | | inline |
268 | | double |
269 | | as_float( const string& func, const wstring& s, size_t* idx ) |
270 | 0 | { |
271 | 0 | return as_float_helper<double>( func, s, idx, wcstod ); |
272 | 0 | } |
273 | | |
274 | | template<> |
275 | | inline |
276 | | long double |
277 | | as_float( const string& func, const wstring& s, size_t* idx ) |
278 | 0 | { |
279 | 0 | return as_float_helper<long double>( func, s, idx, wcstold ); |
280 | 0 | } |
281 | | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
282 | | |
283 | | } // unnamed namespace |
284 | | |
285 | | int |
286 | | stoi(const string& str, size_t* idx, int base) |
287 | 0 | { |
288 | 0 | return as_integer<int>( "stoi", str, idx, base ); |
289 | 0 | } |
290 | | |
291 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
292 | | int |
293 | | stoi(const wstring& str, size_t* idx, int base) |
294 | 0 | { |
295 | 0 | return as_integer<int>( "stoi", str, idx, base ); |
296 | 0 | } |
297 | | #endif |
298 | | |
299 | | long |
300 | | stol(const string& str, size_t* idx, int base) |
301 | 0 | { |
302 | 0 | return as_integer<long>( "stol", str, idx, base ); |
303 | 0 | } |
304 | | |
305 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
306 | | long |
307 | | stol(const wstring& str, size_t* idx, int base) |
308 | 0 | { |
309 | 0 | return as_integer<long>( "stol", str, idx, base ); |
310 | 0 | } |
311 | | #endif |
312 | | |
313 | | unsigned long |
314 | | stoul(const string& str, size_t* idx, int base) |
315 | 0 | { |
316 | 0 | return as_integer<unsigned long>( "stoul", str, idx, base ); |
317 | 0 | } |
318 | | |
319 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
320 | | unsigned long |
321 | | stoul(const wstring& str, size_t* idx, int base) |
322 | 0 | { |
323 | 0 | return as_integer<unsigned long>( "stoul", str, idx, base ); |
324 | 0 | } |
325 | | #endif |
326 | | |
327 | | long long |
328 | | stoll(const string& str, size_t* idx, int base) |
329 | 0 | { |
330 | 0 | return as_integer<long long>( "stoll", str, idx, base ); |
331 | 0 | } |
332 | | |
333 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
334 | | long long |
335 | | stoll(const wstring& str, size_t* idx, int base) |
336 | 0 | { |
337 | 0 | return as_integer<long long>( "stoll", str, idx, base ); |
338 | 0 | } |
339 | | #endif |
340 | | |
341 | | unsigned long long |
342 | | stoull(const string& str, size_t* idx, int base) |
343 | 0 | { |
344 | 0 | return as_integer<unsigned long long>( "stoull", str, idx, base ); |
345 | 0 | } |
346 | | |
347 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
348 | | unsigned long long |
349 | | stoull(const wstring& str, size_t* idx, int base) |
350 | 0 | { |
351 | 0 | return as_integer<unsigned long long>( "stoull", str, idx, base ); |
352 | 0 | } |
353 | | #endif |
354 | | |
355 | | float |
356 | | stof(const string& str, size_t* idx) |
357 | 0 | { |
358 | 0 | return as_float<float>( "stof", str, idx ); |
359 | 0 | } |
360 | | |
361 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
362 | | float |
363 | | stof(const wstring& str, size_t* idx) |
364 | 0 | { |
365 | 0 | return as_float<float>( "stof", str, idx ); |
366 | 0 | } |
367 | | #endif |
368 | | |
369 | | double |
370 | | stod(const string& str, size_t* idx) |
371 | 0 | { |
372 | 0 | return as_float<double>( "stod", str, idx ); |
373 | 0 | } |
374 | | |
375 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
376 | | double |
377 | | stod(const wstring& str, size_t* idx) |
378 | 0 | { |
379 | 0 | return as_float<double>( "stod", str, idx ); |
380 | 0 | } |
381 | | #endif |
382 | | |
383 | | long double |
384 | | stold(const string& str, size_t* idx) |
385 | 0 | { |
386 | 0 | return as_float<long double>( "stold", str, idx ); |
387 | 0 | } |
388 | | |
389 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
390 | | long double |
391 | | stold(const wstring& str, size_t* idx) |
392 | 0 | { |
393 | 0 | return as_float<long double>( "stold", str, idx ); |
394 | 0 | } |
395 | | #endif |
396 | | |
397 | | // to_string |
398 | | |
399 | | namespace |
400 | | { |
401 | | |
402 | | // as_string |
403 | | |
404 | | template<typename S, typename P, typename V > |
405 | | inline |
406 | | S |
407 | | as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a) |
408 | 0 | { |
409 | 0 | typedef typename S::size_type size_type; |
410 | 0 | size_type available = s.size(); |
411 | 0 | while (true) |
412 | 0 | { |
413 | 0 | int status = sprintf_like(&s[0], available + 1, fmt, a); |
414 | 0 | if ( status >= 0 ) |
415 | 0 | { |
416 | 0 | size_type used = static_cast<size_type>(status); |
417 | 0 | if ( used <= available ) |
418 | 0 | { |
419 | 0 | s.resize( used ); |
420 | 0 | break; |
421 | 0 | } |
422 | 0 | available = used; // Assume this is advice of how much space we need. |
423 | 0 | } |
424 | 0 | else |
425 | 0 | available = available * 2 + 1; |
426 | 0 | s.resize(available); |
427 | 0 | } |
428 | 0 | return s; |
429 | 0 | } Unexecuted instantiation: string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::as_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int (*)(char*, unsigned long, char const*, ...), float>(int (*)(char*, unsigned long, char const*, ...), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::value_type const*, float) Unexecuted instantiation: string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::as_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int (*)(char*, unsigned long, char const*, ...), double>(int (*)(char*, unsigned long, char const*, ...), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::value_type const*, double) Unexecuted instantiation: string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::as_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int (*)(char*, unsigned long, char const*, ...), long double>(int (*)(char*, unsigned long, char const*, ...), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::value_type const*, long double) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::as_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, int (*)(wchar_t*, unsigned long, wchar_t const*, ...), float>(int (*)(wchar_t*, unsigned long, wchar_t const*, ...), std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >::value_type const*, float) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::as_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, int (*)(wchar_t*, unsigned long, wchar_t const*, ...), double>(int (*)(wchar_t*, unsigned long, wchar_t const*, ...), std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >::value_type const*, double) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::as_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, int (*)(wchar_t*, unsigned long, wchar_t const*, ...), long double>(int (*)(wchar_t*, unsigned long, wchar_t const*, ...), std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >::value_type const*, long double) |
430 | | |
431 | | template <class S> |
432 | | struct initial_string; |
433 | | |
434 | | template <> |
435 | | struct initial_string<string> |
436 | | { |
437 | | string |
438 | | operator()() const |
439 | 0 | { |
440 | 0 | string s; |
441 | 0 | s.resize(s.capacity()); |
442 | 0 | return s; |
443 | 0 | } |
444 | | }; |
445 | | |
446 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
447 | | template <> |
448 | | struct initial_string<wstring> |
449 | | { |
450 | | wstring |
451 | | operator()() const |
452 | 0 | { |
453 | 0 | wstring s(20, wchar_t()); |
454 | 0 | s.resize(s.capacity()); |
455 | 0 | return s; |
456 | 0 | } |
457 | | }; |
458 | | |
459 | | typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); |
460 | | |
461 | | inline |
462 | | wide_printf |
463 | | get_swprintf() |
464 | 0 | { |
465 | 0 | #ifndef _LIBCPP_MSVCRT |
466 | 0 | return swprintf; |
467 | | #else |
468 | | return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(_snwprintf); |
469 | | #endif |
470 | 0 | } |
471 | | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
472 | | |
473 | | template <typename S, typename V> |
474 | | S i_to_string(V v) |
475 | 1.09M | { |
476 | | // numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers. |
477 | | // For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented), |
478 | | // so we need +1 here. |
479 | 1.09M | constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10 |
480 | 1.09M | char buf[bufsize]; |
481 | 1.09M | const auto res = to_chars(buf, buf + bufsize, v); |
482 | 1.09M | _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value"); |
483 | 1.09M | return S(buf, res.ptr); |
484 | 1.09M | } Unexecuted instantiation: string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>(int) Unexecuted instantiation: string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long>(long) Unexecuted instantiation: string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long long>(long long) string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned int>(unsigned int) Line | Count | Source | 475 | 1.09M | { | 476 | | // numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers. | 477 | | // For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented), | 478 | | // so we need +1 here. | 479 | 1.09M | constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10 | 480 | 1.09M | char buf[bufsize]; | 481 | 1.09M | const auto res = to_chars(buf, buf + bufsize, v); | 482 | 1.09M | _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value"); | 483 | 1.09M | return S(buf, res.ptr); | 484 | 1.09M | } |
string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned long>(unsigned long) Line | Count | Source | 475 | 16 | { | 476 | | // numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers. | 477 | | // For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented), | 478 | | // so we need +1 here. | 479 | 16 | constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10 | 480 | 16 | char buf[bufsize]; | 481 | 16 | const auto res = to_chars(buf, buf + bufsize, v); | 482 | 16 | _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value"); | 483 | 16 | return S(buf, res.ptr); | 484 | 16 | } |
Unexecuted instantiation: string.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned long long>(unsigned long long) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, int>(int) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, long>(long) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, long long>(long long) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned int>(unsigned int) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned long>(unsigned long) Unexecuted instantiation: string.cpp:std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > std::__1::(anonymous namespace)::i_to_string<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, unsigned long long>(unsigned long long) |
485 | | |
486 | | } // unnamed namespace |
487 | | |
488 | 0 | string to_string (int val) { return i_to_string< string>(val); } |
489 | 0 | string to_string (long val) { return i_to_string< string>(val); } |
490 | 0 | string to_string (long long val) { return i_to_string< string>(val); } |
491 | 1.09M | string to_string (unsigned val) { return i_to_string< string>(val); } |
492 | 16 | string to_string (unsigned long val) { return i_to_string< string>(val); } |
493 | 0 | string to_string (unsigned long long val) { return i_to_string< string>(val); } |
494 | | |
495 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
496 | 0 | wstring to_wstring(int val) { return i_to_string<wstring>(val); } |
497 | 0 | wstring to_wstring(long val) { return i_to_string<wstring>(val); } |
498 | 0 | wstring to_wstring(long long val) { return i_to_string<wstring>(val); } |
499 | 0 | wstring to_wstring(unsigned val) { return i_to_string<wstring>(val); } |
500 | 0 | wstring to_wstring(unsigned long val) { return i_to_string<wstring>(val); } |
501 | 0 | wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); } |
502 | | #endif |
503 | | |
504 | 0 | string to_string (float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); } |
505 | 0 | string to_string (double val) { return as_string(snprintf, initial_string< string>()(), "%f", val); } |
506 | 0 | string to_string (long double val) { return as_string(snprintf, initial_string< string>()(), "%Lf", val); } |
507 | | |
508 | | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
509 | 0 | wstring to_wstring(float val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); } |
510 | 0 | wstring to_wstring(double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%f", val); } |
511 | 0 | wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string<wstring>()(), L"%Lf", val); } |
512 | | #endif |
513 | | |
514 | | _LIBCPP_END_NAMESPACE_STD |