1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP___LOCALE |
11 | #define _LIBCPP___LOCALE |
12 | |
13 | #include <__config> |
14 | |
15 | #if _LIBCPP_HAS_LOCALIZATION |
16 | |
17 | # include <__locale_dir/locale_base_api.h> |
18 | # include <__memory/addressof.h> |
19 | # include <__memory/shared_count.h> |
20 | # include <__mutex/once_flag.h> |
21 | # include <__type_traits/make_unsigned.h> |
22 | # include <__utility/no_destroy.h> |
23 | # include <__utility/private_constructor_tag.h> |
24 | # include <cctype> |
25 | # include <clocale> |
26 | # include <cstdint> |
27 | # include <cstdlib> |
28 | # include <string> |
29 | |
30 | // Some platforms require more includes than others. Keep the includes on all plaforms for now. |
31 | # include <cstddef> |
32 | # include <cstring> |
33 | |
34 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
35 | # include <cwchar> |
36 | # else |
37 | # include <__std_mbstate_t.h> |
38 | # endif |
39 | |
40 | # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
41 | # pragma GCC system_header |
42 | # endif |
43 | |
44 | _LIBCPP_BEGIN_NAMESPACE_STD |
45 | |
46 | class _LIBCPP_EXPORTED_FROM_ABI locale; |
47 | |
48 | template <class _CharT> |
49 | class collate; |
50 | |
51 | template <class _Facet> |
52 | _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale&) _NOEXCEPT; |
53 | |
54 | template <class _Facet> |
55 | _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&); |
56 | |
57 | class _LIBCPP_EXPORTED_FROM_ABI locale { |
58 | public: |
59 | // locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor, |
60 | // so it is trivially relocatable. Like shared_ptr, it is also replaceable. |
61 | using __trivially_relocatable _LIBCPP_NODEBUG = locale; |
62 | using __replaceable _LIBCPP_NODEBUG = locale; |
63 | |
64 | // types: |
65 | class _LIBCPP_EXPORTED_FROM_ABI facet; |
66 | class _LIBCPP_EXPORTED_FROM_ABI id; |
67 | |
68 | typedef int category; |
69 | |
70 | static const category // values assigned here are for exposition only |
71 | none = 0, |
72 | collate = _LIBCPP_COLLATE_MASK, ctype = _LIBCPP_CTYPE_MASK, monetary = _LIBCPP_MONETARY_MASK, |
73 | numeric = _LIBCPP_NUMERIC_MASK, time = _LIBCPP_TIME_MASK, messages = _LIBCPP_MESSAGES_MASK, |
74 | all = collate | ctype | monetary | numeric | time | messages; |
75 | |
76 | // construct/copy/destroy: |
77 | locale() _NOEXCEPT; |
78 | locale(const locale&) _NOEXCEPT; |
79 | explicit locale(const char*); |
80 | explicit locale(const string&); |
81 | locale(const locale&, const char*, category); |
82 | locale(const locale&, const string&, category); |
83 | template <class _Facet> |
84 | _LIBCPP_HIDE_FROM_ABI locale(const locale&, _Facet*); |
85 | locale(const locale&, const locale&, category); |
86 | |
87 | ~locale(); |
88 | |
89 | const locale& operator=(const locale&) _NOEXCEPT; |
90 | |
91 | template <class _Facet> |
92 | _LIBCPP_HIDE_FROM_ABI locale combine(const locale& __other) const { |
93 | if (!std::has_facet<_Facet>(__other)) |
94 | __throw_runtime_error("locale::combine: locale missing facet" ); |
95 | |
96 | return locale(*this, std::addressof(const_cast<_Facet&>(std::use_facet<_Facet>(__other)))); |
97 | } |
98 | |
99 | // locale operations: |
100 | string name() const; |
101 | bool operator==(const locale&) const; |
102 | # if _LIBCPP_STD_VER <= 17 |
103 | _LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const { return !(*this == __y); } |
104 | # endif |
105 | template <class _CharT, class _Traits, class _Allocator> |
106 | _LIBCPP_HIDE_FROM_ABI bool operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, |
107 | const basic_string<_CharT, _Traits, _Allocator>& __y) const { |
108 | return std::use_facet<std::collate<_CharT> >(*this).compare( |
109 | __x.data(), __x.data() + __x.size(), __y.data(), __y.data() + __y.size()) < 0; |
110 | } |
111 | |
112 | // global locale objects: |
113 | static locale global(const locale&); |
114 | static const locale& classic(); |
115 | |
116 | private: |
117 | class __imp; |
118 | __imp* __locale_; |
119 | |
120 | template <class> |
121 | friend struct __no_destroy; |
122 | _LIBCPP_HIDE_FROM_ABI explicit locale(__private_constructor_tag, __imp* __loc) : __locale_(__loc) {} |
123 | |
124 | void __install_ctor(const locale&, facet*, long); |
125 | static locale& __global(); |
126 | bool has_facet(id&) const; |
127 | const facet* use_facet(id&) const; |
128 | |
129 | template <class _Facet> |
130 | friend bool has_facet(const locale&) _NOEXCEPT; |
131 | template <class _Facet> |
132 | friend const _Facet& use_facet(const locale&); |
133 | }; |
134 | |
135 | class _LIBCPP_EXPORTED_FROM_ABI locale::facet : public __shared_count { |
136 | protected: |
137 | _LIBCPP_HIDE_FROM_ABI explicit facet(size_t __refs = 0) : __shared_count(static_cast<long>(__refs) - 1) {} |
138 | |
139 | ~facet() override; |
140 | |
141 | // facet(const facet&) = delete; // effectively done in __shared_count |
142 | // void operator=(const facet&) = delete; |
143 | |
144 | private: |
145 | void __on_zero_shared() _NOEXCEPT override; |
146 | }; |
147 | |
148 | class _LIBCPP_EXPORTED_FROM_ABI locale::id { |
149 | once_flag __flag_; |
150 | int32_t __id_; |
151 | |
152 | static int32_t __next_id; |
153 | |
154 | public: |
155 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR id() : __id_(0) {} |
156 | void operator=(const id&) = delete; |
157 | id(const id&) = delete; |
158 | |
159 | public: // only needed for tests |
160 | long __get(); |
161 | |
162 | friend class locale; |
163 | friend class locale::__imp; |
164 | }; |
165 | |
166 | template <class _Facet> |
167 | inline _LIBCPP_HIDE_FROM_ABI locale::locale(const locale& __other, _Facet* __f) { |
168 | __install_ctor(__other, __f, __f ? __f->id.__get() : 0); |
169 | } |
170 | |
171 | template <class _Facet> |
172 | inline _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale& __l) _NOEXCEPT { |
173 | return __l.has_facet(_Facet::id); |
174 | } |
175 | |
176 | template <class _Facet> |
177 | inline _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale& __l) { |
178 | return static_cast<const _Facet&>(*__l.use_facet(_Facet::id)); |
179 | } |
180 | |
181 | // template <class _CharT> class collate; |
182 | |
183 | template <class _CharT> |
184 | class collate : public locale::facet { |
185 | public: |
186 | typedef _CharT char_type; |
187 | typedef basic_string<char_type> string_type; |
188 | |
189 | _LIBCPP_HIDE_FROM_ABI explicit collate(size_t __refs = 0) : locale::facet(__refs) {} |
190 | |
191 | _LIBCPP_HIDE_FROM_ABI int |
192 | compare(const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const { |
193 | return do_compare(__lo1, __hi1, __lo2, __hi2); |
194 | } |
195 | |
196 | // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work |
197 | // around a dllimport bug that expects an external instantiation. |
198 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE string_type |
199 | transform(const char_type* __lo, const char_type* __hi) const { |
200 | return do_transform(__lo, __hi); |
201 | } |
202 | |
203 | _LIBCPP_HIDE_FROM_ABI long hash(const char_type* __lo, const char_type* __hi) const { return do_hash(__lo, __hi); } |
204 | |
205 | static locale::id id; |
206 | |
207 | protected: |
208 | ~collate() override; |
209 | virtual int |
210 | do_compare(const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const; |
211 | virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const { |
212 | return string_type(__lo, __hi); |
213 | } |
214 | virtual long do_hash(const char_type* __lo, const char_type* __hi) const; |
215 | }; |
216 | |
217 | template <class _CharT> |
218 | locale::id collate<_CharT>::id; |
219 | |
220 | template <class _CharT> |
221 | collate<_CharT>::~collate() {} |
222 | |
223 | template <class _CharT> |
224 | int collate<_CharT>::do_compare( |
225 | const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const { |
226 | for (; __lo2 != __hi2; ++__lo1, ++__lo2) { |
227 | if (__lo1 == __hi1 || *__lo1 < *__lo2) |
228 | return -1; |
229 | if (*__lo2 < *__lo1) |
230 | return 1; |
231 | } |
232 | return __lo1 != __hi1; |
233 | } |
234 | |
235 | template <class _CharT> |
236 | long collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const { |
237 | size_t __h = 0; |
238 | const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8; |
239 | const size_t __mask = size_t(0xF) << (__sr + 4); |
240 | for (const char_type* __p = __lo; __p != __hi; ++__p) { |
241 | __h = (__h << 4) + static_cast<size_t>(*__p); |
242 | size_t __g = __h & __mask; |
243 | __h ^= __g | (__g >> __sr); |
244 | } |
245 | return static_cast<long>(__h); |
246 | } |
247 | |
248 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>; |
249 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
250 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>; |
251 | # endif |
252 | |
253 | // template <class CharT> class collate_byname; |
254 | |
255 | template <class _CharT> |
256 | class collate_byname; |
257 | |
258 | template <> |
259 | class _LIBCPP_EXPORTED_FROM_ABI collate_byname<char> : public collate<char> { |
260 | __locale::__locale_t __l_; |
261 | |
262 | public: |
263 | typedef char char_type; |
264 | typedef basic_string<char_type> string_type; |
265 | |
266 | explicit collate_byname(const char* __n, size_t __refs = 0); |
267 | explicit collate_byname(const string& __n, size_t __refs = 0); |
268 | |
269 | protected: |
270 | ~collate_byname() override; |
271 | int do_compare( |
272 | const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const override; |
273 | string_type do_transform(const char_type* __lo, const char_type* __hi) const override; |
274 | }; |
275 | |
276 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
277 | template <> |
278 | class _LIBCPP_EXPORTED_FROM_ABI collate_byname<wchar_t> : public collate<wchar_t> { |
279 | __locale::__locale_t __l_; |
280 | |
281 | public: |
282 | typedef wchar_t char_type; |
283 | typedef basic_string<char_type> string_type; |
284 | |
285 | explicit collate_byname(const char* __n, size_t __refs = 0); |
286 | explicit collate_byname(const string& __n, size_t __refs = 0); |
287 | |
288 | protected: |
289 | ~collate_byname() override; |
290 | |
291 | int do_compare( |
292 | const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const override; |
293 | string_type do_transform(const char_type* __lo, const char_type* __hi) const override; |
294 | }; |
295 | # endif |
296 | |
297 | // template <class charT> class ctype |
298 | |
299 | class _LIBCPP_EXPORTED_FROM_ABI ctype_base { |
300 | public: |
301 | # if defined(_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE) |
302 | typedef unsigned long mask; |
303 | static const mask space = 1 << 0; |
304 | static const mask print = 1 << 1; |
305 | static const mask cntrl = 1 << 2; |
306 | static const mask upper = 1 << 3; |
307 | static const mask lower = 1 << 4; |
308 | static const mask alpha = 1 << 5; |
309 | static const mask digit = 1 << 6; |
310 | static const mask punct = 1 << 7; |
311 | static const mask xdigit = 1 << 8; |
312 | static const mask blank = 1 << 9; |
313 | # if defined(__BIONIC__) |
314 | // Historically this was a part of regex_traits rather than ctype_base. The |
315 | // historical value of the constant is preserved for ABI compatibility. |
316 | static const mask __regex_word = 0x8000; |
317 | # else |
318 | static const mask __regex_word = 1 << 10; |
319 | # endif // defined(__BIONIC__) |
320 | # elif defined(__GLIBC__) |
321 | typedef unsigned short mask; |
322 | static const mask space = _ISspace; |
323 | static const mask print = _ISprint; |
324 | static const mask cntrl = _IScntrl; |
325 | static const mask upper = _ISupper; |
326 | static const mask lower = _ISlower; |
327 | static const mask alpha = _ISalpha; |
328 | static const mask digit = _ISdigit; |
329 | static const mask punct = _ISpunct; |
330 | static const mask xdigit = _ISxdigit; |
331 | static const mask blank = _ISblank; |
332 | # if defined(__mips__) || (BYTE_ORDER == BIG_ENDIAN) |
333 | static const mask __regex_word = static_cast<mask>(_ISbit(15)); |
334 | # else |
335 | static const mask __regex_word = 0x80; |
336 | # endif |
337 | # elif defined(_LIBCPP_MSVCRT_LIKE) |
338 | typedef unsigned short mask; |
339 | static const mask space = _SPACE; |
340 | static const mask print = _BLANK | _PUNCT | _ALPHA | _DIGIT; |
341 | static const mask cntrl = _CONTROL; |
342 | static const mask upper = _UPPER; |
343 | static const mask lower = _LOWER; |
344 | static const mask alpha = _ALPHA; |
345 | static const mask digit = _DIGIT; |
346 | static const mask punct = _PUNCT; |
347 | static const mask xdigit = _HEX; |
348 | static const mask blank = _BLANK; |
349 | static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used |
350 | # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT |
351 | # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA |
352 | # elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) |
353 | # ifdef __APPLE__ |
354 | typedef uint32_t mask; |
355 | # elif defined(__FreeBSD__) |
356 | typedef unsigned long mask; |
357 | # elif defined(__NetBSD__) |
358 | typedef unsigned short mask; |
359 | # endif |
360 | static const mask space = _CTYPE_S; |
361 | static const mask print = _CTYPE_R; |
362 | static const mask cntrl = _CTYPE_C; |
363 | static const mask upper = _CTYPE_U; |
364 | static const mask lower = _CTYPE_L; |
365 | static const mask alpha = _CTYPE_A; |
366 | static const mask digit = _CTYPE_D; |
367 | static const mask punct = _CTYPE_P; |
368 | static const mask xdigit = _CTYPE_X; |
369 | |
370 | # if defined(__NetBSD__) |
371 | static const mask blank = _CTYPE_BL; |
372 | // NetBSD defines classes up to 0x2000 |
373 | // see sys/ctype_bits.h, _CTYPE_Q |
374 | static const mask __regex_word = 0x8000; |
375 | # else |
376 | static const mask blank = _CTYPE_B; |
377 | static const mask __regex_word = 0x80; |
378 | # endif |
379 | # elif defined(_AIX) |
380 | typedef unsigned int mask; |
381 | static const mask space = _ISSPACE; |
382 | static const mask print = _ISPRINT; |
383 | static const mask cntrl = _ISCNTRL; |
384 | static const mask upper = _ISUPPER; |
385 | static const mask lower = _ISLOWER; |
386 | static const mask alpha = _ISALPHA; |
387 | static const mask digit = _ISDIGIT; |
388 | static const mask punct = _ISPUNCT; |
389 | static const mask xdigit = _ISXDIGIT; |
390 | static const mask blank = _ISBLANK; |
391 | static const mask __regex_word = 0x8000; |
392 | # elif defined(_NEWLIB_VERSION) |
393 | // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. |
394 | typedef char mask; |
395 | // In case char is signed, static_cast is needed to avoid warning on |
396 | // positive value becomming negative. |
397 | static const mask space = static_cast<mask>(_S); |
398 | static const mask print = static_cast<mask>(_P | _U | _L | _N | _B); |
399 | static const mask cntrl = static_cast<mask>(_C); |
400 | static const mask upper = static_cast<mask>(_U); |
401 | static const mask lower = static_cast<mask>(_L); |
402 | static const mask alpha = static_cast<mask>(_U | _L); |
403 | static const mask digit = static_cast<mask>(_N); |
404 | static const mask punct = static_cast<mask>(_P); |
405 | static const mask xdigit = static_cast<mask>(_X | _N); |
406 | static const mask blank = static_cast<mask>(_B); |
407 | // mask is already fully saturated, use a different type in regex_type_traits. |
408 | static const unsigned short __regex_word = 0x100; |
409 | # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT |
410 | # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA |
411 | # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT |
412 | # elif defined(__MVS__) |
413 | # if defined(__NATIVE_ASCII_F) |
414 | typedef unsigned int mask; |
415 | static const mask space = _ISSPACE_A; |
416 | static const mask print = _ISPRINT_A; |
417 | static const mask cntrl = _ISCNTRL_A; |
418 | static const mask upper = _ISUPPER_A; |
419 | static const mask lower = _ISLOWER_A; |
420 | static const mask alpha = _ISALPHA_A; |
421 | static const mask digit = _ISDIGIT_A; |
422 | static const mask punct = _ISPUNCT_A; |
423 | static const mask xdigit = _ISXDIGIT_A; |
424 | static const mask blank = _ISBLANK_A; |
425 | # else |
426 | typedef unsigned short mask; |
427 | static const mask space = __ISSPACE; |
428 | static const mask print = __ISPRINT; |
429 | static const mask cntrl = __ISCNTRL; |
430 | static const mask upper = __ISUPPER; |
431 | static const mask lower = __ISLOWER; |
432 | static const mask alpha = __ISALPHA; |
433 | static const mask digit = __ISDIGIT; |
434 | static const mask punct = __ISPUNCT; |
435 | static const mask xdigit = __ISXDIGIT; |
436 | static const mask blank = __ISBLANK; |
437 | # endif |
438 | static const mask __regex_word = 0x8000; |
439 | # else |
440 | # error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE? |
441 | # endif |
442 | static const mask alnum = alpha | digit; |
443 | static const mask graph = alnum | punct; |
444 | |
445 | _LIBCPP_HIDE_FROM_ABI ctype_base() {} |
446 | |
447 | static_assert((__regex_word & ~(std::make_unsigned<mask>::type)(space | print | cntrl | upper | lower | alpha | |
448 | digit | punct | xdigit | blank)) == __regex_word, |
449 | "__regex_word can't overlap other bits" ); |
450 | }; |
451 | |
452 | template <class _CharT> |
453 | class ctype; |
454 | |
455 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
456 | template <> |
457 | class _LIBCPP_EXPORTED_FROM_ABI ctype<wchar_t> : public locale::facet, public ctype_base { |
458 | public: |
459 | typedef wchar_t char_type; |
460 | |
461 | _LIBCPP_HIDE_FROM_ABI explicit ctype(size_t __refs = 0) : locale::facet(__refs) {} |
462 | |
463 | _LIBCPP_HIDE_FROM_ABI bool is(mask __m, char_type __c) const { return do_is(__m, __c); } |
464 | |
465 | _LIBCPP_HIDE_FROM_ABI const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const { |
466 | return do_is(__low, __high, __vec); |
467 | } |
468 | |
469 | _LIBCPP_HIDE_FROM_ABI const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const { |
470 | return do_scan_is(__m, __low, __high); |
471 | } |
472 | |
473 | _LIBCPP_HIDE_FROM_ABI const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const { |
474 | return do_scan_not(__m, __low, __high); |
475 | } |
476 | |
477 | _LIBCPP_HIDE_FROM_ABI char_type toupper(char_type __c) const { return do_toupper(__c); } |
478 | |
479 | _LIBCPP_HIDE_FROM_ABI const char_type* toupper(char_type* __low, const char_type* __high) const { |
480 | return do_toupper(__low, __high); |
481 | } |
482 | |
483 | _LIBCPP_HIDE_FROM_ABI char_type tolower(char_type __c) const { return do_tolower(__c); } |
484 | |
485 | _LIBCPP_HIDE_FROM_ABI const char_type* tolower(char_type* __low, const char_type* __high) const { |
486 | return do_tolower(__low, __high); |
487 | } |
488 | |
489 | _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const { return do_widen(__c); } |
490 | |
491 | _LIBCPP_HIDE_FROM_ABI const char* widen(const char* __low, const char* __high, char_type* __to) const { |
492 | return do_widen(__low, __high, dest: __to); |
493 | } |
494 | |
495 | _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const { return do_narrow(__c, __dfault); } |
496 | |
497 | _LIBCPP_HIDE_FROM_ABI const char_type* |
498 | narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const { |
499 | return do_narrow(__low, __high, __dfault, dest: __to); |
500 | } |
501 | |
502 | static locale::id id; |
503 | |
504 | protected: |
505 | ~ctype() override; |
506 | virtual bool do_is(mask __m, char_type __c) const; |
507 | virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; |
508 | virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; |
509 | virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; |
510 | virtual char_type do_toupper(char_type) const; |
511 | virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; |
512 | virtual char_type do_tolower(char_type) const; |
513 | virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; |
514 | virtual char_type do_widen(char) const; |
515 | virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; |
516 | virtual char do_narrow(char_type, char __dfault) const; |
517 | virtual const char_type* |
518 | do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; |
519 | }; |
520 | # endif // _LIBCPP_HAS_WIDE_CHARACTERS |
521 | |
522 | inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_isascii(int __c) { return (__c & ~0x7F) == 0; } |
523 | |
524 | template <> |
525 | class _LIBCPP_EXPORTED_FROM_ABI ctype<char> : public locale::facet, public ctype_base { |
526 | const mask* __tab_; |
527 | bool __del_; |
528 | |
529 | public: |
530 | typedef char char_type; |
531 | |
532 | explicit ctype(const mask* __tab = nullptr, bool __del = false, size_t __refs = 0); |
533 | |
534 | _LIBCPP_HIDE_FROM_ABI bool is(mask __m, char_type __c) const { |
535 | return std::__libcpp_isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) != 0 : false; |
536 | } |
537 | |
538 | _LIBCPP_HIDE_FROM_ABI const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const { |
539 | for (; __low != __high; ++__low, ++__vec) |
540 | *__vec = std::__libcpp_isascii(c: *__low) ? __tab_[static_cast<int>(*__low)] : 0; |
541 | return __low; |
542 | } |
543 | |
544 | _LIBCPP_HIDE_FROM_ABI const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const { |
545 | for (; __low != __high; ++__low) |
546 | if (std::__libcpp_isascii(c: *__low) && (__tab_[static_cast<int>(*__low)] & __m)) |
547 | break; |
548 | return __low; |
549 | } |
550 | |
551 | _LIBCPP_HIDE_FROM_ABI const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const { |
552 | for (; __low != __high; ++__low) |
553 | if (!std::__libcpp_isascii(c: *__low) || !(__tab_[static_cast<int>(*__low)] & __m)) |
554 | break; |
555 | return __low; |
556 | } |
557 | |
558 | _LIBCPP_HIDE_FROM_ABI char_type toupper(char_type __c) const { return do_toupper(__c); } |
559 | |
560 | _LIBCPP_HIDE_FROM_ABI const char_type* toupper(char_type* __low, const char_type* __high) const { |
561 | return do_toupper(__low, __high); |
562 | } |
563 | |
564 | _LIBCPP_HIDE_FROM_ABI char_type tolower(char_type __c) const { return do_tolower(__c); } |
565 | |
566 | _LIBCPP_HIDE_FROM_ABI const char_type* tolower(char_type* __low, const char_type* __high) const { |
567 | return do_tolower(__low, __high); |
568 | } |
569 | |
570 | _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const { return do_widen(__c); } |
571 | |
572 | _LIBCPP_HIDE_FROM_ABI const char* widen(const char* __low, const char* __high, char_type* __to) const { |
573 | return do_widen(__low, __high, __to); |
574 | } |
575 | |
576 | _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const { return do_narrow(__c, __dfault); } |
577 | |
578 | _LIBCPP_HIDE_FROM_ABI const char* |
579 | narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const { |
580 | return do_narrow(__low, __high, __dfault, __to); |
581 | } |
582 | |
583 | static locale::id id; |
584 | |
585 | # ifdef _CACHED_RUNES |
586 | static const size_t table_size = _CACHED_RUNES; |
587 | # else |
588 | static const size_t table_size = 256; // FIXME: Don't hardcode this. |
589 | # endif |
590 | _LIBCPP_HIDE_FROM_ABI const mask* table() const _NOEXCEPT { return __tab_; } |
591 | static const mask* classic_table() _NOEXCEPT; |
592 | # if defined(__GLIBC__) || defined(__EMSCRIPTEN__) |
593 | static const int* __classic_upper_table() _NOEXCEPT; |
594 | static const int* __classic_lower_table() _NOEXCEPT; |
595 | # endif |
596 | # if defined(__NetBSD__) |
597 | static const short* __classic_upper_table() _NOEXCEPT; |
598 | static const short* __classic_lower_table() _NOEXCEPT; |
599 | # endif |
600 | # if defined(__MVS__) |
601 | static const unsigned short* __classic_upper_table() _NOEXCEPT; |
602 | static const unsigned short* __classic_lower_table() _NOEXCEPT; |
603 | # endif |
604 | |
605 | protected: |
606 | ~ctype() override; |
607 | virtual char_type do_toupper(char_type __c) const; |
608 | virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; |
609 | virtual char_type do_tolower(char_type __c) const; |
610 | virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; |
611 | virtual char_type do_widen(char __c) const; |
612 | virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const; |
613 | virtual char do_narrow(char_type __c, char __dfault) const; |
614 | virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const; |
615 | }; |
616 | |
617 | // template <class CharT> class ctype_byname; |
618 | |
619 | template <class _CharT> |
620 | class ctype_byname; |
621 | |
622 | template <> |
623 | class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<char> : public ctype<char> { |
624 | __locale::__locale_t __l_; |
625 | |
626 | public: |
627 | explicit ctype_byname(const char*, size_t = 0); |
628 | explicit ctype_byname(const string&, size_t = 0); |
629 | |
630 | protected: |
631 | ~ctype_byname() override; |
632 | char_type do_toupper(char_type) const override; |
633 | const char_type* do_toupper(char_type* __low, const char_type* __high) const override; |
634 | char_type do_tolower(char_type) const override; |
635 | const char_type* do_tolower(char_type* __low, const char_type* __high) const override; |
636 | }; |
637 | |
638 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
639 | template <> |
640 | class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<wchar_t> : public ctype<wchar_t> { |
641 | __locale::__locale_t __l_; |
642 | |
643 | public: |
644 | explicit ctype_byname(const char*, size_t = 0); |
645 | explicit ctype_byname(const string&, size_t = 0); |
646 | |
647 | protected: |
648 | ~ctype_byname() override; |
649 | bool do_is(mask __m, char_type __c) const override; |
650 | const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const override; |
651 | const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const override; |
652 | const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const override; |
653 | char_type do_toupper(char_type) const override; |
654 | const char_type* do_toupper(char_type* __low, const char_type* __high) const override; |
655 | char_type do_tolower(char_type) const override; |
656 | const char_type* do_tolower(char_type* __low, const char_type* __high) const override; |
657 | char_type do_widen(char) const override; |
658 | const char* do_widen(const char* __low, const char* __high, char_type* __dest) const override; |
659 | char do_narrow(char_type, char __dfault) const override; |
660 | const char_type* |
661 | do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const override; |
662 | }; |
663 | # endif // _LIBCPP_HAS_WIDE_CHARACTERS |
664 | |
665 | template <class _CharT> |
666 | inline _LIBCPP_HIDE_FROM_ABI bool isspace(_CharT __c, const locale& __loc) { |
667 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); |
668 | } |
669 | |
670 | template <class _CharT> |
671 | inline _LIBCPP_HIDE_FROM_ABI bool isprint(_CharT __c, const locale& __loc) { |
672 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); |
673 | } |
674 | |
675 | template <class _CharT> |
676 | inline _LIBCPP_HIDE_FROM_ABI bool iscntrl(_CharT __c, const locale& __loc) { |
677 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); |
678 | } |
679 | |
680 | template <class _CharT> |
681 | inline _LIBCPP_HIDE_FROM_ABI bool isupper(_CharT __c, const locale& __loc) { |
682 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); |
683 | } |
684 | |
685 | template <class _CharT> |
686 | inline _LIBCPP_HIDE_FROM_ABI bool islower(_CharT __c, const locale& __loc) { |
687 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); |
688 | } |
689 | |
690 | template <class _CharT> |
691 | inline _LIBCPP_HIDE_FROM_ABI bool isalpha(_CharT __c, const locale& __loc) { |
692 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); |
693 | } |
694 | |
695 | template <class _CharT> |
696 | inline _LIBCPP_HIDE_FROM_ABI bool isdigit(_CharT __c, const locale& __loc) { |
697 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); |
698 | } |
699 | |
700 | template <class _CharT> |
701 | inline _LIBCPP_HIDE_FROM_ABI bool ispunct(_CharT __c, const locale& __loc) { |
702 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); |
703 | } |
704 | |
705 | template <class _CharT> |
706 | inline _LIBCPP_HIDE_FROM_ABI bool isxdigit(_CharT __c, const locale& __loc) { |
707 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); |
708 | } |
709 | |
710 | template <class _CharT> |
711 | inline _LIBCPP_HIDE_FROM_ABI bool isalnum(_CharT __c, const locale& __loc) { |
712 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); |
713 | } |
714 | |
715 | template <class _CharT> |
716 | inline _LIBCPP_HIDE_FROM_ABI bool isgraph(_CharT __c, const locale& __loc) { |
717 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); |
718 | } |
719 | |
720 | template <class _CharT> |
721 | _LIBCPP_HIDE_FROM_ABI bool isblank(_CharT __c, const locale& __loc) { |
722 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c); |
723 | } |
724 | |
725 | template <class _CharT> |
726 | inline _LIBCPP_HIDE_FROM_ABI _CharT toupper(_CharT __c, const locale& __loc) { |
727 | return std::use_facet<ctype<_CharT> >(__loc).toupper(__c); |
728 | } |
729 | |
730 | template <class _CharT> |
731 | inline _LIBCPP_HIDE_FROM_ABI _CharT tolower(_CharT __c, const locale& __loc) { |
732 | return std::use_facet<ctype<_CharT> >(__loc).tolower(__c); |
733 | } |
734 | |
735 | // codecvt_base |
736 | |
737 | class _LIBCPP_EXPORTED_FROM_ABI codecvt_base { |
738 | public: |
739 | _LIBCPP_HIDE_FROM_ABI codecvt_base() {} |
740 | enum result { ok, partial, error, noconv }; |
741 | }; |
742 | |
743 | // template <class internT, class externT, class stateT> class codecvt; |
744 | |
745 | template <class _InternT, class _ExternT, class _StateT> |
746 | class codecvt; |
747 | |
748 | // template <> class codecvt<char, char, mbstate_t> |
749 | |
750 | template <> |
751 | class _LIBCPP_EXPORTED_FROM_ABI codecvt<char, char, mbstate_t> : public locale::facet, public codecvt_base { |
752 | public: |
753 | typedef char intern_type; |
754 | typedef char extern_type; |
755 | typedef mbstate_t state_type; |
756 | |
757 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} |
758 | |
759 | _LIBCPP_HIDE_FROM_ABI result |
760 | out(state_type& __st, |
761 | const intern_type* __frm, |
762 | const intern_type* __frm_end, |
763 | const intern_type*& __frm_nxt, |
764 | extern_type* __to, |
765 | extern_type* __to_end, |
766 | extern_type*& __to_nxt) const { |
767 | return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
768 | } |
769 | |
770 | _LIBCPP_HIDE_FROM_ABI result |
771 | unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { |
772 | return do_unshift(__st, __to, __to_end, __to_nxt); |
773 | } |
774 | |
775 | _LIBCPP_HIDE_FROM_ABI result |
776 | in(state_type& __st, |
777 | const extern_type* __frm, |
778 | const extern_type* __frm_end, |
779 | const extern_type*& __frm_nxt, |
780 | intern_type* __to, |
781 | intern_type* __to_end, |
782 | intern_type*& __to_nxt) const { |
783 | return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
784 | } |
785 | |
786 | _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); } |
787 | |
788 | _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } |
789 | |
790 | _LIBCPP_HIDE_FROM_ABI int |
791 | length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { |
792 | return do_length(__st, __frm, __end, __mx); |
793 | } |
794 | |
795 | _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); } |
796 | |
797 | static locale::id id; |
798 | |
799 | protected: |
800 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {} |
801 | |
802 | ~codecvt() override; |
803 | |
804 | virtual result |
805 | do_out(state_type& __st, |
806 | const intern_type* __frm, |
807 | const intern_type* __frm_end, |
808 | const intern_type*& __frm_nxt, |
809 | extern_type* __to, |
810 | extern_type* __to_end, |
811 | extern_type*& __to_nxt) const; |
812 | virtual result |
813 | do_in(state_type& __st, |
814 | const extern_type* __frm, |
815 | const extern_type* __frm_end, |
816 | const extern_type*& __frm_nxt, |
817 | intern_type* __to, |
818 | intern_type* __to_end, |
819 | intern_type*& __to_nxt) const; |
820 | virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; |
821 | virtual int do_encoding() const _NOEXCEPT; |
822 | virtual bool do_always_noconv() const _NOEXCEPT; |
823 | virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const; |
824 | virtual int do_max_length() const _NOEXCEPT; |
825 | }; |
826 | |
827 | // template <> class codecvt<wchar_t, char, mbstate_t> |
828 | |
829 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
830 | template <> |
831 | class _LIBCPP_EXPORTED_FROM_ABI codecvt<wchar_t, char, mbstate_t> : public locale::facet, public codecvt_base { |
832 | __locale::__locale_t __l_; |
833 | |
834 | public: |
835 | typedef wchar_t intern_type; |
836 | typedef char extern_type; |
837 | typedef mbstate_t state_type; |
838 | |
839 | explicit codecvt(size_t __refs = 0); |
840 | |
841 | _LIBCPP_HIDE_FROM_ABI result |
842 | out(state_type& __st, |
843 | const intern_type* __frm, |
844 | const intern_type* __frm_end, |
845 | const intern_type*& __frm_nxt, |
846 | extern_type* __to, |
847 | extern_type* __to_end, |
848 | extern_type*& __to_nxt) const { |
849 | return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
850 | } |
851 | |
852 | _LIBCPP_HIDE_FROM_ABI result |
853 | unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { |
854 | return do_unshift(__st, __to, __to_end, __to_nxt); |
855 | } |
856 | |
857 | _LIBCPP_HIDE_FROM_ABI result |
858 | in(state_type& __st, |
859 | const extern_type* __frm, |
860 | const extern_type* __frm_end, |
861 | const extern_type*& __frm_nxt, |
862 | intern_type* __to, |
863 | intern_type* __to_end, |
864 | intern_type*& __to_nxt) const { |
865 | return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
866 | } |
867 | |
868 | _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); } |
869 | |
870 | _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } |
871 | |
872 | _LIBCPP_HIDE_FROM_ABI int |
873 | length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { |
874 | return do_length(__st, __frm, __end, __mx); |
875 | } |
876 | |
877 | _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); } |
878 | |
879 | static locale::id id; |
880 | |
881 | protected: |
882 | explicit codecvt(const char*, size_t __refs = 0); |
883 | |
884 | ~codecvt() override; |
885 | |
886 | virtual result |
887 | do_out(state_type& __st, |
888 | const intern_type* __frm, |
889 | const intern_type* __frm_end, |
890 | const intern_type*& __frm_nxt, |
891 | extern_type* __to, |
892 | extern_type* __to_end, |
893 | extern_type*& __to_nxt) const; |
894 | virtual result |
895 | do_in(state_type& __st, |
896 | const extern_type* __frm, |
897 | const extern_type* __frm_end, |
898 | const extern_type*& __frm_nxt, |
899 | intern_type* __to, |
900 | intern_type* __to_end, |
901 | intern_type*& __to_nxt) const; |
902 | virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; |
903 | virtual int do_encoding() const _NOEXCEPT; |
904 | virtual bool do_always_noconv() const _NOEXCEPT; |
905 | virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; |
906 | virtual int do_max_length() const _NOEXCEPT; |
907 | }; |
908 | # endif // _LIBCPP_HAS_WIDE_CHARACTERS |
909 | |
910 | // template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20 |
911 | |
912 | template <> |
913 | class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char, mbstate_t> |
914 | : public locale::facet, public codecvt_base { |
915 | public: |
916 | typedef char16_t intern_type; |
917 | typedef char extern_type; |
918 | typedef mbstate_t state_type; |
919 | |
920 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} |
921 | |
922 | _LIBCPP_HIDE_FROM_ABI result |
923 | out(state_type& __st, |
924 | const intern_type* __frm, |
925 | const intern_type* __frm_end, |
926 | const intern_type*& __frm_nxt, |
927 | extern_type* __to, |
928 | extern_type* __to_end, |
929 | extern_type*& __to_nxt) const { |
930 | return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
931 | } |
932 | |
933 | _LIBCPP_HIDE_FROM_ABI result |
934 | unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { |
935 | return do_unshift(__st, __to, __to_end, __to_nxt); |
936 | } |
937 | |
938 | _LIBCPP_HIDE_FROM_ABI result |
939 | in(state_type& __st, |
940 | const extern_type* __frm, |
941 | const extern_type* __frm_end, |
942 | const extern_type*& __frm_nxt, |
943 | intern_type* __to, |
944 | intern_type* __to_end, |
945 | intern_type*& __to_nxt) const { |
946 | return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
947 | } |
948 | |
949 | _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); } |
950 | |
951 | _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } |
952 | |
953 | _LIBCPP_HIDE_FROM_ABI int |
954 | length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { |
955 | return do_length(__st, __frm, __end, __mx); |
956 | } |
957 | |
958 | _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); } |
959 | |
960 | static locale::id id; |
961 | |
962 | protected: |
963 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {} |
964 | |
965 | ~codecvt() override; |
966 | |
967 | virtual result |
968 | do_out(state_type& __st, |
969 | const intern_type* __frm, |
970 | const intern_type* __frm_end, |
971 | const intern_type*& __frm_nxt, |
972 | extern_type* __to, |
973 | extern_type* __to_end, |
974 | extern_type*& __to_nxt) const; |
975 | virtual result |
976 | do_in(state_type& __st, |
977 | const extern_type* __frm, |
978 | const extern_type* __frm_end, |
979 | const extern_type*& __frm_nxt, |
980 | intern_type* __to, |
981 | intern_type* __to_end, |
982 | intern_type*& __to_nxt) const; |
983 | virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; |
984 | virtual int do_encoding() const _NOEXCEPT; |
985 | virtual bool do_always_noconv() const _NOEXCEPT; |
986 | virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; |
987 | virtual int do_max_length() const _NOEXCEPT; |
988 | }; |
989 | |
990 | # if _LIBCPP_HAS_CHAR8_T |
991 | |
992 | // template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20 |
993 | |
994 | template <> |
995 | class _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char8_t, mbstate_t> : public locale::facet, public codecvt_base { |
996 | public: |
997 | typedef char16_t intern_type; |
998 | typedef char8_t extern_type; |
999 | typedef mbstate_t state_type; |
1000 | |
1001 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} |
1002 | |
1003 | _LIBCPP_HIDE_FROM_ABI result |
1004 | out(state_type& __st, |
1005 | const intern_type* __frm, |
1006 | const intern_type* __frm_end, |
1007 | const intern_type*& __frm_nxt, |
1008 | extern_type* __to, |
1009 | extern_type* __to_end, |
1010 | extern_type*& __to_nxt) const { |
1011 | return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
1012 | } |
1013 | |
1014 | _LIBCPP_HIDE_FROM_ABI result |
1015 | unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { |
1016 | return do_unshift(__st, __to, __to_end, __to_nxt); |
1017 | } |
1018 | |
1019 | _LIBCPP_HIDE_FROM_ABI result |
1020 | in(state_type& __st, |
1021 | const extern_type* __frm, |
1022 | const extern_type* __frm_end, |
1023 | const extern_type*& __frm_nxt, |
1024 | intern_type* __to, |
1025 | intern_type* __to_end, |
1026 | intern_type*& __to_nxt) const { |
1027 | return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
1028 | } |
1029 | |
1030 | _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); } |
1031 | |
1032 | _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } |
1033 | |
1034 | _LIBCPP_HIDE_FROM_ABI int |
1035 | length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { |
1036 | return do_length(__st, __frm, __end, __mx); |
1037 | } |
1038 | |
1039 | _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); } |
1040 | |
1041 | static locale::id id; |
1042 | |
1043 | protected: |
1044 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {} |
1045 | |
1046 | ~codecvt() override; |
1047 | |
1048 | virtual result |
1049 | do_out(state_type& __st, |
1050 | const intern_type* __frm, |
1051 | const intern_type* __frm_end, |
1052 | const intern_type*& __frm_nxt, |
1053 | extern_type* __to, |
1054 | extern_type* __to_end, |
1055 | extern_type*& __to_nxt) const; |
1056 | virtual result |
1057 | do_in(state_type& __st, |
1058 | const extern_type* __frm, |
1059 | const extern_type* __frm_end, |
1060 | const extern_type*& __frm_nxt, |
1061 | intern_type* __to, |
1062 | intern_type* __to_end, |
1063 | intern_type*& __to_nxt) const; |
1064 | virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; |
1065 | virtual int do_encoding() const _NOEXCEPT; |
1066 | virtual bool do_always_noconv() const _NOEXCEPT; |
1067 | virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; |
1068 | virtual int do_max_length() const _NOEXCEPT; |
1069 | }; |
1070 | |
1071 | # endif |
1072 | |
1073 | // template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20 |
1074 | |
1075 | template <> |
1076 | class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char, mbstate_t> |
1077 | : public locale::facet, public codecvt_base { |
1078 | public: |
1079 | typedef char32_t intern_type; |
1080 | typedef char extern_type; |
1081 | typedef mbstate_t state_type; |
1082 | |
1083 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} |
1084 | |
1085 | _LIBCPP_HIDE_FROM_ABI result |
1086 | out(state_type& __st, |
1087 | const intern_type* __frm, |
1088 | const intern_type* __frm_end, |
1089 | const intern_type*& __frm_nxt, |
1090 | extern_type* __to, |
1091 | extern_type* __to_end, |
1092 | extern_type*& __to_nxt) const { |
1093 | return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
1094 | } |
1095 | |
1096 | _LIBCPP_HIDE_FROM_ABI result |
1097 | unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { |
1098 | return do_unshift(__st, __to, __to_end, __to_nxt); |
1099 | } |
1100 | |
1101 | _LIBCPP_HIDE_FROM_ABI result |
1102 | in(state_type& __st, |
1103 | const extern_type* __frm, |
1104 | const extern_type* __frm_end, |
1105 | const extern_type*& __frm_nxt, |
1106 | intern_type* __to, |
1107 | intern_type* __to_end, |
1108 | intern_type*& __to_nxt) const { |
1109 | return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
1110 | } |
1111 | |
1112 | _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); } |
1113 | |
1114 | _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } |
1115 | |
1116 | _LIBCPP_HIDE_FROM_ABI int |
1117 | length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { |
1118 | return do_length(__st, __frm, __end, __mx); |
1119 | } |
1120 | |
1121 | _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); } |
1122 | |
1123 | static locale::id id; |
1124 | |
1125 | protected: |
1126 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {} |
1127 | |
1128 | ~codecvt() override; |
1129 | |
1130 | virtual result |
1131 | do_out(state_type& __st, |
1132 | const intern_type* __frm, |
1133 | const intern_type* __frm_end, |
1134 | const intern_type*& __frm_nxt, |
1135 | extern_type* __to, |
1136 | extern_type* __to_end, |
1137 | extern_type*& __to_nxt) const; |
1138 | virtual result |
1139 | do_in(state_type& __st, |
1140 | const extern_type* __frm, |
1141 | const extern_type* __frm_end, |
1142 | const extern_type*& __frm_nxt, |
1143 | intern_type* __to, |
1144 | intern_type* __to_end, |
1145 | intern_type*& __to_nxt) const; |
1146 | virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; |
1147 | virtual int do_encoding() const _NOEXCEPT; |
1148 | virtual bool do_always_noconv() const _NOEXCEPT; |
1149 | virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; |
1150 | virtual int do_max_length() const _NOEXCEPT; |
1151 | }; |
1152 | |
1153 | # if _LIBCPP_HAS_CHAR8_T |
1154 | |
1155 | // template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20 |
1156 | |
1157 | template <> |
1158 | class _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char8_t, mbstate_t> : public locale::facet, public codecvt_base { |
1159 | public: |
1160 | typedef char32_t intern_type; |
1161 | typedef char8_t extern_type; |
1162 | typedef mbstate_t state_type; |
1163 | |
1164 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} |
1165 | |
1166 | _LIBCPP_HIDE_FROM_ABI result |
1167 | out(state_type& __st, |
1168 | const intern_type* __frm, |
1169 | const intern_type* __frm_end, |
1170 | const intern_type*& __frm_nxt, |
1171 | extern_type* __to, |
1172 | extern_type* __to_end, |
1173 | extern_type*& __to_nxt) const { |
1174 | return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
1175 | } |
1176 | |
1177 | _LIBCPP_HIDE_FROM_ABI result |
1178 | unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { |
1179 | return do_unshift(__st, __to, __to_end, __to_nxt); |
1180 | } |
1181 | |
1182 | _LIBCPP_HIDE_FROM_ABI result |
1183 | in(state_type& __st, |
1184 | const extern_type* __frm, |
1185 | const extern_type* __frm_end, |
1186 | const extern_type*& __frm_nxt, |
1187 | intern_type* __to, |
1188 | intern_type* __to_end, |
1189 | intern_type*& __to_nxt) const { |
1190 | return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); |
1191 | } |
1192 | |
1193 | _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); } |
1194 | |
1195 | _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } |
1196 | |
1197 | _LIBCPP_HIDE_FROM_ABI int |
1198 | length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { |
1199 | return do_length(__st, __frm, __end, __mx); |
1200 | } |
1201 | |
1202 | _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); } |
1203 | |
1204 | static locale::id id; |
1205 | |
1206 | protected: |
1207 | _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {} |
1208 | |
1209 | ~codecvt() override; |
1210 | |
1211 | virtual result |
1212 | do_out(state_type& __st, |
1213 | const intern_type* __frm, |
1214 | const intern_type* __frm_end, |
1215 | const intern_type*& __frm_nxt, |
1216 | extern_type* __to, |
1217 | extern_type* __to_end, |
1218 | extern_type*& __to_nxt) const; |
1219 | virtual result |
1220 | do_in(state_type& __st, |
1221 | const extern_type* __frm, |
1222 | const extern_type* __frm_end, |
1223 | const extern_type*& __frm_nxt, |
1224 | intern_type* __to, |
1225 | intern_type* __to_end, |
1226 | intern_type*& __to_nxt) const; |
1227 | virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; |
1228 | virtual int do_encoding() const _NOEXCEPT; |
1229 | virtual bool do_always_noconv() const _NOEXCEPT; |
1230 | virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; |
1231 | virtual int do_max_length() const _NOEXCEPT; |
1232 | }; |
1233 | |
1234 | # endif |
1235 | |
1236 | // template <class _InternT, class _ExternT, class _StateT> class codecvt_byname |
1237 | |
1238 | template <class _InternT, class _ExternT, class _StateT> |
1239 | class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> { |
1240 | public: |
1241 | _LIBCPP_HIDE_FROM_ABI explicit codecvt_byname(const char* __nm, size_t __refs = 0) |
1242 | : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {} |
1243 | _LIBCPP_HIDE_FROM_ABI explicit codecvt_byname(const string& __nm, size_t __refs = 0) |
1244 | : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {} |
1245 | |
1246 | protected: |
1247 | ~codecvt_byname() override; |
1248 | }; |
1249 | |
1250 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
1251 | template <class _InternT, class _ExternT, class _StateT> |
1252 | codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() {} |
1253 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
1254 | |
1255 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>; |
1256 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
1257 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>; |
1258 | # endif |
1259 | extern template class _LIBCPP_DEPRECATED_IN_CXX20 |
1260 | _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>; // deprecated in C++20 |
1261 | extern template class _LIBCPP_DEPRECATED_IN_CXX20 |
1262 | _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>; // deprecated in C++20 |
1263 | # if _LIBCPP_HAS_CHAR8_T |
1264 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>; // C++20 |
1265 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>; // C++20 |
1266 | # endif |
1267 | |
1268 | template <size_t _Np> |
1269 | struct __narrow_to_utf8 { |
1270 | template <class _OutputIterator, class _CharT> |
1271 | _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const; |
1272 | }; |
1273 | |
1274 | template <> |
1275 | struct __narrow_to_utf8<8> { |
1276 | template <class _OutputIterator, class _CharT> |
1277 | _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const { |
1278 | for (; __wb < __we; ++__wb, ++__s) |
1279 | *__s = *__wb; |
1280 | return __s; |
1281 | } |
1282 | }; |
1283 | |
1284 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
1285 | template <> |
1286 | struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<16> : public codecvt<char16_t, char, mbstate_t> { |
1287 | _LIBCPP_HIDE_FROM_ABI __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} |
1288 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
1289 | |
1290 | ~__narrow_to_utf8() override; |
1291 | |
1292 | template <class _OutputIterator, class _CharT> |
1293 | _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const { |
1294 | result __r = ok; |
1295 | mbstate_t __mb; |
1296 | while (__wb < __we && __r != error) { |
1297 | const int __sz = 32; |
1298 | char __buf[__sz]; |
1299 | char* __bn; |
1300 | const char16_t* __wn = (const char16_t*)__wb; |
1301 | __r = do_out(st&: __mb, frm: (const char16_t*)__wb, frm_end: (const char16_t*)__we, frm_nxt&: __wn, to: __buf, to_end: __buf + __sz, to_nxt&: __bn); |
1302 | if (__r == codecvt_base::error || __wn == (const char16_t*)__wb) |
1303 | std::__throw_runtime_error("locale not supported" ); |
1304 | for (const char* __p = __buf; __p < __bn; ++__p, ++__s) |
1305 | *__s = *__p; |
1306 | __wb = (const _CharT*)__wn; |
1307 | } |
1308 | return __s; |
1309 | } |
1310 | }; |
1311 | |
1312 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
1313 | template <> |
1314 | struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<32> : public codecvt<char32_t, char, mbstate_t> { |
1315 | _LIBCPP_HIDE_FROM_ABI __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} |
1316 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
1317 | |
1318 | ~__narrow_to_utf8() override; |
1319 | |
1320 | template <class _OutputIterator, class _CharT> |
1321 | _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const { |
1322 | result __r = ok; |
1323 | mbstate_t __mb; |
1324 | while (__wb < __we && __r != error) { |
1325 | const int __sz = 32; |
1326 | char __buf[__sz]; |
1327 | char* __bn; |
1328 | const char32_t* __wn = (const char32_t*)__wb; |
1329 | __r = do_out(st&: __mb, frm: (const char32_t*)__wb, frm_end: (const char32_t*)__we, frm_nxt&: __wn, to: __buf, to_end: __buf + __sz, to_nxt&: __bn); |
1330 | if (__r == codecvt_base::error || __wn == (const char32_t*)__wb) |
1331 | std::__throw_runtime_error("locale not supported" ); |
1332 | for (const char* __p = __buf; __p < __bn; ++__p, ++__s) |
1333 | *__s = *__p; |
1334 | __wb = (const _CharT*)__wn; |
1335 | } |
1336 | return __s; |
1337 | } |
1338 | }; |
1339 | |
1340 | template <size_t _Np> |
1341 | struct __widen_from_utf8 { |
1342 | template <class _OutputIterator> |
1343 | _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; |
1344 | }; |
1345 | |
1346 | template <> |
1347 | struct __widen_from_utf8<8> { |
1348 | template <class _OutputIterator> |
1349 | _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const { |
1350 | for (; __nb < __ne; ++__nb, ++__s) |
1351 | *__s = *__nb; |
1352 | return __s; |
1353 | } |
1354 | }; |
1355 | |
1356 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
1357 | template <> |
1358 | struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<16> : public codecvt<char16_t, char, mbstate_t> { |
1359 | _LIBCPP_HIDE_FROM_ABI __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} |
1360 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
1361 | |
1362 | ~__widen_from_utf8() override; |
1363 | |
1364 | template <class _OutputIterator> |
1365 | _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const { |
1366 | result __r = ok; |
1367 | mbstate_t __mb; |
1368 | while (__nb < __ne && __r != error) { |
1369 | const int __sz = 32; |
1370 | char16_t __buf[__sz]; |
1371 | char16_t* __bn; |
1372 | const char* __nn = __nb; |
1373 | __r = do_in(st&: __mb, frm: __nb, frm_end: __ne - __nb > __sz ? __nb + __sz : __ne, frm_nxt&: __nn, to: __buf, to_end: __buf + __sz, to_nxt&: __bn); |
1374 | if (__r == codecvt_base::error || __nn == __nb) |
1375 | std::__throw_runtime_error("locale not supported" ); |
1376 | for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) |
1377 | *__s = *__p; |
1378 | __nb = __nn; |
1379 | } |
1380 | return __s; |
1381 | } |
1382 | }; |
1383 | |
1384 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
1385 | template <> |
1386 | struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<32> : public codecvt<char32_t, char, mbstate_t> { |
1387 | _LIBCPP_HIDE_FROM_ABI __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} |
1388 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
1389 | |
1390 | ~__widen_from_utf8() override; |
1391 | |
1392 | template <class _OutputIterator> |
1393 | _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const { |
1394 | result __r = ok; |
1395 | mbstate_t __mb; |
1396 | while (__nb < __ne && __r != error) { |
1397 | const int __sz = 32; |
1398 | char32_t __buf[__sz]; |
1399 | char32_t* __bn; |
1400 | const char* __nn = __nb; |
1401 | __r = do_in(st&: __mb, frm: __nb, frm_end: __ne - __nb > __sz ? __nb + __sz : __ne, frm_nxt&: __nn, to: __buf, to_end: __buf + __sz, to_nxt&: __bn); |
1402 | if (__r == codecvt_base::error || __nn == __nb) |
1403 | std::__throw_runtime_error("locale not supported" ); |
1404 | for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) |
1405 | *__s = *__p; |
1406 | __nb = __nn; |
1407 | } |
1408 | return __s; |
1409 | } |
1410 | }; |
1411 | |
1412 | // template <class charT> class numpunct |
1413 | |
1414 | template <class _CharT> |
1415 | class numpunct; |
1416 | |
1417 | template <> |
1418 | class _LIBCPP_EXPORTED_FROM_ABI numpunct<char> : public locale::facet { |
1419 | public: |
1420 | typedef char char_type; |
1421 | typedef basic_string<char_type> string_type; |
1422 | |
1423 | explicit numpunct(size_t __refs = 0); |
1424 | |
1425 | _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); } |
1426 | _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); } |
1427 | _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); } |
1428 | _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); } |
1429 | _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); } |
1430 | |
1431 | static locale::id id; |
1432 | |
1433 | protected: |
1434 | ~numpunct() override; |
1435 | virtual char_type do_decimal_point() const; |
1436 | virtual char_type do_thousands_sep() const; |
1437 | virtual string do_grouping() const; |
1438 | virtual string_type do_truename() const; |
1439 | virtual string_type do_falsename() const; |
1440 | |
1441 | char_type __decimal_point_; |
1442 | char_type __thousands_sep_; |
1443 | string __grouping_; |
1444 | }; |
1445 | |
1446 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
1447 | template <> |
1448 | class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t> : public locale::facet { |
1449 | public: |
1450 | typedef wchar_t char_type; |
1451 | typedef basic_string<char_type> string_type; |
1452 | |
1453 | explicit numpunct(size_t __refs = 0); |
1454 | |
1455 | _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); } |
1456 | _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); } |
1457 | _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); } |
1458 | _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); } |
1459 | _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); } |
1460 | |
1461 | static locale::id id; |
1462 | |
1463 | protected: |
1464 | ~numpunct() override; |
1465 | virtual char_type do_decimal_point() const; |
1466 | virtual char_type do_thousands_sep() const; |
1467 | virtual string do_grouping() const; |
1468 | virtual string_type do_truename() const; |
1469 | virtual string_type do_falsename() const; |
1470 | |
1471 | char_type __decimal_point_; |
1472 | char_type __thousands_sep_; |
1473 | string __grouping_; |
1474 | }; |
1475 | # endif // _LIBCPP_HAS_WIDE_CHARACTERS |
1476 | |
1477 | // template <class charT> class numpunct_byname |
1478 | |
1479 | template <class _CharT> |
1480 | class numpunct_byname; |
1481 | |
1482 | template <> |
1483 | class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char> : public numpunct<char> { |
1484 | public: |
1485 | typedef char char_type; |
1486 | typedef basic_string<char_type> string_type; |
1487 | |
1488 | explicit numpunct_byname(const char* __nm, size_t __refs = 0); |
1489 | explicit numpunct_byname(const string& __nm, size_t __refs = 0); |
1490 | |
1491 | protected: |
1492 | ~numpunct_byname() override; |
1493 | |
1494 | private: |
1495 | void __init(const char*); |
1496 | }; |
1497 | |
1498 | # if _LIBCPP_HAS_WIDE_CHARACTERS |
1499 | template <> |
1500 | class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t> : public numpunct<wchar_t> { |
1501 | public: |
1502 | typedef wchar_t char_type; |
1503 | typedef basic_string<char_type> string_type; |
1504 | |
1505 | explicit numpunct_byname(const char* __nm, size_t __refs = 0); |
1506 | explicit numpunct_byname(const string& __nm, size_t __refs = 0); |
1507 | |
1508 | protected: |
1509 | ~numpunct_byname() override; |
1510 | |
1511 | private: |
1512 | void __init(const char*); |
1513 | }; |
1514 | # endif // _LIBCPP_HAS_WIDE_CHARACTERS |
1515 | |
1516 | _LIBCPP_END_NAMESPACE_STD |
1517 | |
1518 | #endif // _LIBCPP_HAS_LOCALIZATION |
1519 | |
1520 | #endif // _LIBCPP___LOCALE |
1521 | |