blob: d9d2682c4810c7b3ba1ebdd38a828b96ba265cfd [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>
Vasileios Kalintiris281b4cf2015-11-09 10:21:04 +000038#elif defined(_LIBCPP_HAS_MUSL_LIBC)
39# include <support/musl/xlocale.h>
Petr Hosekfdb4a872017-04-13 21:29:21 +000040#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000041
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000042#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +000043#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000044#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000045
46_LIBCPP_BEGIN_NAMESPACE_STD
47
Martin Storsjo5482ac62017-11-23 10:38:18 +000048#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
Eric Fiselierebc2d2c2017-05-08 22:02:43 +000049struct __libcpp_locale_guard {
50 _LIBCPP_INLINE_VISIBILITY
51 __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
52
53 _LIBCPP_INLINE_VISIBILITY
54 ~__libcpp_locale_guard() {
55 if (__old_loc_)
56 uselocale(__old_loc_);
57 }
58
59 locale_t __old_loc_;
60private:
61 __libcpp_locale_guard(__libcpp_locale_guard const&);
62 __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
63};
Martin Storsjo5482ac62017-11-23 10:38:18 +000064#elif defined(_LIBCPP_MSVCRT_LIKE)
65struct __libcpp_locale_guard {
66 __libcpp_locale_guard(locale_t __l) :
Thomas Anderson094acbc2019-03-27 18:09:30 +000067 __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
68 // Setting the locale can be expensive even when the locale given is
69 // already the current locale, so do an explicit check to see if the
70 // current locale is already the one we want.
71 const char* __lc = __setlocale(nullptr);
72 // If every category is the same, the locale string will simply be the
73 // locale name, otherwise it will be a semicolon-separated string listing
74 // each category. In the second case, we know at least one category won't
75 // be what we want, so we only have to check the first case.
76 if (strcmp(__l.__get_locale(), __lc) != 0) {
77 __locale_all = _strdup(__lc);
78 if (__locale_all == nullptr)
79 __throw_bad_alloc();
80 __setlocale(__l.__get_locale());
81 }
82 }
Martin Storsjo5482ac62017-11-23 10:38:18 +000083 ~__libcpp_locale_guard() {
Thomas Anderson094acbc2019-03-27 18:09:30 +000084 // The CRT documentation doesn't explicitly say, but setlocale() does the
85 // right thing when given a semicolon-separated list of locale settings
86 // for the different categories in the same format as returned by
87 // setlocale(LC_ALL, nullptr).
88 if (__locale_all != nullptr) {
89 __setlocale(__locale_all);
90 free(__locale_all);
91 }
92 _configthreadlocale(__status);
93 }
94 static const char* __setlocale(const char* __locale) {
95 const char* __new_locale = setlocale(LC_ALL, __locale);
96 if (__new_locale == nullptr)
97 __throw_bad_alloc();
98 return __new_locale;
Martin Storsjo5482ac62017-11-23 10:38:18 +000099 }
100 int __status;
Thomas Anderson094acbc2019-03-27 18:09:30 +0000101 char* __locale_all = nullptr;
Martin Storsjo5482ac62017-11-23 10:38:18 +0000102};
Eric Fiselierebc2d2c2017-05-08 22:02:43 +0000103#endif
104
105
Howard Hinnant8331b762013-03-06 23:30:19 +0000106class _LIBCPP_TYPE_VIS locale;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000107
Howard Hinnanta54386e2012-09-14 00:39:16 +0000108template <class _Facet>
109_LIBCPP_INLINE_VISIBILITY
110bool
111has_facet(const locale&) _NOEXCEPT;
112
113template <class _Facet>
114_LIBCPP_INLINE_VISIBILITY
115const _Facet&
116use_facet(const locale&);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000117
Howard Hinnant8331b762013-03-06 23:30:19 +0000118class _LIBCPP_TYPE_VIS locale
Howard Hinnantc51e1022010-05-11 19:42:16 +0000119{
120public:
121 // types:
Howard Hinnant8331b762013-03-06 23:30:19 +0000122 class _LIBCPP_TYPE_VIS facet;
123 class _LIBCPP_TYPE_VIS id;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000124
125 typedef int category;
Mehdi Amini228053d2017-05-04 17:08:54 +0000126 _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000127 static const category // values assigned here are for exposition only
128 none = 0,
129 collate = LC_COLLATE_MASK,
130 ctype = LC_CTYPE_MASK,
131 monetary = LC_MONETARY_MASK,
132 numeric = LC_NUMERIC_MASK,
133 time = LC_TIME_MASK,
134 messages = LC_MESSAGES_MASK,
135 all = collate | ctype | monetary | numeric | time | messages;
136
137 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000138 locale() _NOEXCEPT;
139 locale(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000140 explicit locale(const char*);
141 explicit locale(const string&);
142 locale(const locale&, const char*, category);
143 locale(const locale&, const string&, category);
Howard Hinnantcf823322010-12-17 14:46:43 +0000144 template <class _Facet>
145 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000146 locale(const locale&, const locale&, category);
147
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000148 ~locale();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000149
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000150 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000151
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000152 template <class _Facet>
153 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
154 locale combine(const locale&) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000155
156 // locale operations:
157 string name() const;
158 bool operator==(const locale&) const;
159 bool operator!=(const locale& __y) const {return !(*this == __y);}
160 template <class _CharT, class _Traits, class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000161 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000162 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
163 const basic_string<_CharT, _Traits, _Allocator>&) const;
164
165 // global locale objects:
166 static locale global(const locale&);
167 static const locale& classic();
168
169private:
170 class __imp;
171 __imp* __locale_;
172
173 void __install_ctor(const locale&, facet*, long);
174 static locale& __global();
175 bool has_facet(id&) const;
176 const facet* use_facet(id&) const;
177
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000178 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000179 template <class _Facet> friend const _Facet& use_facet(const locale&);
180};
181
Howard Hinnant8331b762013-03-06 23:30:19 +0000182class _LIBCPP_TYPE_VIS locale::facet
Howard Hinnantc51e1022010-05-11 19:42:16 +0000183 : public __shared_count
184{
185protected:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000186 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187 explicit facet(size_t __refs = 0)
188 : __shared_count(static_cast<long>(__refs)-1) {}
189
190 virtual ~facet();
191
192// facet(const facet&) = delete; // effectively done in __shared_count
193// void operator=(const facet&) = delete;
194private:
Howard Hinnant719bda32011-05-28 14:41:13 +0000195 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000196};
197
Howard Hinnant8331b762013-03-06 23:30:19 +0000198class _LIBCPP_TYPE_VIS locale::id
Howard Hinnantc51e1022010-05-11 19:42:16 +0000199{
200 once_flag __flag_;
201 int32_t __id_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000202
Howard Hinnantc51e1022010-05-11 19:42:16 +0000203 static int32_t __next_id;
204public:
Howard Hinnantac7d9f02012-07-26 16:14:37 +0000205 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000206private:
207 void __init();
208 void operator=(const id&); // = delete;
209 id(const id&); // = delete;
210public: // only needed for tests
211 long __get();
212
213 friend class locale;
214 friend class locale::__imp;
215};
216
217template <class _Facet>
218inline _LIBCPP_INLINE_VISIBILITY
219locale::locale(const locale& __other, _Facet* __f)
220{
221 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
222}
223
224template <class _Facet>
225locale
226locale::combine(const locale& __other) const
227{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000228 if (!_VSTD::has_facet<_Facet>(__other))
Marshall Clow8fea1612016-08-25 15:09:01 +0000229 __throw_runtime_error("locale::combine: locale missing facet");
230
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000231 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000232}
233
234template <class _Facet>
235inline _LIBCPP_INLINE_VISIBILITY
236bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000237has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000238{
239 return __l.has_facet(_Facet::id);
240}
241
242template <class _Facet>
243inline _LIBCPP_INLINE_VISIBILITY
244const _Facet&
245use_facet(const locale& __l)
246{
247 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
248}
249
250// template <class _CharT> class collate;
251
252template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000253class _LIBCPP_TEMPLATE_VIS collate
Howard Hinnantc51e1022010-05-11 19:42:16 +0000254 : public locale::facet
255{
256public:
257 typedef _CharT char_type;
258 typedef basic_string<char_type> string_type;
259
Howard Hinnant9833cad2010-09-21 18:58:51 +0000260 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000261 explicit collate(size_t __refs = 0)
262 : locale::facet(__refs) {}
263
Howard Hinnant9833cad2010-09-21 18:58:51 +0000264 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000265 int compare(const char_type* __lo1, const char_type* __hi1,
266 const char_type* __lo2, const char_type* __hi2) const
267 {
268 return do_compare(__lo1, __hi1, __lo2, __hi2);
269 }
270
Eric Fiselier39b86ea2019-03-08 23:59:29 +0000271 // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work
272 // around a dllimport bug that expects an external instantiation.
Howard Hinnant9833cad2010-09-21 18:58:51 +0000273 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier39b86ea2019-03-08 23:59:29 +0000274 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +0000275 string_type transform(const char_type* __lo, const char_type* __hi) const
276 {
277 return do_transform(__lo, __hi);
278 }
279
Howard Hinnant9833cad2010-09-21 18:58:51 +0000280 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000281 long hash(const char_type* __lo, const char_type* __hi) const
282 {
283 return do_hash(__lo, __hi);
284 }
285
286 static locale::id id;
287
288protected:
289 ~collate();
290 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
291 const char_type* __lo2, const char_type* __hi2) const;
292 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
293 {return string_type(__lo, __hi);}
294 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
295};
296
297template <class _CharT> locale::id collate<_CharT>::id;
298
299template <class _CharT>
300collate<_CharT>::~collate()
301{
302}
303
304template <class _CharT>
305int
306collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
307 const char_type* __lo2, const char_type* __hi2) const
308{
309 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
310 {
311 if (__lo1 == __hi1 || *__lo1 < *__lo2)
312 return -1;
313 if (*__lo2 < *__lo1)
314 return 1;
315 }
316 return __lo1 != __hi1;
317}
318
319template <class _CharT>
320long
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000321collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000322{
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000323 size_t __h = 0;
324 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
325 const size_t __mask = size_t(0xF) << (__sr + 4);
326 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000327 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000328 __h = (__h << 4) + static_cast<size_t>(*__p);
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000329 size_t __g = __h & __mask;
330 __h ^= __g | (__g >> __sr);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000331 }
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000332 return static_cast<long>(__h);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000333}
334
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000335_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>)
336_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000337
338// template <class CharT> class collate_byname;
339
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000340template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000341
342template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000343class _LIBCPP_TYPE_VIS collate_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000344 : public collate<char>
345{
346 locale_t __l;
347public:
348 typedef char char_type;
349 typedef basic_string<char_type> string_type;
350
351 explicit collate_byname(const char* __n, size_t __refs = 0);
352 explicit collate_byname(const string& __n, size_t __refs = 0);
353
354protected:
355 ~collate_byname();
356 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
357 const char_type* __lo2, const char_type* __hi2) const;
358 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
359};
360
361template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000362class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000363 : public collate<wchar_t>
364{
365 locale_t __l;
366public:
367 typedef wchar_t char_type;
368 typedef basic_string<char_type> string_type;
369
370 explicit collate_byname(const char* __n, size_t __refs = 0);
371 explicit collate_byname(const string& __n, size_t __refs = 0);
372
373protected:
374 ~collate_byname();
375
376 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
377 const char_type* __lo2, const char_type* __hi2) const;
378 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
379};
380
381template <class _CharT, class _Traits, class _Allocator>
382bool
383locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
384 const basic_string<_CharT, _Traits, _Allocator>& __y) const
385{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000386 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantc51e1022010-05-11 19:42:16 +0000387 __x.data(), __x.data() + __x.size(),
388 __y.data(), __y.data() + __y.size()) < 0;
389}
390
391// template <class charT> class ctype
392
Howard Hinnant8331b762013-03-06 23:30:19 +0000393class _LIBCPP_TYPE_VIS ctype_base
Howard Hinnant9833cad2010-09-21 18:58:51 +0000394{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000395public:
Vasileios Kalintiris281b4cf2015-11-09 10:21:04 +0000396#if defined(__GLIBC__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000397 typedef unsigned short mask;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000398 static const mask space = _ISspace;
399 static const mask print = _ISprint;
400 static const mask cntrl = _IScntrl;
401 static const mask upper = _ISupper;
402 static const mask lower = _ISlower;
403 static const mask alpha = _ISalpha;
404 static const mask digit = _ISdigit;
405 static const mask punct = _ISpunct;
406 static const mask xdigit = _ISxdigit;
407 static const mask blank = _ISblank;
Eric Fiselierbb999f92017-05-31 22:14:05 +0000408#elif defined(_LIBCPP_MSVCRT_LIKE)
Howard Hinnantd7a78632011-09-29 13:33:15 +0000409 typedef unsigned short mask;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000410 static const mask space = _SPACE;
411 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
412 static const mask cntrl = _CONTROL;
413 static const mask upper = _UPPER;
414 static const mask lower = _LOWER;
415 static const mask alpha = _ALPHA;
416 static const mask digit = _DIGIT;
417 static const mask punct = _PUNCT;
418 static const mask xdigit = _HEX;
419 static const mask blank = _BLANK;
Jonathan Roelofsae9ab252015-03-11 17:00:28 +0000420# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
Dan Albertebdf28b2015-03-11 00:51:06 +0000421#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
JF Bastien0c265d82015-02-25 22:16:46 +0000422# ifdef __APPLE__
David Chisnall1d581062011-09-21 08:39:44 +0000423 typedef __uint32_t mask;
JF Bastien0c265d82015-02-25 22:16:46 +0000424# elif defined(__FreeBSD__)
David Chisnall1d581062011-09-21 08:39:44 +0000425 typedef unsigned long mask;
Vasileios Kalintirisc5dd8942015-11-24 10:24:54 +0000426# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
Howard Hinnant942dbd22013-03-29 18:27:28 +0000427 typedef unsigned short mask;
JF Bastien0c265d82015-02-25 22:16:46 +0000428# endif
David Chisnall1d581062011-09-21 08:39:44 +0000429 static const mask space = _CTYPE_S;
430 static const mask print = _CTYPE_R;
431 static const mask cntrl = _CTYPE_C;
432 static const mask upper = _CTYPE_U;
433 static const mask lower = _CTYPE_L;
434 static const mask alpha = _CTYPE_A;
435 static const mask digit = _CTYPE_D;
436 static const mask punct = _CTYPE_P;
437 static const mask xdigit = _CTYPE_X;
Dan Albert2dca4072014-07-23 19:32:03 +0000438
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000439# if defined(__NetBSD__)
440 static const mask blank = _CTYPE_BL;
441# else
David Chisnall1d581062011-09-21 08:39:44 +0000442 static const mask blank = _CTYPE_B;
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000443# endif
Howard Hinnanta47505d2013-08-30 14:42:39 +0000444#elif defined(__sun__) || defined(_AIX)
David Chisnall8074c342012-02-29 13:05:08 +0000445 typedef unsigned int mask;
446 static const mask space = _ISSPACE;
447 static const mask print = _ISPRINT;
448 static const mask cntrl = _ISCNTRL;
449 static const mask upper = _ISUPPER;
450 static const mask lower = _ISLOWER;
451 static const mask alpha = _ISALPHA;
452 static const mask digit = _ISDIGIT;
453 static const mask punct = _ISPUNCT;
454 static const mask xdigit = _ISXDIGIT;
455 static const mask blank = _ISBLANK;
JF Bastien0c265d82015-02-25 22:16:46 +0000456#elif defined(_NEWLIB_VERSION)
457 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
458 typedef char mask;
459 static const mask space = _S;
460 static const mask print = _P | _U | _L | _N | _B;
461 static const mask cntrl = _C;
462 static const mask upper = _U;
463 static const mask lower = _L;
464 static const mask alpha = _U | _L;
465 static const mask digit = _N;
466 static const mask punct = _P;
467 static const mask xdigit = _X | _N;
468 static const mask blank = _B;
Jonathan Roelofsae9ab252015-03-11 17:00:28 +0000469# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
470# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
471# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
JF Bastien0c265d82015-02-25 22:16:46 +0000472#else
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000473 typedef unsigned long mask;
474 static const mask space = 1<<0;
475 static const mask print = 1<<1;
476 static const mask cntrl = 1<<2;
477 static const mask upper = 1<<3;
478 static const mask lower = 1<<4;
479 static const mask alpha = 1<<5;
480 static const mask digit = 1<<6;
481 static const mask punct = 1<<7;
482 static const mask xdigit = 1<<8;
483 static const mask blank = 1<<9;
JF Bastien0c265d82015-02-25 22:16:46 +0000484#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000485 static const mask alnum = alpha | digit;
486 static const mask graph = alnum | punct;
487
Louis Dionne16fe2952018-07-11 23:14:33 +0000488 _LIBCPP_INLINE_VISIBILITY ctype_base() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000489};
490
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000491template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000492
493template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000494class _LIBCPP_TYPE_VIS ctype<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000495 : public locale::facet,
496 public ctype_base
497{
498public:
499 typedef wchar_t char_type;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000500
Louis Dionne16fe2952018-07-11 23:14:33 +0000501 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000502 explicit ctype(size_t __refs = 0)
503 : locale::facet(__refs) {}
504
Louis Dionne16fe2952018-07-11 23:14:33 +0000505 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000506 bool is(mask __m, char_type __c) const
507 {
508 return do_is(__m, __c);
509 }
510
Louis Dionne16fe2952018-07-11 23:14:33 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000512 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
513 {
514 return do_is(__low, __high, __vec);
515 }
516
Louis Dionne16fe2952018-07-11 23:14:33 +0000517 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000518 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
519 {
520 return do_scan_is(__m, __low, __high);
521 }
522
Louis Dionne16fe2952018-07-11 23:14:33 +0000523 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000524 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
525 {
526 return do_scan_not(__m, __low, __high);
527 }
528
Louis Dionne16fe2952018-07-11 23:14:33 +0000529 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000530 char_type toupper(char_type __c) const
531 {
532 return do_toupper(__c);
533 }
534
Louis Dionne16fe2952018-07-11 23:14:33 +0000535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000536 const char_type* toupper(char_type* __low, const char_type* __high) const
537 {
538 return do_toupper(__low, __high);
539 }
540
Louis Dionne16fe2952018-07-11 23:14:33 +0000541 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000542 char_type tolower(char_type __c) const
543 {
544 return do_tolower(__c);
545 }
546
Louis Dionne16fe2952018-07-11 23:14:33 +0000547 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000548 const char_type* tolower(char_type* __low, const char_type* __high) const
549 {
550 return do_tolower(__low, __high);
551 }
552
Louis Dionne16fe2952018-07-11 23:14:33 +0000553 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000554 char_type widen(char __c) const
555 {
556 return do_widen(__c);
557 }
558
Louis Dionne16fe2952018-07-11 23:14:33 +0000559 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000560 const char* widen(const char* __low, const char* __high, char_type* __to) const
561 {
562 return do_widen(__low, __high, __to);
563 }
564
Louis Dionne16fe2952018-07-11 23:14:33 +0000565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000566 char narrow(char_type __c, char __dfault) const
567 {
568 return do_narrow(__c, __dfault);
569 }
570
Louis Dionne16fe2952018-07-11 23:14:33 +0000571 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000572 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
573 {
574 return do_narrow(__low, __high, __dfault, __to);
575 }
576
577 static locale::id id;
578
579protected:
580 ~ctype();
581 virtual bool do_is(mask __m, char_type __c) const;
582 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
583 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
584 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
585 virtual char_type do_toupper(char_type) const;
586 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
587 virtual char_type do_tolower(char_type) const;
588 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
589 virtual char_type do_widen(char) const;
590 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
591 virtual char do_narrow(char_type, char __dfault) const;
592 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
593};
594
595template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000596class _LIBCPP_TYPE_VIS ctype<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000597 : public locale::facet, public ctype_base
598{
599 const mask* __tab_;
600 bool __del_;
601public:
602 typedef char char_type;
603
604 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
605
Louis Dionne16fe2952018-07-11 23:14:33 +0000606 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000607 bool is(mask __m, char_type __c) const
608 {
Marshall Clow11de4872013-10-21 14:41:05 +0000609 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000610 }
611
Louis Dionne16fe2952018-07-11 23:14:33 +0000612 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000613 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
614 {
615 for (; __low != __high; ++__low, ++__vec)
Howard Hinnant28b24882011-12-01 20:21:04 +0000616 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000617 return __low;
618 }
619
Louis Dionne16fe2952018-07-11 23:14:33 +0000620 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000621 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
622 {
623 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000624 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000625 break;
626 return __low;
627 }
628
Louis Dionne16fe2952018-07-11 23:14:33 +0000629 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000630 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
631 {
632 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000633 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000634 break;
635 return __low;
636 }
637
Louis Dionne16fe2952018-07-11 23:14:33 +0000638 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000639 char_type toupper(char_type __c) const
640 {
641 return do_toupper(__c);
642 }
643
Louis Dionne16fe2952018-07-11 23:14:33 +0000644 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000645 const char_type* toupper(char_type* __low, const char_type* __high) const
646 {
647 return do_toupper(__low, __high);
648 }
649
Louis Dionne16fe2952018-07-11 23:14:33 +0000650 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000651 char_type tolower(char_type __c) const
652 {
653 return do_tolower(__c);
654 }
655
Louis Dionne16fe2952018-07-11 23:14:33 +0000656 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000657 const char_type* tolower(char_type* __low, const char_type* __high) const
658 {
659 return do_tolower(__low, __high);
660 }
661
Louis Dionne16fe2952018-07-11 23:14:33 +0000662 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000663 char_type widen(char __c) const
664 {
665 return do_widen(__c);
666 }
667
Louis Dionne16fe2952018-07-11 23:14:33 +0000668 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000669 const char* widen(const char* __low, const char* __high, char_type* __to) const
670 {
671 return do_widen(__low, __high, __to);
672 }
673
Louis Dionne16fe2952018-07-11 23:14:33 +0000674 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000675 char narrow(char_type __c, char __dfault) const
676 {
677 return do_narrow(__c, __dfault);
678 }
679
Louis Dionne16fe2952018-07-11 23:14:33 +0000680 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000681 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
682 {
683 return do_narrow(__low, __high, __dfault, __to);
684 }
685
686 static locale::id id;
687
Howard Hinnant155c2af2010-05-24 17:49:41 +0000688#ifdef _CACHED_RUNES
Howard Hinnantc51e1022010-05-11 19:42:16 +0000689 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000690#else
691 static const size_t table_size = 256; // FIXME: Don't hardcode this.
692#endif
Louis Dionne16fe2952018-07-11 23:14:33 +0000693 _LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;}
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000694 static const mask* classic_table() _NOEXCEPT;
Vasileios Kalintirisc5dd8942015-11-24 10:24:54 +0000695#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000696 static const int* __classic_upper_table() _NOEXCEPT;
697 static const int* __classic_lower_table() _NOEXCEPT;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000698#endif
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000699#if defined(__NetBSD__)
700 static const short* __classic_upper_table() _NOEXCEPT;
701 static const short* __classic_lower_table() _NOEXCEPT;
702#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000703
704protected:
705 ~ctype();
706 virtual char_type do_toupper(char_type __c) const;
707 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
708 virtual char_type do_tolower(char_type __c) const;
709 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
710 virtual char_type do_widen(char __c) const;
711 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
712 virtual char do_narrow(char_type __c, char __dfault) const;
713 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
714};
715
716// template <class CharT> class ctype_byname;
717
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000718template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000719
720template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000721class _LIBCPP_TYPE_VIS ctype_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000722 : public ctype<char>
723{
724 locale_t __l;
725
726public:
727 explicit ctype_byname(const char*, size_t = 0);
728 explicit ctype_byname(const string&, size_t = 0);
729
730protected:
731 ~ctype_byname();
732 virtual char_type do_toupper(char_type) const;
733 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
734 virtual char_type do_tolower(char_type) const;
735 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
736};
737
738template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000739class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000740 : public ctype<wchar_t>
741{
742 locale_t __l;
743
744public:
745 explicit ctype_byname(const char*, size_t = 0);
746 explicit ctype_byname(const string&, size_t = 0);
747
748protected:
749 ~ctype_byname();
750 virtual bool do_is(mask __m, char_type __c) const;
751 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
752 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
753 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
754 virtual char_type do_toupper(char_type) const;
755 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
756 virtual char_type do_tolower(char_type) const;
757 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
758 virtual char_type do_widen(char) const;
759 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
760 virtual char do_narrow(char_type, char __dfault) const;
761 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
762};
763
764template <class _CharT>
765inline _LIBCPP_INLINE_VISIBILITY
766bool
767isspace(_CharT __c, const locale& __loc)
768{
769 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
770}
771
772template <class _CharT>
773inline _LIBCPP_INLINE_VISIBILITY
774bool
775isprint(_CharT __c, const locale& __loc)
776{
777 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
778}
779
780template <class _CharT>
781inline _LIBCPP_INLINE_VISIBILITY
782bool
783iscntrl(_CharT __c, const locale& __loc)
784{
785 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
786}
787
788template <class _CharT>
789inline _LIBCPP_INLINE_VISIBILITY
790bool
791isupper(_CharT __c, const locale& __loc)
792{
793 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
794}
795
796template <class _CharT>
797inline _LIBCPP_INLINE_VISIBILITY
798bool
799islower(_CharT __c, const locale& __loc)
800{
801 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
802}
803
804template <class _CharT>
805inline _LIBCPP_INLINE_VISIBILITY
806bool
807isalpha(_CharT __c, const locale& __loc)
808{
809 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
810}
811
812template <class _CharT>
813inline _LIBCPP_INLINE_VISIBILITY
814bool
815isdigit(_CharT __c, const locale& __loc)
816{
817 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
818}
819
820template <class _CharT>
821inline _LIBCPP_INLINE_VISIBILITY
822bool
823ispunct(_CharT __c, const locale& __loc)
824{
825 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
826}
827
828template <class _CharT>
829inline _LIBCPP_INLINE_VISIBILITY
830bool
831isxdigit(_CharT __c, const locale& __loc)
832{
833 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
834}
835
836template <class _CharT>
837inline _LIBCPP_INLINE_VISIBILITY
838bool
839isalnum(_CharT __c, const locale& __loc)
840{
841 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
842}
843
844template <class _CharT>
845inline _LIBCPP_INLINE_VISIBILITY
846bool
847isgraph(_CharT __c, const locale& __loc)
848{
849 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
850}
851
852template <class _CharT>
853inline _LIBCPP_INLINE_VISIBILITY
854_CharT
855toupper(_CharT __c, const locale& __loc)
856{
857 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
858}
859
860template <class _CharT>
861inline _LIBCPP_INLINE_VISIBILITY
862_CharT
863tolower(_CharT __c, const locale& __loc)
864{
865 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
866}
867
868// codecvt_base
869
Howard Hinnant8331b762013-03-06 23:30:19 +0000870class _LIBCPP_TYPE_VIS codecvt_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000871{
872public:
Louis Dionne16fe2952018-07-11 23:14:33 +0000873 _LIBCPP_INLINE_VISIBILITY codecvt_base() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000874 enum result {ok, partial, error, noconv};
875};
876
877// template <class internT, class externT, class stateT> class codecvt;
878
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000879template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000880
881// template <> class codecvt<char, char, mbstate_t>
882
883template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000884class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000885 : public locale::facet,
886 public codecvt_base
887{
888public:
889 typedef char intern_type;
890 typedef char extern_type;
891 typedef mbstate_t state_type;
892
Louis Dionne16fe2952018-07-11 23:14:33 +0000893 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000894 explicit codecvt(size_t __refs = 0)
895 : locale::facet(__refs) {}
896
Louis Dionne16fe2952018-07-11 23:14:33 +0000897 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000898 result out(state_type& __st,
899 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
900 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
901 {
902 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
903 }
904
Louis Dionne16fe2952018-07-11 23:14:33 +0000905 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000906 result unshift(state_type& __st,
907 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
908 {
909 return do_unshift(__st, __to, __to_end, __to_nxt);
910 }
911
Louis Dionne16fe2952018-07-11 23:14:33 +0000912 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000913 result in(state_type& __st,
914 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
915 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
916 {
917 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
918 }
919
Louis Dionne16fe2952018-07-11 23:14:33 +0000920 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000921 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000922 {
923 return do_encoding();
924 }
925
Louis Dionne16fe2952018-07-11 23:14:33 +0000926 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000927 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000928 {
929 return do_always_noconv();
930 }
931
Louis Dionne16fe2952018-07-11 23:14:33 +0000932 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000933 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
934 {
935 return do_length(__st, __frm, __end, __mx);
936 }
937
Louis Dionne16fe2952018-07-11 23:14:33 +0000938 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000939 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000940 {
941 return do_max_length();
942 }
943
944 static locale::id id;
945
946protected:
Louis Dionne16fe2952018-07-11 23:14:33 +0000947 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000948 explicit codecvt(const char*, size_t __refs = 0)
949 : locale::facet(__refs) {}
950
951 ~codecvt();
952
953 virtual result do_out(state_type& __st,
954 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
955 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
956 virtual result do_in(state_type& __st,
957 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
958 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
959 virtual result do_unshift(state_type& __st,
960 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000961 virtual int do_encoding() const _NOEXCEPT;
962 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000963 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 +0000964 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000965};
966
967// template <> class codecvt<wchar_t, char, mbstate_t>
968
969template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000970class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000971 : public locale::facet,
972 public codecvt_base
973{
974 locale_t __l;
975public:
976 typedef wchar_t intern_type;
977 typedef char extern_type;
978 typedef mbstate_t state_type;
979
980 explicit codecvt(size_t __refs = 0);
981
Louis Dionne16fe2952018-07-11 23:14:33 +0000982 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000983 result out(state_type& __st,
984 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
985 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
986 {
987 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
988 }
989
Louis Dionne16fe2952018-07-11 23:14:33 +0000990 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000991 result unshift(state_type& __st,
992 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
993 {
994 return do_unshift(__st, __to, __to_end, __to_nxt);
995 }
996
Louis Dionne16fe2952018-07-11 23:14:33 +0000997 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000998 result in(state_type& __st,
999 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1000 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1001 {
1002 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1003 }
1004
Louis Dionne16fe2952018-07-11 23:14:33 +00001005 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001006 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001007 {
1008 return do_encoding();
1009 }
1010
Louis Dionne16fe2952018-07-11 23:14:33 +00001011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001012 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001013 {
1014 return do_always_noconv();
1015 }
1016
Louis Dionne16fe2952018-07-11 23:14:33 +00001017 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001018 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1019 {
1020 return do_length(__st, __frm, __end, __mx);
1021 }
1022
Louis Dionne16fe2952018-07-11 23:14:33 +00001023 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001024 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001025 {
1026 return do_max_length();
1027 }
1028
1029 static locale::id id;
1030
1031protected:
1032 explicit codecvt(const char*, size_t __refs = 0);
1033
1034 ~codecvt();
1035
1036 virtual result do_out(state_type& __st,
1037 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1038 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1039 virtual result do_in(state_type& __st,
1040 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1041 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1042 virtual result do_unshift(state_type& __st,
1043 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001044 virtual int do_encoding() const _NOEXCEPT;
1045 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001046 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 +00001047 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001048};
1049
1050// template <> class codecvt<char16_t, char, mbstate_t>
1051
1052template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001053class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001054 : public locale::facet,
1055 public codecvt_base
1056{
1057public:
1058 typedef char16_t intern_type;
1059 typedef char extern_type;
1060 typedef mbstate_t state_type;
1061
Louis Dionne16fe2952018-07-11 23:14:33 +00001062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001063 explicit codecvt(size_t __refs = 0)
1064 : locale::facet(__refs) {}
1065
Louis Dionne16fe2952018-07-11 23:14:33 +00001066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001067 result out(state_type& __st,
1068 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1069 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1070 {
1071 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1072 }
1073
Louis Dionne16fe2952018-07-11 23:14:33 +00001074 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001075 result unshift(state_type& __st,
1076 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1077 {
1078 return do_unshift(__st, __to, __to_end, __to_nxt);
1079 }
1080
Louis Dionne16fe2952018-07-11 23:14:33 +00001081 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001082 result in(state_type& __st,
1083 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1084 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1085 {
1086 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1087 }
1088
Louis Dionne16fe2952018-07-11 23:14:33 +00001089 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001090 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001091 {
1092 return do_encoding();
1093 }
1094
Louis Dionne16fe2952018-07-11 23:14:33 +00001095 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001096 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001097 {
1098 return do_always_noconv();
1099 }
1100
Louis Dionne16fe2952018-07-11 23:14:33 +00001101 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001102 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1103 {
1104 return do_length(__st, __frm, __end, __mx);
1105 }
1106
Louis Dionne16fe2952018-07-11 23:14:33 +00001107 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001108 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001109 {
1110 return do_max_length();
1111 }
1112
1113 static locale::id id;
1114
1115protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00001116 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001117 explicit codecvt(const char*, size_t __refs = 0)
1118 : locale::facet(__refs) {}
1119
1120 ~codecvt();
1121
1122 virtual result do_out(state_type& __st,
1123 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1124 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1125 virtual result do_in(state_type& __st,
1126 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1127 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1128 virtual result do_unshift(state_type& __st,
1129 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001130 virtual int do_encoding() const _NOEXCEPT;
1131 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001132 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 +00001133 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001134};
1135
1136// template <> class codecvt<char32_t, char, mbstate_t>
1137
1138template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001139class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001140 : public locale::facet,
1141 public codecvt_base
1142{
1143public:
1144 typedef char32_t intern_type;
1145 typedef char extern_type;
1146 typedef mbstate_t state_type;
1147
Louis Dionne16fe2952018-07-11 23:14:33 +00001148 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001149 explicit codecvt(size_t __refs = 0)
1150 : locale::facet(__refs) {}
1151
Louis Dionne16fe2952018-07-11 23:14:33 +00001152 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001153 result out(state_type& __st,
1154 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1155 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1156 {
1157 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1158 }
1159
Louis Dionne16fe2952018-07-11 23:14:33 +00001160 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001161 result unshift(state_type& __st,
1162 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1163 {
1164 return do_unshift(__st, __to, __to_end, __to_nxt);
1165 }
1166
Louis Dionne16fe2952018-07-11 23:14:33 +00001167 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001168 result in(state_type& __st,
1169 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1170 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1171 {
1172 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1173 }
1174
Louis Dionne16fe2952018-07-11 23:14:33 +00001175 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001176 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001177 {
1178 return do_encoding();
1179 }
1180
Louis Dionne16fe2952018-07-11 23:14:33 +00001181 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001182 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001183 {
1184 return do_always_noconv();
1185 }
1186
Louis Dionne16fe2952018-07-11 23:14:33 +00001187 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001188 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1189 {
1190 return do_length(__st, __frm, __end, __mx);
1191 }
1192
Louis Dionne16fe2952018-07-11 23:14:33 +00001193 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001194 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001195 {
1196 return do_max_length();
1197 }
1198
1199 static locale::id id;
1200
1201protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00001202 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001203 explicit codecvt(const char*, size_t __refs = 0)
1204 : locale::facet(__refs) {}
1205
1206 ~codecvt();
1207
1208 virtual result do_out(state_type& __st,
1209 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1210 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1211 virtual result do_in(state_type& __st,
1212 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1213 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1214 virtual result do_unshift(state_type& __st,
1215 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001216 virtual int do_encoding() const _NOEXCEPT;
1217 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001218 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 +00001219 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001220};
1221
Howard Hinnantc51e1022010-05-11 19:42:16 +00001222// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1223
1224template <class _InternT, class _ExternT, class _StateT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001225class _LIBCPP_TEMPLATE_VIS codecvt_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00001226 : public codecvt<_InternT, _ExternT, _StateT>
1227{
1228public:
Louis Dionne16fe2952018-07-11 23:14:33 +00001229 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001230 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1231 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Louis Dionne16fe2952018-07-11 23:14:33 +00001232 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001233 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1234 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1235protected:
1236 ~codecvt_byname();
1237};
1238
1239template <class _InternT, class _ExternT, class _StateT>
1240codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1241{
1242}
1243
Eric Fiselier1b57fa82016-09-15 22:27:07 +00001244_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
1245_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
1246_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
1247_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001248
Howard Hinnantc834c512011-11-29 18:15:50 +00001249template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001250struct __narrow_to_utf8
1251{
1252 template <class _OutputIterator, class _CharT>
1253 _OutputIterator
1254 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1255};
1256
1257template <>
1258struct __narrow_to_utf8<8>
1259{
1260 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001261 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001262 _OutputIterator
1263 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1264 {
1265 for (; __wb < __we; ++__wb, ++__s)
1266 *__s = *__wb;
1267 return __s;
1268 }
1269};
1270
1271template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001272struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001273 : public codecvt<char16_t, char, mbstate_t>
1274{
Louis Dionne16fe2952018-07-11 23:14:33 +00001275 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001276 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1277
Louis Dionne5254b372018-10-25 12:13:43 +00001278 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001279
1280 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001281 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001282 _OutputIterator
1283 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1284 {
1285 result __r = ok;
1286 mbstate_t __mb;
1287 while (__wb < __we && __r != error)
1288 {
1289 const int __sz = 32;
1290 char __buf[__sz];
1291 char* __bn;
1292 const char16_t* __wn = (const char16_t*)__wb;
1293 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1294 __buf, __buf+__sz, __bn);
1295 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1296 __throw_runtime_error("locale not supported");
1297 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1298 *__s = *__p;
1299 __wb = (const _CharT*)__wn;
1300 }
1301 return __s;
1302 }
1303};
1304
1305template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001306struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001307 : public codecvt<char32_t, char, mbstate_t>
1308{
Louis Dionne16fe2952018-07-11 23:14:33 +00001309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001310 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1311
Louis Dionne5254b372018-10-25 12:13:43 +00001312 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001313
1314 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001316 _OutputIterator
1317 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1318 {
1319 result __r = ok;
1320 mbstate_t __mb;
1321 while (__wb < __we && __r != error)
1322 {
1323 const int __sz = 32;
1324 char __buf[__sz];
1325 char* __bn;
1326 const char32_t* __wn = (const char32_t*)__wb;
1327 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1328 __buf, __buf+__sz, __bn);
1329 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1330 __throw_runtime_error("locale not supported");
1331 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1332 *__s = *__p;
1333 __wb = (const _CharT*)__wn;
1334 }
1335 return __s;
1336 }
1337};
1338
Howard Hinnantc834c512011-11-29 18:15:50 +00001339template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001340struct __widen_from_utf8
1341{
1342 template <class _OutputIterator>
1343 _OutputIterator
1344 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1345};
1346
1347template <>
1348struct __widen_from_utf8<8>
1349{
1350 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001351 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001352 _OutputIterator
1353 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1354 {
1355 for (; __nb < __ne; ++__nb, ++__s)
1356 *__s = *__nb;
1357 return __s;
1358 }
1359};
1360
1361template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001362struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001363 : public codecvt<char16_t, char, mbstate_t>
1364{
Louis Dionne16fe2952018-07-11 23:14:33 +00001365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001366 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1367
Louis Dionne5254b372018-10-25 12:13:43 +00001368 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001369
1370 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001371 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001372 _OutputIterator
1373 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1374 {
1375 result __r = ok;
1376 mbstate_t __mb;
1377 while (__nb < __ne && __r != error)
1378 {
1379 const int __sz = 32;
1380 char16_t __buf[__sz];
1381 char16_t* __bn;
1382 const char* __nn = __nb;
1383 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1384 __buf, __buf+__sz, __bn);
1385 if (__r == codecvt_base::error || __nn == __nb)
1386 __throw_runtime_error("locale not supported");
1387 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1388 *__s = (wchar_t)*__p;
1389 __nb = __nn;
1390 }
1391 return __s;
1392 }
1393};
1394
1395template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001396struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001397 : public codecvt<char32_t, char, mbstate_t>
1398{
Louis Dionne16fe2952018-07-11 23:14:33 +00001399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001400 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1401
Louis Dionne5254b372018-10-25 12:13:43 +00001402 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001403
1404 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001405 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001406 _OutputIterator
1407 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1408 {
1409 result __r = ok;
1410 mbstate_t __mb;
1411 while (__nb < __ne && __r != error)
1412 {
1413 const int __sz = 32;
1414 char32_t __buf[__sz];
1415 char32_t* __bn;
1416 const char* __nn = __nb;
1417 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1418 __buf, __buf+__sz, __bn);
1419 if (__r == codecvt_base::error || __nn == __nb)
1420 __throw_runtime_error("locale not supported");
1421 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1422 *__s = (wchar_t)*__p;
1423 __nb = __nn;
1424 }
1425 return __s;
1426 }
1427};
1428
1429// template <class charT> class numpunct
1430
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001431template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001432
1433template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001434class _LIBCPP_TYPE_VIS numpunct<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001435 : public locale::facet
1436{
1437public:
1438 typedef char char_type;
1439 typedef basic_string<char_type> string_type;
1440
1441 explicit numpunct(size_t __refs = 0);
1442
Louis Dionne16fe2952018-07-11 23:14:33 +00001443 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
1444 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
1445 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
1446 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
1447 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001448
1449 static locale::id id;
1450
1451protected:
1452 ~numpunct();
1453 virtual char_type do_decimal_point() const;
1454 virtual char_type do_thousands_sep() const;
1455 virtual string do_grouping() const;
1456 virtual string_type do_truename() const;
1457 virtual string_type do_falsename() const;
1458
1459 char_type __decimal_point_;
1460 char_type __thousands_sep_;
1461 string __grouping_;
1462};
1463
1464template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001465class _LIBCPP_TYPE_VIS numpunct<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001466 : public locale::facet
1467{
1468public:
1469 typedef wchar_t char_type;
1470 typedef basic_string<char_type> string_type;
1471
1472 explicit numpunct(size_t __refs = 0);
1473
Louis Dionne16fe2952018-07-11 23:14:33 +00001474 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
1475 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
1476 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
1477 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
1478 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001479
1480 static locale::id id;
1481
1482protected:
1483 ~numpunct();
1484 virtual char_type do_decimal_point() const;
1485 virtual char_type do_thousands_sep() const;
1486 virtual string do_grouping() const;
1487 virtual string_type do_truename() const;
1488 virtual string_type do_falsename() const;
1489
1490 char_type __decimal_point_;
1491 char_type __thousands_sep_;
1492 string __grouping_;
1493};
1494
1495// template <class charT> class numpunct_byname
1496
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001497template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001498
1499template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001500class _LIBCPP_TYPE_VIS numpunct_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001501: public numpunct<char>
1502{
1503public:
1504 typedef char char_type;
1505 typedef basic_string<char_type> string_type;
1506
1507 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1508 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1509
1510protected:
1511 ~numpunct_byname();
1512
1513private:
1514 void __init(const char*);
1515};
1516
1517template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001518class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001519: public numpunct<wchar_t>
1520{
1521public:
1522 typedef wchar_t char_type;
1523 typedef basic_string<char_type> string_type;
1524
1525 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1526 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1527
1528protected:
1529 ~numpunct_byname();
1530
1531private:
1532 void __init(const char*);
1533};
1534
1535_LIBCPP_END_NAMESPACE_STD
1536
1537#endif // _LIBCPP___LOCALE