blob: 1cafca74f7ef6928cdad0920511b4370b30eff98 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// 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
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___LOCALE
11#define _LIBCPP___LOCALE
12
13#include <__config>
14#include <string>
15#include <memory>
16#include <utility>
17#include <mutex>
18#include <cstdint>
19#include <cctype>
Howard Hinnant155c2af2010-05-24 17:49:41 +000020#include <locale.h>
Eric Fiselierbb999f92017-05-31 22:14:05 +000021#if defined(_LIBCPP_MSVCRT_LIKE)
Thomas Anderson094acbc2019-03-27 18:09:30 +000022# include <cstring>
Howard Hinnantae0f80b2011-09-29 20:33:10 +000023# include <support/win32/locale_win32.h>
Marshall Clow2f96ec62014-03-11 17:18:47 +000024#elif defined(_AIX)
Howard Hinnantea382952013-08-14 18:00:20 +000025# include <support/ibm/xlocale.h>
Marshall Clow3477ec92014-07-10 15:20:28 +000026#elif defined(__ANDROID__)
Saleem Abdulrasoolac039f32018-04-13 18:14:57 +000027# include <support/android/locale_bionic.h>
Eric Fiselier7274c652014-11-25 21:57:41 +000028#elif defined(__sun__)
Eric Fiselier90adc202015-01-23 22:22:36 +000029# include <xlocale.h>
Eric Fiselier7274c652014-11-25 21:57:41 +000030# include <support/solaris/xlocale.h>
Sergey Dmitrouk9935bd42014-12-12 08:36:16 +000031#elif defined(_NEWLIB_VERSION)
32# include <support/newlib/xlocale.h>
Eric Fiseliercee57932017-08-03 04:28:10 +000033#elif (defined(__APPLE__) || defined(__FreeBSD__) \
Eric Fiselier7274c652014-11-25 21:57:41 +000034 || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
Howard Hinnantdd0d7022011-09-22 19:10:18 +000035# include <xlocale.h>
Petr Hosekfdb4a872017-04-13 21:29:21 +000036#elif defined(__Fuchsia__)
37# include <support/fuchsia/xlocale.h>
Dan Gohman280fd6b2019-05-01 16:47:30 +000038#elif defined(__wasi__)
39// WASI libc uses musl's locales support.
40# include <support/musl/xlocale.h>
Vasileios Kalintiris281b4cf2015-11-09 10:21:04 +000041#elif defined(_LIBCPP_HAS_MUSL_LIBC)
42# include <support/musl/xlocale.h>
Petr Hosekfdb4a872017-04-13 21:29:21 +000043#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000044
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000045#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +000046#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000047#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000048
49_LIBCPP_BEGIN_NAMESPACE_STD
50
Martin Storsjo5482ac62017-11-23 10:38:18 +000051#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
Eric Fiselierebc2d2c2017-05-08 22:02:43 +000052struct __libcpp_locale_guard {
53 _LIBCPP_INLINE_VISIBILITY
54 __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
55
56 _LIBCPP_INLINE_VISIBILITY
57 ~__libcpp_locale_guard() {
58 if (__old_loc_)
59 uselocale(__old_loc_);
60 }
61
62 locale_t __old_loc_;
63private:
64 __libcpp_locale_guard(__libcpp_locale_guard const&);
65 __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
66};
Martin Storsjo5482ac62017-11-23 10:38:18 +000067#elif defined(_LIBCPP_MSVCRT_LIKE)
68struct __libcpp_locale_guard {
69 __libcpp_locale_guard(locale_t __l) :
Thomas Anderson094acbc2019-03-27 18:09:30 +000070 __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
71 // Setting the locale can be expensive even when the locale given is
72 // already the current locale, so do an explicit check to see if the
73 // current locale is already the one we want.
74 const char* __lc = __setlocale(nullptr);
75 // If every category is the same, the locale string will simply be the
76 // locale name, otherwise it will be a semicolon-separated string listing
77 // each category. In the second case, we know at least one category won't
78 // be what we want, so we only have to check the first case.
79 if (strcmp(__l.__get_locale(), __lc) != 0) {
80 __locale_all = _strdup(__lc);
81 if (__locale_all == nullptr)
82 __throw_bad_alloc();
83 __setlocale(__l.__get_locale());
84 }
85 }
Martin Storsjo5482ac62017-11-23 10:38:18 +000086 ~__libcpp_locale_guard() {
Thomas Anderson094acbc2019-03-27 18:09:30 +000087 // The CRT documentation doesn't explicitly say, but setlocale() does the
88 // right thing when given a semicolon-separated list of locale settings
89 // for the different categories in the same format as returned by
90 // setlocale(LC_ALL, nullptr).
91 if (__locale_all != nullptr) {
92 __setlocale(__locale_all);
93 free(__locale_all);
94 }
95 _configthreadlocale(__status);
96 }
97 static const char* __setlocale(const char* __locale) {
98 const char* __new_locale = setlocale(LC_ALL, __locale);
99 if (__new_locale == nullptr)
100 __throw_bad_alloc();
101 return __new_locale;
Martin Storsjo5482ac62017-11-23 10:38:18 +0000102 }
103 int __status;
Thomas Anderson094acbc2019-03-27 18:09:30 +0000104 char* __locale_all = nullptr;
Martin Storsjo5482ac62017-11-23 10:38:18 +0000105};
Eric Fiselierebc2d2c2017-05-08 22:02:43 +0000106#endif
107
108
Howard Hinnant8331b762013-03-06 23:30:19 +0000109class _LIBCPP_TYPE_VIS locale;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000110
Howard Hinnanta54386e2012-09-14 00:39:16 +0000111template <class _Facet>
112_LIBCPP_INLINE_VISIBILITY
113bool
114has_facet(const locale&) _NOEXCEPT;
115
116template <class _Facet>
117_LIBCPP_INLINE_VISIBILITY
118const _Facet&
119use_facet(const locale&);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000120
Howard Hinnant8331b762013-03-06 23:30:19 +0000121class _LIBCPP_TYPE_VIS locale
Howard Hinnantc51e1022010-05-11 19:42:16 +0000122{
123public:
124 // types:
Howard Hinnant8331b762013-03-06 23:30:19 +0000125 class _LIBCPP_TYPE_VIS facet;
126 class _LIBCPP_TYPE_VIS id;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000127
128 typedef int category;
Mehdi Amini228053d2017-05-04 17:08:54 +0000129 _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000130 static const category // values assigned here are for exposition only
131 none = 0,
132 collate = LC_COLLATE_MASK,
133 ctype = LC_CTYPE_MASK,
134 monetary = LC_MONETARY_MASK,
135 numeric = LC_NUMERIC_MASK,
136 time = LC_TIME_MASK,
137 messages = LC_MESSAGES_MASK,
138 all = collate | ctype | monetary | numeric | time | messages;
139
140 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000141 locale() _NOEXCEPT;
142 locale(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000143 explicit locale(const char*);
144 explicit locale(const string&);
145 locale(const locale&, const char*, category);
146 locale(const locale&, const string&, category);
Howard Hinnantcf823322010-12-17 14:46:43 +0000147 template <class _Facet>
148 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000149 locale(const locale&, const locale&, category);
150
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000151 ~locale();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000152
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000153 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000154
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000155 template <class _Facet>
156 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
157 locale combine(const locale&) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000158
159 // locale operations:
160 string name() const;
161 bool operator==(const locale&) const;
162 bool operator!=(const locale& __y) const {return !(*this == __y);}
163 template <class _CharT, class _Traits, class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000164 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000165 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
166 const basic_string<_CharT, _Traits, _Allocator>&) const;
167
168 // global locale objects:
169 static locale global(const locale&);
170 static const locale& classic();
171
172private:
173 class __imp;
174 __imp* __locale_;
175
176 void __install_ctor(const locale&, facet*, long);
177 static locale& __global();
178 bool has_facet(id&) const;
179 const facet* use_facet(id&) const;
180
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000181 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000182 template <class _Facet> friend const _Facet& use_facet(const locale&);
183};
184
Howard Hinnant8331b762013-03-06 23:30:19 +0000185class _LIBCPP_TYPE_VIS locale::facet
Howard Hinnantc51e1022010-05-11 19:42:16 +0000186 : public __shared_count
187{
188protected:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000190 explicit facet(size_t __refs = 0)
191 : __shared_count(static_cast<long>(__refs)-1) {}
192
193 virtual ~facet();
194
195// facet(const facet&) = delete; // effectively done in __shared_count
196// void operator=(const facet&) = delete;
197private:
Howard Hinnant719bda32011-05-28 14:41:13 +0000198 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000199};
200
Howard Hinnant8331b762013-03-06 23:30:19 +0000201class _LIBCPP_TYPE_VIS locale::id
Howard Hinnantc51e1022010-05-11 19:42:16 +0000202{
203 once_flag __flag_;
204 int32_t __id_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000205
Howard Hinnantc51e1022010-05-11 19:42:16 +0000206 static int32_t __next_id;
207public:
Howard Hinnantac7d9f02012-07-26 16:14:37 +0000208 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000209private:
210 void __init();
211 void operator=(const id&); // = delete;
212 id(const id&); // = delete;
213public: // only needed for tests
214 long __get();
215
216 friend class locale;
217 friend class locale::__imp;
218};
219
220template <class _Facet>
221inline _LIBCPP_INLINE_VISIBILITY
222locale::locale(const locale& __other, _Facet* __f)
223{
224 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
225}
226
227template <class _Facet>
228locale
229locale::combine(const locale& __other) const
230{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000231 if (!_VSTD::has_facet<_Facet>(__other))
Marshall Clow8fea1612016-08-25 15:09:01 +0000232 __throw_runtime_error("locale::combine: locale missing facet");
233
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000234 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000235}
236
237template <class _Facet>
238inline _LIBCPP_INLINE_VISIBILITY
239bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000240has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000241{
242 return __l.has_facet(_Facet::id);
243}
244
245template <class _Facet>
246inline _LIBCPP_INLINE_VISIBILITY
247const _Facet&
248use_facet(const locale& __l)
249{
250 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
251}
252
253// template <class _CharT> class collate;
254
255template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000256class _LIBCPP_TEMPLATE_VIS collate
Howard Hinnantc51e1022010-05-11 19:42:16 +0000257 : public locale::facet
258{
259public:
260 typedef _CharT char_type;
261 typedef basic_string<char_type> string_type;
262
Howard Hinnant9833cad2010-09-21 18:58:51 +0000263 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000264 explicit collate(size_t __refs = 0)
265 : locale::facet(__refs) {}
266
Howard Hinnant9833cad2010-09-21 18:58:51 +0000267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000268 int compare(const char_type* __lo1, const char_type* __hi1,
269 const char_type* __lo2, const char_type* __hi2) const
270 {
271 return do_compare(__lo1, __hi1, __lo2, __hi2);
272 }
273
Eric Fiselier39b86ea2019-03-08 23:59:29 +0000274 // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work
275 // around a dllimport bug that expects an external instantiation.
Howard Hinnant9833cad2010-09-21 18:58:51 +0000276 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier39b86ea2019-03-08 23:59:29 +0000277 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +0000278 string_type transform(const char_type* __lo, const char_type* __hi) const
279 {
280 return do_transform(__lo, __hi);
281 }
282
Howard Hinnant9833cad2010-09-21 18:58:51 +0000283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000284 long hash(const char_type* __lo, const char_type* __hi) const
285 {
286 return do_hash(__lo, __hi);
287 }
288
289 static locale::id id;
290
291protected:
292 ~collate();
293 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
294 const char_type* __lo2, const char_type* __hi2) const;
295 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
296 {return string_type(__lo, __hi);}
297 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
298};
299
300template <class _CharT> locale::id collate<_CharT>::id;
301
302template <class _CharT>
303collate<_CharT>::~collate()
304{
305}
306
307template <class _CharT>
308int
309collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
310 const char_type* __lo2, const char_type* __hi2) const
311{
312 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
313 {
314 if (__lo1 == __hi1 || *__lo1 < *__lo2)
315 return -1;
316 if (*__lo2 < *__lo1)
317 return 1;
318 }
319 return __lo1 != __hi1;
320}
321
322template <class _CharT>
323long
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000324collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325{
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000326 size_t __h = 0;
327 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
328 const size_t __mask = size_t(0xF) << (__sr + 4);
329 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000330 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000331 __h = (__h << 4) + static_cast<size_t>(*__p);
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000332 size_t __g = __h & __mask;
333 __h ^= __g | (__g >> __sr);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000334 }
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000335 return static_cast<long>(__h);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000336}
337
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000338_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>)
339_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000340
341// template <class CharT> class collate_byname;
342
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000343template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000344
345template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000346class _LIBCPP_TYPE_VIS collate_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000347 : public collate<char>
348{
349 locale_t __l;
350public:
351 typedef char char_type;
352 typedef basic_string<char_type> string_type;
353
354 explicit collate_byname(const char* __n, size_t __refs = 0);
355 explicit collate_byname(const string& __n, size_t __refs = 0);
356
357protected:
358 ~collate_byname();
359 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
360 const char_type* __lo2, const char_type* __hi2) const;
361 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
362};
363
364template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000365class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000366 : public collate<wchar_t>
367{
368 locale_t __l;
369public:
370 typedef wchar_t char_type;
371 typedef basic_string<char_type> string_type;
372
373 explicit collate_byname(const char* __n, size_t __refs = 0);
374 explicit collate_byname(const string& __n, size_t __refs = 0);
375
376protected:
377 ~collate_byname();
378
379 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
380 const char_type* __lo2, const char_type* __hi2) const;
381 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
382};
383
384template <class _CharT, class _Traits, class _Allocator>
385bool
386locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
387 const basic_string<_CharT, _Traits, _Allocator>& __y) const
388{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000389 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390 __x.data(), __x.data() + __x.size(),
391 __y.data(), __y.data() + __y.size()) < 0;
392}
393
394// template <class charT> class ctype
395
Howard Hinnant8331b762013-03-06 23:30:19 +0000396class _LIBCPP_TYPE_VIS ctype_base
Howard Hinnant9833cad2010-09-21 18:58:51 +0000397{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000398public:
Vasileios Kalintiris281b4cf2015-11-09 10:21:04 +0000399#if defined(__GLIBC__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000400 typedef unsigned short mask;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000401 static const mask space = _ISspace;
402 static const mask print = _ISprint;
403 static const mask cntrl = _IScntrl;
404 static const mask upper = _ISupper;
405 static const mask lower = _ISlower;
406 static const mask alpha = _ISalpha;
407 static const mask digit = _ISdigit;
408 static const mask punct = _ISpunct;
409 static const mask xdigit = _ISxdigit;
410 static const mask blank = _ISblank;
Eric Fiselierbb999f92017-05-31 22:14:05 +0000411#elif defined(_LIBCPP_MSVCRT_LIKE)
Howard Hinnantd7a78632011-09-29 13:33:15 +0000412 typedef unsigned short mask;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000413 static const mask space = _SPACE;
414 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
415 static const mask cntrl = _CONTROL;
416 static const mask upper = _UPPER;
417 static const mask lower = _LOWER;
418 static const mask alpha = _ALPHA;
419 static const mask digit = _DIGIT;
420 static const mask punct = _PUNCT;
421 static const mask xdigit = _HEX;
422 static const mask blank = _BLANK;
Jonathan Roelofsae9ab252015-03-11 17:00:28 +0000423# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
Dan Albertebdf28b2015-03-11 00:51:06 +0000424#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
JF Bastien0c265d82015-02-25 22:16:46 +0000425# ifdef __APPLE__
David Chisnall1d581062011-09-21 08:39:44 +0000426 typedef __uint32_t mask;
JF Bastien0c265d82015-02-25 22:16:46 +0000427# elif defined(__FreeBSD__)
David Chisnall1d581062011-09-21 08:39:44 +0000428 typedef unsigned long mask;
Vasileios Kalintirisc5dd8942015-11-24 10:24:54 +0000429# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
Howard Hinnant942dbd22013-03-29 18:27:28 +0000430 typedef unsigned short mask;
JF Bastien0c265d82015-02-25 22:16:46 +0000431# endif
David Chisnall1d581062011-09-21 08:39:44 +0000432 static const mask space = _CTYPE_S;
433 static const mask print = _CTYPE_R;
434 static const mask cntrl = _CTYPE_C;
435 static const mask upper = _CTYPE_U;
436 static const mask lower = _CTYPE_L;
437 static const mask alpha = _CTYPE_A;
438 static const mask digit = _CTYPE_D;
439 static const mask punct = _CTYPE_P;
440 static const mask xdigit = _CTYPE_X;
Dan Albert2dca4072014-07-23 19:32:03 +0000441
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000442# if defined(__NetBSD__)
443 static const mask blank = _CTYPE_BL;
444# else
David Chisnall1d581062011-09-21 08:39:44 +0000445 static const mask blank = _CTYPE_B;
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000446# endif
Howard Hinnanta47505d2013-08-30 14:42:39 +0000447#elif defined(__sun__) || defined(_AIX)
David Chisnall8074c342012-02-29 13:05:08 +0000448 typedef unsigned int mask;
449 static const mask space = _ISSPACE;
450 static const mask print = _ISPRINT;
451 static const mask cntrl = _ISCNTRL;
452 static const mask upper = _ISUPPER;
453 static const mask lower = _ISLOWER;
454 static const mask alpha = _ISALPHA;
455 static const mask digit = _ISDIGIT;
456 static const mask punct = _ISPUNCT;
457 static const mask xdigit = _ISXDIGIT;
458 static const mask blank = _ISBLANK;
JF Bastien0c265d82015-02-25 22:16:46 +0000459#elif defined(_NEWLIB_VERSION)
460 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
461 typedef char mask;
462 static const mask space = _S;
463 static const mask print = _P | _U | _L | _N | _B;
464 static const mask cntrl = _C;
465 static const mask upper = _U;
466 static const mask lower = _L;
467 static const mask alpha = _U | _L;
468 static const mask digit = _N;
469 static const mask punct = _P;
470 static const mask xdigit = _X | _N;
471 static const mask blank = _B;
Jonathan Roelofsae9ab252015-03-11 17:00:28 +0000472# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
473# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
474# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
JF Bastien0c265d82015-02-25 22:16:46 +0000475#else
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000476 typedef unsigned long mask;
477 static const mask space = 1<<0;
478 static const mask print = 1<<1;
479 static const mask cntrl = 1<<2;
480 static const mask upper = 1<<3;
481 static const mask lower = 1<<4;
482 static const mask alpha = 1<<5;
483 static const mask digit = 1<<6;
484 static const mask punct = 1<<7;
485 static const mask xdigit = 1<<8;
486 static const mask blank = 1<<9;
JF Bastien0c265d82015-02-25 22:16:46 +0000487#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000488 static const mask alnum = alpha | digit;
489 static const mask graph = alnum | punct;
490
Louis Dionne16fe2952018-07-11 23:14:33 +0000491 _LIBCPP_INLINE_VISIBILITY ctype_base() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000492};
493
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000494template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000495
496template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000497class _LIBCPP_TYPE_VIS ctype<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000498 : public locale::facet,
499 public ctype_base
500{
501public:
502 typedef wchar_t char_type;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000503
Louis Dionne16fe2952018-07-11 23:14:33 +0000504 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000505 explicit ctype(size_t __refs = 0)
506 : locale::facet(__refs) {}
507
Louis Dionne16fe2952018-07-11 23:14:33 +0000508 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000509 bool is(mask __m, char_type __c) const
510 {
511 return do_is(__m, __c);
512 }
513
Louis Dionne16fe2952018-07-11 23:14:33 +0000514 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000515 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
516 {
517 return do_is(__low, __high, __vec);
518 }
519
Louis Dionne16fe2952018-07-11 23:14:33 +0000520 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000521 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
522 {
523 return do_scan_is(__m, __low, __high);
524 }
525
Louis Dionne16fe2952018-07-11 23:14:33 +0000526 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000527 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
528 {
529 return do_scan_not(__m, __low, __high);
530 }
531
Louis Dionne16fe2952018-07-11 23:14:33 +0000532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000533 char_type toupper(char_type __c) const
534 {
535 return do_toupper(__c);
536 }
537
Louis Dionne16fe2952018-07-11 23:14:33 +0000538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000539 const char_type* toupper(char_type* __low, const char_type* __high) const
540 {
541 return do_toupper(__low, __high);
542 }
543
Louis Dionne16fe2952018-07-11 23:14:33 +0000544 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000545 char_type tolower(char_type __c) const
546 {
547 return do_tolower(__c);
548 }
549
Louis Dionne16fe2952018-07-11 23:14:33 +0000550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000551 const char_type* tolower(char_type* __low, const char_type* __high) const
552 {
553 return do_tolower(__low, __high);
554 }
555
Louis Dionne16fe2952018-07-11 23:14:33 +0000556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000557 char_type widen(char __c) const
558 {
559 return do_widen(__c);
560 }
561
Louis Dionne16fe2952018-07-11 23:14:33 +0000562 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000563 const char* widen(const char* __low, const char* __high, char_type* __to) const
564 {
565 return do_widen(__low, __high, __to);
566 }
567
Louis Dionne16fe2952018-07-11 23:14:33 +0000568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000569 char narrow(char_type __c, char __dfault) const
570 {
571 return do_narrow(__c, __dfault);
572 }
573
Louis Dionne16fe2952018-07-11 23:14:33 +0000574 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000575 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
576 {
577 return do_narrow(__low, __high, __dfault, __to);
578 }
579
580 static locale::id id;
581
582protected:
583 ~ctype();
584 virtual bool do_is(mask __m, char_type __c) const;
585 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
586 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
587 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
588 virtual char_type do_toupper(char_type) const;
589 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
590 virtual char_type do_tolower(char_type) const;
591 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
592 virtual char_type do_widen(char) const;
593 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
594 virtual char do_narrow(char_type, char __dfault) const;
595 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
596};
597
598template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000599class _LIBCPP_TYPE_VIS ctype<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000600 : public locale::facet, public ctype_base
601{
602 const mask* __tab_;
603 bool __del_;
604public:
605 typedef char char_type;
606
607 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
608
Louis Dionne16fe2952018-07-11 23:14:33 +0000609 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000610 bool is(mask __m, char_type __c) const
611 {
Marshall Clow11de4872013-10-21 14:41:05 +0000612 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000613 }
614
Louis Dionne16fe2952018-07-11 23:14:33 +0000615 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000616 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
617 {
618 for (; __low != __high; ++__low, ++__vec)
Howard Hinnant28b24882011-12-01 20:21:04 +0000619 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000620 return __low;
621 }
622
Louis Dionne16fe2952018-07-11 23:14:33 +0000623 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000624 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
625 {
626 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000627 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000628 break;
629 return __low;
630 }
631
Louis Dionne16fe2952018-07-11 23:14:33 +0000632 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000633 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
634 {
635 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000636 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000637 break;
638 return __low;
639 }
640
Louis Dionne16fe2952018-07-11 23:14:33 +0000641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000642 char_type toupper(char_type __c) const
643 {
644 return do_toupper(__c);
645 }
646
Louis Dionne16fe2952018-07-11 23:14:33 +0000647 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000648 const char_type* toupper(char_type* __low, const char_type* __high) const
649 {
650 return do_toupper(__low, __high);
651 }
652
Louis Dionne16fe2952018-07-11 23:14:33 +0000653 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000654 char_type tolower(char_type __c) const
655 {
656 return do_tolower(__c);
657 }
658
Louis Dionne16fe2952018-07-11 23:14:33 +0000659 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000660 const char_type* tolower(char_type* __low, const char_type* __high) const
661 {
662 return do_tolower(__low, __high);
663 }
664
Louis Dionne16fe2952018-07-11 23:14:33 +0000665 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000666 char_type widen(char __c) const
667 {
668 return do_widen(__c);
669 }
670
Louis Dionne16fe2952018-07-11 23:14:33 +0000671 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000672 const char* widen(const char* __low, const char* __high, char_type* __to) const
673 {
674 return do_widen(__low, __high, __to);
675 }
676
Louis Dionne16fe2952018-07-11 23:14:33 +0000677 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000678 char narrow(char_type __c, char __dfault) const
679 {
680 return do_narrow(__c, __dfault);
681 }
682
Louis Dionne16fe2952018-07-11 23:14:33 +0000683 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000684 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
685 {
686 return do_narrow(__low, __high, __dfault, __to);
687 }
688
689 static locale::id id;
690
Howard Hinnant155c2af2010-05-24 17:49:41 +0000691#ifdef _CACHED_RUNES
Howard Hinnantc51e1022010-05-11 19:42:16 +0000692 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000693#else
694 static const size_t table_size = 256; // FIXME: Don't hardcode this.
695#endif
Louis Dionne16fe2952018-07-11 23:14:33 +0000696 _LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;}
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000697 static const mask* classic_table() _NOEXCEPT;
Vasileios Kalintirisc5dd8942015-11-24 10:24:54 +0000698#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000699 static const int* __classic_upper_table() _NOEXCEPT;
700 static const int* __classic_lower_table() _NOEXCEPT;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000701#endif
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000702#if defined(__NetBSD__)
703 static const short* __classic_upper_table() _NOEXCEPT;
704 static const short* __classic_lower_table() _NOEXCEPT;
705#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000706
707protected:
708 ~ctype();
709 virtual char_type do_toupper(char_type __c) const;
710 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
711 virtual char_type do_tolower(char_type __c) const;
712 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
713 virtual char_type do_widen(char __c) const;
714 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
715 virtual char do_narrow(char_type __c, char __dfault) const;
716 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
717};
718
719// template <class CharT> class ctype_byname;
720
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000721template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000722
723template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000724class _LIBCPP_TYPE_VIS ctype_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000725 : public ctype<char>
726{
727 locale_t __l;
728
729public:
730 explicit ctype_byname(const char*, size_t = 0);
731 explicit ctype_byname(const string&, size_t = 0);
732
733protected:
734 ~ctype_byname();
735 virtual char_type do_toupper(char_type) const;
736 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
737 virtual char_type do_tolower(char_type) const;
738 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
739};
740
741template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000742class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000743 : public ctype<wchar_t>
744{
745 locale_t __l;
746
747public:
748 explicit ctype_byname(const char*, size_t = 0);
749 explicit ctype_byname(const string&, size_t = 0);
750
751protected:
752 ~ctype_byname();
753 virtual bool do_is(mask __m, char_type __c) const;
754 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
755 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
756 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
757 virtual char_type do_toupper(char_type) const;
758 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
759 virtual char_type do_tolower(char_type) const;
760 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
761 virtual char_type do_widen(char) const;
762 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
763 virtual char do_narrow(char_type, char __dfault) const;
764 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
765};
766
767template <class _CharT>
768inline _LIBCPP_INLINE_VISIBILITY
769bool
770isspace(_CharT __c, const locale& __loc)
771{
772 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
773}
774
775template <class _CharT>
776inline _LIBCPP_INLINE_VISIBILITY
777bool
778isprint(_CharT __c, const locale& __loc)
779{
780 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
781}
782
783template <class _CharT>
784inline _LIBCPP_INLINE_VISIBILITY
785bool
786iscntrl(_CharT __c, const locale& __loc)
787{
788 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
789}
790
791template <class _CharT>
792inline _LIBCPP_INLINE_VISIBILITY
793bool
794isupper(_CharT __c, const locale& __loc)
795{
796 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
797}
798
799template <class _CharT>
800inline _LIBCPP_INLINE_VISIBILITY
801bool
802islower(_CharT __c, const locale& __loc)
803{
804 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
805}
806
807template <class _CharT>
808inline _LIBCPP_INLINE_VISIBILITY
809bool
810isalpha(_CharT __c, const locale& __loc)
811{
812 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
813}
814
815template <class _CharT>
816inline _LIBCPP_INLINE_VISIBILITY
817bool
818isdigit(_CharT __c, const locale& __loc)
819{
820 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
821}
822
823template <class _CharT>
824inline _LIBCPP_INLINE_VISIBILITY
825bool
826ispunct(_CharT __c, const locale& __loc)
827{
828 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
829}
830
831template <class _CharT>
832inline _LIBCPP_INLINE_VISIBILITY
833bool
834isxdigit(_CharT __c, const locale& __loc)
835{
836 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
837}
838
839template <class _CharT>
840inline _LIBCPP_INLINE_VISIBILITY
841bool
842isalnum(_CharT __c, const locale& __loc)
843{
844 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
845}
846
847template <class _CharT>
848inline _LIBCPP_INLINE_VISIBILITY
849bool
850isgraph(_CharT __c, const locale& __loc)
851{
852 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
853}
854
855template <class _CharT>
856inline _LIBCPP_INLINE_VISIBILITY
857_CharT
858toupper(_CharT __c, const locale& __loc)
859{
860 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
861}
862
863template <class _CharT>
864inline _LIBCPP_INLINE_VISIBILITY
865_CharT
866tolower(_CharT __c, const locale& __loc)
867{
868 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
869}
870
871// codecvt_base
872
Howard Hinnant8331b762013-03-06 23:30:19 +0000873class _LIBCPP_TYPE_VIS codecvt_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000874{
875public:
Louis Dionne16fe2952018-07-11 23:14:33 +0000876 _LIBCPP_INLINE_VISIBILITY codecvt_base() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000877 enum result {ok, partial, error, noconv};
878};
879
880// template <class internT, class externT, class stateT> class codecvt;
881
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000882template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000883
884// template <> class codecvt<char, char, mbstate_t>
885
886template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000887class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000888 : public locale::facet,
889 public codecvt_base
890{
891public:
892 typedef char intern_type;
893 typedef char extern_type;
894 typedef mbstate_t state_type;
895
Louis Dionne16fe2952018-07-11 23:14:33 +0000896 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000897 explicit codecvt(size_t __refs = 0)
898 : locale::facet(__refs) {}
899
Louis Dionne16fe2952018-07-11 23:14:33 +0000900 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000901 result out(state_type& __st,
902 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
903 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
904 {
905 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
906 }
907
Louis Dionne16fe2952018-07-11 23:14:33 +0000908 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000909 result unshift(state_type& __st,
910 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
911 {
912 return do_unshift(__st, __to, __to_end, __to_nxt);
913 }
914
Louis Dionne16fe2952018-07-11 23:14:33 +0000915 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000916 result in(state_type& __st,
917 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
918 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
919 {
920 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
921 }
922
Louis Dionne16fe2952018-07-11 23:14:33 +0000923 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000924 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000925 {
926 return do_encoding();
927 }
928
Louis Dionne16fe2952018-07-11 23:14:33 +0000929 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000930 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000931 {
932 return do_always_noconv();
933 }
934
Louis Dionne16fe2952018-07-11 23:14:33 +0000935 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000936 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
937 {
938 return do_length(__st, __frm, __end, __mx);
939 }
940
Louis Dionne16fe2952018-07-11 23:14:33 +0000941 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000942 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000943 {
944 return do_max_length();
945 }
946
947 static locale::id id;
948
949protected:
Louis Dionne16fe2952018-07-11 23:14:33 +0000950 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000951 explicit codecvt(const char*, size_t __refs = 0)
952 : locale::facet(__refs) {}
953
954 ~codecvt();
955
956 virtual result do_out(state_type& __st,
957 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
958 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
959 virtual result do_in(state_type& __st,
960 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
961 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
962 virtual result do_unshift(state_type& __st,
963 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000964 virtual int do_encoding() const _NOEXCEPT;
965 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000966 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000967 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000968};
969
970// template <> class codecvt<wchar_t, char, mbstate_t>
971
972template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000973class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000974 : public locale::facet,
975 public codecvt_base
976{
977 locale_t __l;
978public:
979 typedef wchar_t intern_type;
980 typedef char extern_type;
981 typedef mbstate_t state_type;
982
983 explicit codecvt(size_t __refs = 0);
984
Louis Dionne16fe2952018-07-11 23:14:33 +0000985 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000986 result out(state_type& __st,
987 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
988 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
989 {
990 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
991 }
992
Louis Dionne16fe2952018-07-11 23:14:33 +0000993 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000994 result unshift(state_type& __st,
995 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
996 {
997 return do_unshift(__st, __to, __to_end, __to_nxt);
998 }
999
Louis Dionne16fe2952018-07-11 23:14:33 +00001000 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001001 result in(state_type& __st,
1002 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1003 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1004 {
1005 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1006 }
1007
Louis Dionne16fe2952018-07-11 23:14:33 +00001008 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001009 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001010 {
1011 return do_encoding();
1012 }
1013
Louis Dionne16fe2952018-07-11 23:14:33 +00001014 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001015 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001016 {
1017 return do_always_noconv();
1018 }
1019
Louis Dionne16fe2952018-07-11 23:14:33 +00001020 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001021 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1022 {
1023 return do_length(__st, __frm, __end, __mx);
1024 }
1025
Louis Dionne16fe2952018-07-11 23:14:33 +00001026 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001027 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001028 {
1029 return do_max_length();
1030 }
1031
1032 static locale::id id;
1033
1034protected:
1035 explicit codecvt(const char*, size_t __refs = 0);
1036
1037 ~codecvt();
1038
1039 virtual result do_out(state_type& __st,
1040 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1041 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1042 virtual result do_in(state_type& __st,
1043 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1044 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1045 virtual result do_unshift(state_type& __st,
1046 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001047 virtual int do_encoding() const _NOEXCEPT;
1048 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001049 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001050 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001051};
1052
1053// template <> class codecvt<char16_t, char, mbstate_t>
1054
1055template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001056class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001057 : public locale::facet,
1058 public codecvt_base
1059{
1060public:
1061 typedef char16_t intern_type;
1062 typedef char extern_type;
1063 typedef mbstate_t state_type;
1064
Louis Dionne16fe2952018-07-11 23:14:33 +00001065 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001066 explicit codecvt(size_t __refs = 0)
1067 : locale::facet(__refs) {}
1068
Louis Dionne16fe2952018-07-11 23:14:33 +00001069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001070 result out(state_type& __st,
1071 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1072 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1073 {
1074 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1075 }
1076
Louis Dionne16fe2952018-07-11 23:14:33 +00001077 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001078 result unshift(state_type& __st,
1079 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1080 {
1081 return do_unshift(__st, __to, __to_end, __to_nxt);
1082 }
1083
Louis Dionne16fe2952018-07-11 23:14:33 +00001084 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001085 result in(state_type& __st,
1086 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1087 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1088 {
1089 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1090 }
1091
Louis Dionne16fe2952018-07-11 23:14:33 +00001092 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001093 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001094 {
1095 return do_encoding();
1096 }
1097
Louis Dionne16fe2952018-07-11 23:14:33 +00001098 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001099 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001100 {
1101 return do_always_noconv();
1102 }
1103
Louis Dionne16fe2952018-07-11 23:14:33 +00001104 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001105 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1106 {
1107 return do_length(__st, __frm, __end, __mx);
1108 }
1109
Louis Dionne16fe2952018-07-11 23:14:33 +00001110 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001111 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001112 {
1113 return do_max_length();
1114 }
1115
1116 static locale::id id;
1117
1118protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00001119 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001120 explicit codecvt(const char*, size_t __refs = 0)
1121 : locale::facet(__refs) {}
1122
1123 ~codecvt();
1124
1125 virtual result do_out(state_type& __st,
1126 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1127 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1128 virtual result do_in(state_type& __st,
1129 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1130 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1131 virtual result do_unshift(state_type& __st,
1132 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001133 virtual int do_encoding() const _NOEXCEPT;
1134 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001135 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001136 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001137};
1138
1139// template <> class codecvt<char32_t, char, mbstate_t>
1140
1141template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001142class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001143 : public locale::facet,
1144 public codecvt_base
1145{
1146public:
1147 typedef char32_t intern_type;
1148 typedef char extern_type;
1149 typedef mbstate_t state_type;
1150
Louis Dionne16fe2952018-07-11 23:14:33 +00001151 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001152 explicit codecvt(size_t __refs = 0)
1153 : locale::facet(__refs) {}
1154
Louis Dionne16fe2952018-07-11 23:14:33 +00001155 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001156 result out(state_type& __st,
1157 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1158 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1159 {
1160 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1161 }
1162
Louis Dionne16fe2952018-07-11 23:14:33 +00001163 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001164 result unshift(state_type& __st,
1165 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1166 {
1167 return do_unshift(__st, __to, __to_end, __to_nxt);
1168 }
1169
Louis Dionne16fe2952018-07-11 23:14:33 +00001170 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001171 result in(state_type& __st,
1172 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1173 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1174 {
1175 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1176 }
1177
Louis Dionne16fe2952018-07-11 23:14:33 +00001178 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001179 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001180 {
1181 return do_encoding();
1182 }
1183
Louis Dionne16fe2952018-07-11 23:14:33 +00001184 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001185 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001186 {
1187 return do_always_noconv();
1188 }
1189
Louis Dionne16fe2952018-07-11 23:14:33 +00001190 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001191 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1192 {
1193 return do_length(__st, __frm, __end, __mx);
1194 }
1195
Louis Dionne16fe2952018-07-11 23:14:33 +00001196 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001197 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001198 {
1199 return do_max_length();
1200 }
1201
1202 static locale::id id;
1203
1204protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00001205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001206 explicit codecvt(const char*, size_t __refs = 0)
1207 : locale::facet(__refs) {}
1208
1209 ~codecvt();
1210
1211 virtual result do_out(state_type& __st,
1212 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1213 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1214 virtual result do_in(state_type& __st,
1215 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1216 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1217 virtual result do_unshift(state_type& __st,
1218 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001219 virtual int do_encoding() const _NOEXCEPT;
1220 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001221 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001222 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001223};
1224
Howard Hinnantc51e1022010-05-11 19:42:16 +00001225// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1226
1227template <class _InternT, class _ExternT, class _StateT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001228class _LIBCPP_TEMPLATE_VIS codecvt_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00001229 : public codecvt<_InternT, _ExternT, _StateT>
1230{
1231public:
Louis Dionne16fe2952018-07-11 23:14:33 +00001232 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001233 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1234 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Louis Dionne16fe2952018-07-11 23:14:33 +00001235 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001236 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1237 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1238protected:
1239 ~codecvt_byname();
1240};
1241
1242template <class _InternT, class _ExternT, class _StateT>
1243codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1244{
1245}
1246
Eric Fiselier1b57fa82016-09-15 22:27:07 +00001247_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
1248_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
1249_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
1250_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001251
Howard Hinnantc834c512011-11-29 18:15:50 +00001252template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001253struct __narrow_to_utf8
1254{
1255 template <class _OutputIterator, class _CharT>
1256 _OutputIterator
1257 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1258};
1259
1260template <>
1261struct __narrow_to_utf8<8>
1262{
1263 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001264 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001265 _OutputIterator
1266 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1267 {
1268 for (; __wb < __we; ++__wb, ++__s)
1269 *__s = *__wb;
1270 return __s;
1271 }
1272};
1273
1274template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001275struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001276 : public codecvt<char16_t, char, mbstate_t>
1277{
Louis Dionne16fe2952018-07-11 23:14:33 +00001278 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001279 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1280
Louis Dionne5254b372018-10-25 12:13:43 +00001281 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001282
1283 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001284 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001285 _OutputIterator
1286 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1287 {
1288 result __r = ok;
1289 mbstate_t __mb;
1290 while (__wb < __we && __r != error)
1291 {
1292 const int __sz = 32;
1293 char __buf[__sz];
1294 char* __bn;
1295 const char16_t* __wn = (const char16_t*)__wb;
1296 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1297 __buf, __buf+__sz, __bn);
1298 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1299 __throw_runtime_error("locale not supported");
1300 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1301 *__s = *__p;
1302 __wb = (const _CharT*)__wn;
1303 }
1304 return __s;
1305 }
1306};
1307
1308template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001309struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001310 : public codecvt<char32_t, char, mbstate_t>
1311{
Louis Dionne16fe2952018-07-11 23:14:33 +00001312 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001313 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1314
Louis Dionne5254b372018-10-25 12:13:43 +00001315 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001316
1317 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001319 _OutputIterator
1320 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1321 {
1322 result __r = ok;
1323 mbstate_t __mb;
1324 while (__wb < __we && __r != error)
1325 {
1326 const int __sz = 32;
1327 char __buf[__sz];
1328 char* __bn;
1329 const char32_t* __wn = (const char32_t*)__wb;
1330 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1331 __buf, __buf+__sz, __bn);
1332 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1333 __throw_runtime_error("locale not supported");
1334 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1335 *__s = *__p;
1336 __wb = (const _CharT*)__wn;
1337 }
1338 return __s;
1339 }
1340};
1341
Howard Hinnantc834c512011-11-29 18:15:50 +00001342template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001343struct __widen_from_utf8
1344{
1345 template <class _OutputIterator>
1346 _OutputIterator
1347 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1348};
1349
1350template <>
1351struct __widen_from_utf8<8>
1352{
1353 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001354 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001355 _OutputIterator
1356 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1357 {
1358 for (; __nb < __ne; ++__nb, ++__s)
1359 *__s = *__nb;
1360 return __s;
1361 }
1362};
1363
1364template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001365struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001366 : public codecvt<char16_t, char, mbstate_t>
1367{
Louis Dionne16fe2952018-07-11 23:14:33 +00001368 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001369 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1370
Louis Dionne5254b372018-10-25 12:13:43 +00001371 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001372
1373 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001375 _OutputIterator
1376 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1377 {
1378 result __r = ok;
1379 mbstate_t __mb;
1380 while (__nb < __ne && __r != error)
1381 {
1382 const int __sz = 32;
1383 char16_t __buf[__sz];
1384 char16_t* __bn;
1385 const char* __nn = __nb;
1386 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1387 __buf, __buf+__sz, __bn);
1388 if (__r == codecvt_base::error || __nn == __nb)
1389 __throw_runtime_error("locale not supported");
1390 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1391 *__s = (wchar_t)*__p;
1392 __nb = __nn;
1393 }
1394 return __s;
1395 }
1396};
1397
1398template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001399struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001400 : public codecvt<char32_t, char, mbstate_t>
1401{
Louis Dionne16fe2952018-07-11 23:14:33 +00001402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001403 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1404
Louis Dionne5254b372018-10-25 12:13:43 +00001405 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001406
1407 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001408 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001409 _OutputIterator
1410 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1411 {
1412 result __r = ok;
1413 mbstate_t __mb;
1414 while (__nb < __ne && __r != error)
1415 {
1416 const int __sz = 32;
1417 char32_t __buf[__sz];
1418 char32_t* __bn;
1419 const char* __nn = __nb;
1420 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1421 __buf, __buf+__sz, __bn);
1422 if (__r == codecvt_base::error || __nn == __nb)
1423 __throw_runtime_error("locale not supported");
1424 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1425 *__s = (wchar_t)*__p;
1426 __nb = __nn;
1427 }
1428 return __s;
1429 }
1430};
1431
1432// template <class charT> class numpunct
1433
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001434template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001435
1436template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001437class _LIBCPP_TYPE_VIS numpunct<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001438 : public locale::facet
1439{
1440public:
1441 typedef char char_type;
1442 typedef basic_string<char_type> string_type;
1443
1444 explicit numpunct(size_t __refs = 0);
1445
Louis Dionne16fe2952018-07-11 23:14:33 +00001446 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
1447 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
1448 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
1449 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
1450 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001451
1452 static locale::id id;
1453
1454protected:
1455 ~numpunct();
1456 virtual char_type do_decimal_point() const;
1457 virtual char_type do_thousands_sep() const;
1458 virtual string do_grouping() const;
1459 virtual string_type do_truename() const;
1460 virtual string_type do_falsename() const;
1461
1462 char_type __decimal_point_;
1463 char_type __thousands_sep_;
1464 string __grouping_;
1465};
1466
1467template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001468class _LIBCPP_TYPE_VIS numpunct<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001469 : public locale::facet
1470{
1471public:
1472 typedef wchar_t char_type;
1473 typedef basic_string<char_type> string_type;
1474
1475 explicit numpunct(size_t __refs = 0);
1476
Louis Dionne16fe2952018-07-11 23:14:33 +00001477 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
1478 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
1479 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
1480 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
1481 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001482
1483 static locale::id id;
1484
1485protected:
1486 ~numpunct();
1487 virtual char_type do_decimal_point() const;
1488 virtual char_type do_thousands_sep() const;
1489 virtual string do_grouping() const;
1490 virtual string_type do_truename() const;
1491 virtual string_type do_falsename() const;
1492
1493 char_type __decimal_point_;
1494 char_type __thousands_sep_;
1495 string __grouping_;
1496};
1497
1498// template <class charT> class numpunct_byname
1499
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001500template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001501
1502template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001503class _LIBCPP_TYPE_VIS numpunct_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001504: public numpunct<char>
1505{
1506public:
1507 typedef char char_type;
1508 typedef basic_string<char_type> string_type;
1509
1510 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1511 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1512
1513protected:
1514 ~numpunct_byname();
1515
1516private:
1517 void __init(const char*);
1518};
1519
1520template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001521class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001522: public numpunct<wchar_t>
1523{
1524public:
1525 typedef wchar_t char_type;
1526 typedef basic_string<char_type> string_type;
1527
1528 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1529 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1530
1531protected:
1532 ~numpunct_byname();
1533
1534private:
1535 void __init(const char*);
1536};
1537
1538_LIBCPP_END_NAMESPACE_STD
1539
1540#endif // _LIBCPP___LOCALE