blob: c5c078756ce3bc24f44b2cf8cea9ceb77da2b78a [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP___LOCALE
12#define _LIBCPP___LOCALE
13
14#include <__config>
15#include <string>
16#include <memory>
17#include <utility>
18#include <mutex>
19#include <cstdint>
20#include <cctype>
Howard Hinnantadff4892010-05-24 17:49:41 +000021#include <locale.h>
Howard Hinnantef5aa932013-09-17 01:34:47 +000022#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Howard Hinnant14fa9f92011-09-29 20:33:10 +000023# include <support/win32/locale_win32.h>
Marshall Clowbe3d1172014-03-11 17:18:47 +000024#elif defined(_AIX)
Howard Hinnant7f764502013-08-14 18:00:20 +000025# include <support/ibm/xlocale.h>
Dan Albert2ef012e2014-04-08 12:03:21 -070026#elif defined(__ANDROID__)
Marshall Clowe45cf3e2014-07-10 15:20:28 +000027// Android gained the locale aware functions in L (API level 21)
28# include <android/api-level.h>
29# if __ANDROID_API__ <= 20
30# include <support/android/locale_bionic.h>
31# endif
32#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) \
33 || defined(__sun__) || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
Howard Hinnant92a07002011-09-22 19:10:18 +000034# include <xlocale.h>
Marshall Clowe45cf3e2014-07-10 15:20:28 +000035#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000036
Howard Hinnant08e17472011-10-17 20:05:10 +000037#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000038#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000039#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000040
41_LIBCPP_BEGIN_NAMESPACE_STD
42
Howard Hinnant83eade62013-03-06 23:30:19 +000043class _LIBCPP_TYPE_VIS locale;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000044
Howard Hinnant33be35e2012-09-14 00:39:16 +000045template <class _Facet>
46_LIBCPP_INLINE_VISIBILITY
47bool
48has_facet(const locale&) _NOEXCEPT;
49
50template <class _Facet>
51_LIBCPP_INLINE_VISIBILITY
52const _Facet&
53use_facet(const locale&);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000054
Howard Hinnant83eade62013-03-06 23:30:19 +000055class _LIBCPP_TYPE_VIS locale
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000056{
57public:
58 // types:
Howard Hinnant83eade62013-03-06 23:30:19 +000059 class _LIBCPP_TYPE_VIS facet;
60 class _LIBCPP_TYPE_VIS id;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000061
62 typedef int category;
63 static const category // values assigned here are for exposition only
64 none = 0,
65 collate = LC_COLLATE_MASK,
66 ctype = LC_CTYPE_MASK,
67 monetary = LC_MONETARY_MASK,
68 numeric = LC_NUMERIC_MASK,
69 time = LC_TIME_MASK,
70 messages = LC_MESSAGES_MASK,
71 all = collate | ctype | monetary | numeric | time | messages;
72
73 // construct/copy/destroy:
Howard Hinnantc9834542011-05-31 15:34:58 +000074 locale() _NOEXCEPT;
75 locale(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000076 explicit locale(const char*);
77 explicit locale(const string&);
78 locale(const locale&, const char*, category);
79 locale(const locale&, const string&, category);
Howard Hinnant2d72b1e2010-12-17 14:46:43 +000080 template <class _Facet>
81 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000082 locale(const locale&, const locale&, category);
83
Howard Hinnantc9834542011-05-31 15:34:58 +000084 ~locale();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000085
Howard Hinnantc9834542011-05-31 15:34:58 +000086 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000087
88 template <class _Facet> locale combine(const locale&) const;
89
90 // locale operations:
91 string name() const;
92 bool operator==(const locale&) const;
93 bool operator!=(const locale& __y) const {return !(*this == __y);}
94 template <class _CharT, class _Traits, class _Allocator>
95 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
96 const basic_string<_CharT, _Traits, _Allocator>&) const;
97
98 // global locale objects:
99 static locale global(const locale&);
100 static const locale& classic();
101
102private:
103 class __imp;
104 __imp* __locale_;
105
106 void __install_ctor(const locale&, facet*, long);
107 static locale& __global();
108 bool has_facet(id&) const;
109 const facet* use_facet(id&) const;
110
Howard Hinnantc9834542011-05-31 15:34:58 +0000111 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000112 template <class _Facet> friend const _Facet& use_facet(const locale&);
113};
114
Howard Hinnant83eade62013-03-06 23:30:19 +0000115class _LIBCPP_TYPE_VIS locale::facet
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000116 : public __shared_count
117{
118protected:
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000119 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000120 explicit facet(size_t __refs = 0)
121 : __shared_count(static_cast<long>(__refs)-1) {}
122
123 virtual ~facet();
124
125// facet(const facet&) = delete; // effectively done in __shared_count
126// void operator=(const facet&) = delete;
127private:
Howard Hinnant1694d232011-05-28 14:41:13 +0000128 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129};
130
Howard Hinnant83eade62013-03-06 23:30:19 +0000131class _LIBCPP_TYPE_VIS locale::id
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000132{
133 once_flag __flag_;
134 int32_t __id_;
Howard Hinnant324bb032010-08-22 00:02:43 +0000135
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000136 static int32_t __next_id;
137public:
Howard Hinnantf3d62ea2012-07-26 16:14:37 +0000138 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000139private:
140 void __init();
141 void operator=(const id&); // = delete;
142 id(const id&); // = delete;
143public: // only needed for tests
144 long __get();
145
146 friend class locale;
147 friend class locale::__imp;
148};
149
150template <class _Facet>
151inline _LIBCPP_INLINE_VISIBILITY
152locale::locale(const locale& __other, _Facet* __f)
153{
154 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
155}
156
157template <class _Facet>
158locale
159locale::combine(const locale& __other) const
160{
Howard Hinnantd4444702010-08-11 17:04:31 +0000161#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +0000162 if (!_VSTD::has_facet<_Facet>(__other))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000163 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnant324bb032010-08-22 00:02:43 +0000164#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +0000165 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000166}
167
168template <class _Facet>
169inline _LIBCPP_INLINE_VISIBILITY
170bool
Howard Hinnantc9834542011-05-31 15:34:58 +0000171has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000172{
173 return __l.has_facet(_Facet::id);
174}
175
176template <class _Facet>
177inline _LIBCPP_INLINE_VISIBILITY
178const _Facet&
179use_facet(const locale& __l)
180{
181 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
182}
183
184// template <class _CharT> class collate;
185
186template <class _CharT>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000187class _LIBCPP_TYPE_VIS_ONLY collate
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000188 : public locale::facet
189{
190public:
191 typedef _CharT char_type;
192 typedef basic_string<char_type> string_type;
193
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000194 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000195 explicit collate(size_t __refs = 0)
196 : locale::facet(__refs) {}
197
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000198 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000199 int compare(const char_type* __lo1, const char_type* __hi1,
200 const char_type* __lo2, const char_type* __hi2) const
201 {
202 return do_compare(__lo1, __hi1, __lo2, __hi2);
203 }
204
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000206 string_type transform(const char_type* __lo, const char_type* __hi) const
207 {
208 return do_transform(__lo, __hi);
209 }
210
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000212 long hash(const char_type* __lo, const char_type* __hi) const
213 {
214 return do_hash(__lo, __hi);
215 }
216
217 static locale::id id;
218
219protected:
220 ~collate();
221 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
222 const char_type* __lo2, const char_type* __hi2) const;
223 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
224 {return string_type(__lo, __hi);}
225 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
226};
227
228template <class _CharT> locale::id collate<_CharT>::id;
229
230template <class _CharT>
231collate<_CharT>::~collate()
232{
233}
234
235template <class _CharT>
236int
237collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
238 const char_type* __lo2, const char_type* __hi2) const
239{
240 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
241 {
242 if (__lo1 == __hi1 || *__lo1 < *__lo2)
243 return -1;
244 if (*__lo2 < *__lo1)
245 return 1;
246 }
247 return __lo1 != __hi1;
248}
249
250template <class _CharT>
251long
Howard Hinnant11624452011-10-11 16:00:46 +0000252collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000253{
Howard Hinnant11624452011-10-11 16:00:46 +0000254 size_t __h = 0;
255 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
256 const size_t __mask = size_t(0xF) << (__sr + 4);
257 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000258 {
Howard Hinnantec3773c2011-12-01 20:21:04 +0000259 __h = (__h << 4) + static_cast<size_t>(*__p);
Howard Hinnant11624452011-10-11 16:00:46 +0000260 size_t __g = __h & __mask;
261 __h ^= __g | (__g >> __sr);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000262 }
Howard Hinnant11624452011-10-11 16:00:46 +0000263 return static_cast<long>(__h);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000264}
265
Howard Hinnant499cea12013-08-23 17:37:05 +0000266_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)
267_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000268
269// template <class CharT> class collate_byname;
270
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000271template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY collate_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000272
273template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000274class _LIBCPP_TYPE_VIS collate_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000275 : public collate<char>
276{
277 locale_t __l;
278public:
279 typedef char char_type;
280 typedef basic_string<char_type> string_type;
281
282 explicit collate_byname(const char* __n, size_t __refs = 0);
283 explicit collate_byname(const string& __n, size_t __refs = 0);
284
285protected:
286 ~collate_byname();
287 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
288 const char_type* __lo2, const char_type* __hi2) const;
289 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
290};
291
292template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000293class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000294 : public collate<wchar_t>
295{
296 locale_t __l;
297public:
298 typedef wchar_t char_type;
299 typedef basic_string<char_type> string_type;
300
301 explicit collate_byname(const char* __n, size_t __refs = 0);
302 explicit collate_byname(const string& __n, size_t __refs = 0);
303
304protected:
305 ~collate_byname();
306
307 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
308 const char_type* __lo2, const char_type* __hi2) const;
309 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
310};
311
312template <class _CharT, class _Traits, class _Allocator>
313bool
314locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
315 const basic_string<_CharT, _Traits, _Allocator>& __y) const
316{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000317 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000318 __x.data(), __x.data() + __x.size(),
319 __y.data(), __y.data() + __y.size()) < 0;
320}
321
322// template <class charT> class ctype
323
Howard Hinnant83eade62013-03-06 23:30:19 +0000324class _LIBCPP_TYPE_VIS ctype_base
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000325{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000326public:
Marshall Clow53e27632013-03-18 19:34:07 +0000327#ifdef __GLIBC__
Sean Hunt62a6ac32011-07-09 00:56:23 +0000328 typedef unsigned short mask;
Howard Hinnantadff4892010-05-24 17:49:41 +0000329 static const mask space = _ISspace;
330 static const mask print = _ISprint;
331 static const mask cntrl = _IScntrl;
332 static const mask upper = _ISupper;
333 static const mask lower = _ISlower;
334 static const mask alpha = _ISalpha;
335 static const mask digit = _ISdigit;
336 static const mask punct = _ISpunct;
337 static const mask xdigit = _ISxdigit;
338 static const mask blank = _ISblank;
Marshall Clowa22d2ad2013-03-18 17:04:29 +0000339#elif defined(_WIN32)
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000340 typedef unsigned short mask;
Howard Hinnant92a07002011-09-22 19:10:18 +0000341 static const mask space = _SPACE;
342 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
343 static const mask cntrl = _CONTROL;
344 static const mask upper = _UPPER;
345 static const mask lower = _LOWER;
346 static const mask alpha = _ALPHA;
347 static const mask digit = _DIGIT;
348 static const mask punct = _PUNCT;
349 static const mask xdigit = _HEX;
350 static const mask blank = _BLANK;
Dan Albert2517f4f2014-04-17 17:42:46 -0700351#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__ANDROID__)
Marshall Clow53e27632013-03-18 19:34:07 +0000352#ifdef __APPLE__
David Chisnallc512df12011-09-21 08:39:44 +0000353 typedef __uint32_t mask;
Marshall Clow53e27632013-03-18 19:34:07 +0000354#elif defined(__FreeBSD__)
David Chisnallc512df12011-09-21 08:39:44 +0000355 typedef unsigned long mask;
Marshall Clow2ccffef2013-11-19 18:05:03 +0000356#elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
Howard Hinnantfc2f0212013-03-29 18:27:28 +0000357 typedef unsigned short mask;
Dan Albert2517f4f2014-04-17 17:42:46 -0700358#elif defined(__ANDROID__)
359 typedef char mask;
David Chisnallc512df12011-09-21 08:39:44 +0000360#endif
361 static const mask space = _CTYPE_S;
362 static const mask print = _CTYPE_R;
363 static const mask cntrl = _CTYPE_C;
364 static const mask upper = _CTYPE_U;
365 static const mask lower = _CTYPE_L;
366 static const mask alpha = _CTYPE_A;
367 static const mask digit = _CTYPE_D;
368 static const mask punct = _CTYPE_P;
Dan Albertd1ab5212014-07-23 19:32:03 +0000369# if defined(__ANDROID__)
370 static const mask xdigit = _CTYPE_X | _CTYPE_D;
371# else
David Chisnallc512df12011-09-21 08:39:44 +0000372 static const mask xdigit = _CTYPE_X;
Dan Albertd1ab5212014-07-23 19:32:03 +0000373# endif
374
Joerg Sonnenbergera71a9522013-05-17 21:17:34 +0000375# if defined(__NetBSD__)
376 static const mask blank = _CTYPE_BL;
377# else
David Chisnallc512df12011-09-21 08:39:44 +0000378 static const mask blank = _CTYPE_B;
Joerg Sonnenbergera71a9522013-05-17 21:17:34 +0000379# endif
Howard Hinnantcb0e6b62013-08-30 14:42:39 +0000380#elif defined(__sun__) || defined(_AIX)
David Chisnall997e4542012-02-29 13:05:08 +0000381 typedef unsigned int mask;
382 static const mask space = _ISSPACE;
383 static const mask print = _ISPRINT;
384 static const mask cntrl = _ISCNTRL;
385 static const mask upper = _ISUPPER;
386 static const mask lower = _ISLOWER;
387 static const mask alpha = _ISALPHA;
388 static const mask digit = _ISDIGIT;
389 static const mask punct = _ISPUNCT;
390 static const mask xdigit = _ISXDIGIT;
391 static const mask blank = _ISBLANK;
Marshall Clow2ccffef2013-11-19 18:05:03 +0000392#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __sun__
Howard Hinnant11624452011-10-11 16:00:46 +0000393 typedef unsigned long mask;
394 static const mask space = 1<<0;
395 static const mask print = 1<<1;
396 static const mask cntrl = 1<<2;
397 static const mask upper = 1<<3;
398 static const mask lower = 1<<4;
399 static const mask alpha = 1<<5;
400 static const mask digit = 1<<6;
401 static const mask punct = 1<<7;
402 static const mask xdigit = 1<<8;
403 static const mask blank = 1<<9;
404#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000405 static const mask alnum = alpha | digit;
406 static const mask graph = alnum | punct;
407
408 _LIBCPP_ALWAYS_INLINE ctype_base() {}
409};
410
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000411template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000412
413template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000414class _LIBCPP_TYPE_VIS ctype<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000415 : public locale::facet,
416 public ctype_base
417{
418public:
419 typedef wchar_t char_type;
Howard Hinnant324bb032010-08-22 00:02:43 +0000420
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000421 _LIBCPP_ALWAYS_INLINE
422 explicit ctype(size_t __refs = 0)
423 : locale::facet(__refs) {}
424
425 _LIBCPP_ALWAYS_INLINE
426 bool is(mask __m, char_type __c) const
427 {
428 return do_is(__m, __c);
429 }
430
431 _LIBCPP_ALWAYS_INLINE
432 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
433 {
434 return do_is(__low, __high, __vec);
435 }
436
437 _LIBCPP_ALWAYS_INLINE
438 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
439 {
440 return do_scan_is(__m, __low, __high);
441 }
442
443 _LIBCPP_ALWAYS_INLINE
444 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
445 {
446 return do_scan_not(__m, __low, __high);
447 }
448
449 _LIBCPP_ALWAYS_INLINE
450 char_type toupper(char_type __c) const
451 {
452 return do_toupper(__c);
453 }
454
455 _LIBCPP_ALWAYS_INLINE
456 const char_type* toupper(char_type* __low, const char_type* __high) const
457 {
458 return do_toupper(__low, __high);
459 }
460
461 _LIBCPP_ALWAYS_INLINE
462 char_type tolower(char_type __c) const
463 {
464 return do_tolower(__c);
465 }
466
467 _LIBCPP_ALWAYS_INLINE
468 const char_type* tolower(char_type* __low, const char_type* __high) const
469 {
470 return do_tolower(__low, __high);
471 }
472
473 _LIBCPP_ALWAYS_INLINE
474 char_type widen(char __c) const
475 {
476 return do_widen(__c);
477 }
478
479 _LIBCPP_ALWAYS_INLINE
480 const char* widen(const char* __low, const char* __high, char_type* __to) const
481 {
482 return do_widen(__low, __high, __to);
483 }
484
485 _LIBCPP_ALWAYS_INLINE
486 char narrow(char_type __c, char __dfault) const
487 {
488 return do_narrow(__c, __dfault);
489 }
490
491 _LIBCPP_ALWAYS_INLINE
492 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
493 {
494 return do_narrow(__low, __high, __dfault, __to);
495 }
496
497 static locale::id id;
498
499protected:
500 ~ctype();
501 virtual bool do_is(mask __m, char_type __c) const;
502 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
503 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
504 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
505 virtual char_type do_toupper(char_type) const;
506 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
507 virtual char_type do_tolower(char_type) const;
508 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
509 virtual char_type do_widen(char) const;
510 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
511 virtual char do_narrow(char_type, char __dfault) const;
512 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
513};
514
515template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000516class _LIBCPP_TYPE_VIS ctype<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000517 : public locale::facet, public ctype_base
518{
519 const mask* __tab_;
520 bool __del_;
521public:
522 typedef char char_type;
523
524 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
525
526 _LIBCPP_ALWAYS_INLINE
527 bool is(mask __m, char_type __c) const
528 {
Marshall Clow8a43fca2013-10-21 14:41:05 +0000529 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000530 }
531
532 _LIBCPP_ALWAYS_INLINE
533 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
534 {
535 for (; __low != __high; ++__low, ++__vec)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000536 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000537 return __low;
538 }
539
540 _LIBCPP_ALWAYS_INLINE
541 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
542 {
543 for (; __low != __high; ++__low)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000544 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000545 break;
546 return __low;
547 }
548
549 _LIBCPP_ALWAYS_INLINE
550 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
551 {
552 for (; __low != __high; ++__low)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000553 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000554 break;
555 return __low;
556 }
557
558 _LIBCPP_ALWAYS_INLINE
559 char_type toupper(char_type __c) const
560 {
561 return do_toupper(__c);
562 }
563
564 _LIBCPP_ALWAYS_INLINE
565 const char_type* toupper(char_type* __low, const char_type* __high) const
566 {
567 return do_toupper(__low, __high);
568 }
569
570 _LIBCPP_ALWAYS_INLINE
571 char_type tolower(char_type __c) const
572 {
573 return do_tolower(__c);
574 }
575
576 _LIBCPP_ALWAYS_INLINE
577 const char_type* tolower(char_type* __low, const char_type* __high) const
578 {
579 return do_tolower(__low, __high);
580 }
581
582 _LIBCPP_ALWAYS_INLINE
583 char_type widen(char __c) const
584 {
585 return do_widen(__c);
586 }
587
588 _LIBCPP_ALWAYS_INLINE
589 const char* widen(const char* __low, const char* __high, char_type* __to) const
590 {
591 return do_widen(__low, __high, __to);
592 }
593
594 _LIBCPP_ALWAYS_INLINE
595 char narrow(char_type __c, char __dfault) const
596 {
597 return do_narrow(__c, __dfault);
598 }
599
600 _LIBCPP_ALWAYS_INLINE
601 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
602 {
603 return do_narrow(__low, __high, __dfault, __to);
604 }
605
606 static locale::id id;
607
Howard Hinnantadff4892010-05-24 17:49:41 +0000608#ifdef _CACHED_RUNES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000609 static const size_t table_size = _CACHED_RUNES;
Howard Hinnantadff4892010-05-24 17:49:41 +0000610#else
611 static const size_t table_size = 256; // FIXME: Don't hardcode this.
612#endif
Howard Hinnantc9834542011-05-31 15:34:58 +0000613 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
614 static const mask* classic_table() _NOEXCEPT;
Marshall Clow2ccffef2013-11-19 18:05:03 +0000615#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000616 static const int* __classic_upper_table() _NOEXCEPT;
617 static const int* __classic_lower_table() _NOEXCEPT;
Sean Hunte59f7242011-07-09 01:09:31 +0000618#endif
Joerg Sonnenbergera71a9522013-05-17 21:17:34 +0000619#if defined(__NetBSD__)
620 static const short* __classic_upper_table() _NOEXCEPT;
621 static const short* __classic_lower_table() _NOEXCEPT;
622#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000623
624protected:
625 ~ctype();
626 virtual char_type do_toupper(char_type __c) const;
627 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
628 virtual char_type do_tolower(char_type __c) const;
629 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
630 virtual char_type do_widen(char __c) const;
631 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
632 virtual char do_narrow(char_type __c, char __dfault) const;
633 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
634};
635
636// template <class CharT> class ctype_byname;
637
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000638template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000639
640template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000641class _LIBCPP_TYPE_VIS ctype_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000642 : public ctype<char>
643{
644 locale_t __l;
645
646public:
647 explicit ctype_byname(const char*, size_t = 0);
648 explicit ctype_byname(const string&, size_t = 0);
649
650protected:
651 ~ctype_byname();
652 virtual char_type do_toupper(char_type) const;
653 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
654 virtual char_type do_tolower(char_type) const;
655 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
656};
657
658template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000659class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000660 : public ctype<wchar_t>
661{
662 locale_t __l;
663
664public:
665 explicit ctype_byname(const char*, size_t = 0);
666 explicit ctype_byname(const string&, size_t = 0);
667
668protected:
669 ~ctype_byname();
670 virtual bool do_is(mask __m, char_type __c) const;
671 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
672 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
673 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
674 virtual char_type do_toupper(char_type) const;
675 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
676 virtual char_type do_tolower(char_type) const;
677 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
678 virtual char_type do_widen(char) const;
679 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
680 virtual char do_narrow(char_type, char __dfault) const;
681 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
682};
683
684template <class _CharT>
685inline _LIBCPP_INLINE_VISIBILITY
686bool
687isspace(_CharT __c, const locale& __loc)
688{
689 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
690}
691
692template <class _CharT>
693inline _LIBCPP_INLINE_VISIBILITY
694bool
695isprint(_CharT __c, const locale& __loc)
696{
697 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
698}
699
700template <class _CharT>
701inline _LIBCPP_INLINE_VISIBILITY
702bool
703iscntrl(_CharT __c, const locale& __loc)
704{
705 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
706}
707
708template <class _CharT>
709inline _LIBCPP_INLINE_VISIBILITY
710bool
711isupper(_CharT __c, const locale& __loc)
712{
713 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
714}
715
716template <class _CharT>
717inline _LIBCPP_INLINE_VISIBILITY
718bool
719islower(_CharT __c, const locale& __loc)
720{
721 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
722}
723
724template <class _CharT>
725inline _LIBCPP_INLINE_VISIBILITY
726bool
727isalpha(_CharT __c, const locale& __loc)
728{
729 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
730}
731
732template <class _CharT>
733inline _LIBCPP_INLINE_VISIBILITY
734bool
735isdigit(_CharT __c, const locale& __loc)
736{
737 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
738}
739
740template <class _CharT>
741inline _LIBCPP_INLINE_VISIBILITY
742bool
743ispunct(_CharT __c, const locale& __loc)
744{
745 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
746}
747
748template <class _CharT>
749inline _LIBCPP_INLINE_VISIBILITY
750bool
751isxdigit(_CharT __c, const locale& __loc)
752{
753 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
754}
755
756template <class _CharT>
757inline _LIBCPP_INLINE_VISIBILITY
758bool
759isalnum(_CharT __c, const locale& __loc)
760{
761 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
762}
763
764template <class _CharT>
765inline _LIBCPP_INLINE_VISIBILITY
766bool
767isgraph(_CharT __c, const locale& __loc)
768{
769 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
770}
771
772template <class _CharT>
773inline _LIBCPP_INLINE_VISIBILITY
774_CharT
775toupper(_CharT __c, const locale& __loc)
776{
777 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
778}
779
780template <class _CharT>
781inline _LIBCPP_INLINE_VISIBILITY
782_CharT
783tolower(_CharT __c, const locale& __loc)
784{
785 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
786}
787
788// codecvt_base
789
Howard Hinnant83eade62013-03-06 23:30:19 +0000790class _LIBCPP_TYPE_VIS codecvt_base
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000791{
792public:
793 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
794 enum result {ok, partial, error, noconv};
795};
796
797// template <class internT, class externT, class stateT> class codecvt;
798
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000799template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS_ONLY codecvt;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000800
801// template <> class codecvt<char, char, mbstate_t>
802
803template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000804class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000805 : public locale::facet,
806 public codecvt_base
807{
808public:
809 typedef char intern_type;
810 typedef char extern_type;
811 typedef mbstate_t state_type;
812
813 _LIBCPP_ALWAYS_INLINE
814 explicit codecvt(size_t __refs = 0)
815 : locale::facet(__refs) {}
816
817 _LIBCPP_ALWAYS_INLINE
818 result out(state_type& __st,
819 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
820 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
821 {
822 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
823 }
824
825 _LIBCPP_ALWAYS_INLINE
826 result unshift(state_type& __st,
827 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
828 {
829 return do_unshift(__st, __to, __to_end, __to_nxt);
830 }
831
832 _LIBCPP_ALWAYS_INLINE
833 result in(state_type& __st,
834 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
835 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
836 {
837 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
838 }
839
840 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000841 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000842 {
843 return do_encoding();
844 }
845
846 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000847 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000848 {
849 return do_always_noconv();
850 }
851
852 _LIBCPP_ALWAYS_INLINE
853 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
854 {
855 return do_length(__st, __frm, __end, __mx);
856 }
857
858 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000859 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000860 {
861 return do_max_length();
862 }
863
864 static locale::id id;
865
866protected:
867 _LIBCPP_ALWAYS_INLINE
868 explicit codecvt(const char*, size_t __refs = 0)
869 : locale::facet(__refs) {}
870
871 ~codecvt();
872
873 virtual result do_out(state_type& __st,
874 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
875 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
876 virtual result do_in(state_type& __st,
877 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
878 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
879 virtual result do_unshift(state_type& __st,
880 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000881 virtual int do_encoding() const _NOEXCEPT;
882 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000883 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000884 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000885};
886
887// template <> class codecvt<wchar_t, char, mbstate_t>
888
889template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000890class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000891 : public locale::facet,
892 public codecvt_base
893{
894 locale_t __l;
895public:
896 typedef wchar_t intern_type;
897 typedef char extern_type;
898 typedef mbstate_t state_type;
899
900 explicit codecvt(size_t __refs = 0);
901
902 _LIBCPP_ALWAYS_INLINE
903 result out(state_type& __st,
904 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
905 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
906 {
907 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
908 }
909
910 _LIBCPP_ALWAYS_INLINE
911 result unshift(state_type& __st,
912 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
913 {
914 return do_unshift(__st, __to, __to_end, __to_nxt);
915 }
916
917 _LIBCPP_ALWAYS_INLINE
918 result in(state_type& __st,
919 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
920 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
921 {
922 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
923 }
924
925 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000926 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000927 {
928 return do_encoding();
929 }
930
931 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000932 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000933 {
934 return do_always_noconv();
935 }
936
937 _LIBCPP_ALWAYS_INLINE
938 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
939 {
940 return do_length(__st, __frm, __end, __mx);
941 }
942
943 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000944 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000945 {
946 return do_max_length();
947 }
948
949 static locale::id id;
950
951protected:
952 explicit codecvt(const char*, size_t __refs = 0);
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 Hinnantc9834542011-05-31 15:34:58 +0000964 virtual int do_encoding() const _NOEXCEPT;
965 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000966 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000967 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000968};
969
970// template <> class codecvt<char16_t, char, mbstate_t>
971
972template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000973class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000974 : public locale::facet,
975 public codecvt_base
976{
977public:
978 typedef char16_t intern_type;
979 typedef char extern_type;
980 typedef mbstate_t state_type;
981
982 _LIBCPP_ALWAYS_INLINE
983 explicit codecvt(size_t __refs = 0)
984 : locale::facet(__refs) {}
985
986 _LIBCPP_ALWAYS_INLINE
987 result out(state_type& __st,
988 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
989 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
990 {
991 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
992 }
993
994 _LIBCPP_ALWAYS_INLINE
995 result unshift(state_type& __st,
996 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
997 {
998 return do_unshift(__st, __to, __to_end, __to_nxt);
999 }
1000
1001 _LIBCPP_ALWAYS_INLINE
1002 result in(state_type& __st,
1003 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1004 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1005 {
1006 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1007 }
1008
1009 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001010 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001011 {
1012 return do_encoding();
1013 }
1014
1015 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001016 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001017 {
1018 return do_always_noconv();
1019 }
1020
1021 _LIBCPP_ALWAYS_INLINE
1022 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1023 {
1024 return do_length(__st, __frm, __end, __mx);
1025 }
1026
1027 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001028 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001029 {
1030 return do_max_length();
1031 }
1032
1033 static locale::id id;
1034
1035protected:
1036 _LIBCPP_ALWAYS_INLINE
1037 explicit codecvt(const char*, size_t __refs = 0)
1038 : locale::facet(__refs) {}
1039
1040 ~codecvt();
1041
1042 virtual result do_out(state_type& __st,
1043 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1044 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1045 virtual result do_in(state_type& __st,
1046 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1047 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1048 virtual result do_unshift(state_type& __st,
1049 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +00001050 virtual int do_encoding() const _NOEXCEPT;
1051 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001052 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantc9834542011-05-31 15:34:58 +00001053 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001054};
1055
1056// template <> class codecvt<char32_t, char, mbstate_t>
1057
1058template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001059class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001060 : public locale::facet,
1061 public codecvt_base
1062{
1063public:
1064 typedef char32_t intern_type;
1065 typedef char extern_type;
1066 typedef mbstate_t state_type;
1067
1068 _LIBCPP_ALWAYS_INLINE
1069 explicit codecvt(size_t __refs = 0)
1070 : locale::facet(__refs) {}
1071
1072 _LIBCPP_ALWAYS_INLINE
1073 result out(state_type& __st,
1074 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1075 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1076 {
1077 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1078 }
1079
1080 _LIBCPP_ALWAYS_INLINE
1081 result unshift(state_type& __st,
1082 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1083 {
1084 return do_unshift(__st, __to, __to_end, __to_nxt);
1085 }
1086
1087 _LIBCPP_ALWAYS_INLINE
1088 result in(state_type& __st,
1089 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1090 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1091 {
1092 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1093 }
1094
1095 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001096 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001097 {
1098 return do_encoding();
1099 }
1100
1101 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001102 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001103 {
1104 return do_always_noconv();
1105 }
1106
1107 _LIBCPP_ALWAYS_INLINE
1108 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1109 {
1110 return do_length(__st, __frm, __end, __mx);
1111 }
1112
1113 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001114 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001115 {
1116 return do_max_length();
1117 }
1118
1119 static locale::id id;
1120
1121protected:
1122 _LIBCPP_ALWAYS_INLINE
1123 explicit codecvt(const char*, size_t __refs = 0)
1124 : locale::facet(__refs) {}
1125
1126 ~codecvt();
1127
1128 virtual result do_out(state_type& __st,
1129 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1130 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1131 virtual result do_in(state_type& __st,
1132 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1133 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1134 virtual result do_unshift(state_type& __st,
1135 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +00001136 virtual int do_encoding() const _NOEXCEPT;
1137 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001138 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantc9834542011-05-31 15:34:58 +00001139 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001140};
1141
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001142// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1143
1144template <class _InternT, class _ExternT, class _StateT>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001145class _LIBCPP_TYPE_VIS_ONLY codecvt_byname
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001146 : public codecvt<_InternT, _ExternT, _StateT>
1147{
1148public:
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001149 _LIBCPP_ALWAYS_INLINE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001150 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1151 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001152 _LIBCPP_ALWAYS_INLINE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001153 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1154 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1155protected:
1156 ~codecvt_byname();
1157};
1158
1159template <class _InternT, class _ExternT, class _StateT>
1160codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1161{
1162}
1163
Howard Hinnant499cea12013-08-23 17:37:05 +00001164_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
1165_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
1166_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
1167_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001168
Howard Hinnant83eade62013-03-06 23:30:19 +00001169_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001170
Howard Hinnant99968442011-11-29 18:15:50 +00001171template <size_t _Np>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001172struct __narrow_to_utf8
1173{
1174 template <class _OutputIterator, class _CharT>
1175 _OutputIterator
1176 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1177};
1178
1179template <>
1180struct __narrow_to_utf8<8>
1181{
1182 template <class _OutputIterator, class _CharT>
1183 _LIBCPP_ALWAYS_INLINE
1184 _OutputIterator
1185 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1186 {
1187 for (; __wb < __we; ++__wb, ++__s)
1188 *__s = *__wb;
1189 return __s;
1190 }
1191};
1192
1193template <>
1194struct __narrow_to_utf8<16>
1195 : public codecvt<char16_t, char, mbstate_t>
1196{
1197 _LIBCPP_ALWAYS_INLINE
1198 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1199
1200 ~__narrow_to_utf8();
1201
1202 template <class _OutputIterator, class _CharT>
1203 _LIBCPP_ALWAYS_INLINE
1204 _OutputIterator
1205 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1206 {
1207 result __r = ok;
1208 mbstate_t __mb;
1209 while (__wb < __we && __r != error)
1210 {
1211 const int __sz = 32;
1212 char __buf[__sz];
1213 char* __bn;
1214 const char16_t* __wn = (const char16_t*)__wb;
1215 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1216 __buf, __buf+__sz, __bn);
1217 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1218 __throw_runtime_error("locale not supported");
1219 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1220 *__s = *__p;
1221 __wb = (const _CharT*)__wn;
1222 }
1223 return __s;
1224 }
1225};
1226
1227template <>
1228struct __narrow_to_utf8<32>
1229 : public codecvt<char32_t, char, mbstate_t>
1230{
1231 _LIBCPP_ALWAYS_INLINE
1232 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1233
1234 ~__narrow_to_utf8();
1235
1236 template <class _OutputIterator, class _CharT>
1237 _LIBCPP_ALWAYS_INLINE
1238 _OutputIterator
1239 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1240 {
1241 result __r = ok;
1242 mbstate_t __mb;
1243 while (__wb < __we && __r != error)
1244 {
1245 const int __sz = 32;
1246 char __buf[__sz];
1247 char* __bn;
1248 const char32_t* __wn = (const char32_t*)__wb;
1249 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1250 __buf, __buf+__sz, __bn);
1251 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1252 __throw_runtime_error("locale not supported");
1253 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1254 *__s = *__p;
1255 __wb = (const _CharT*)__wn;
1256 }
1257 return __s;
1258 }
1259};
1260
Howard Hinnant99968442011-11-29 18:15:50 +00001261template <size_t _Np>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001262struct __widen_from_utf8
1263{
1264 template <class _OutputIterator>
1265 _OutputIterator
1266 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1267};
1268
1269template <>
1270struct __widen_from_utf8<8>
1271{
1272 template <class _OutputIterator>
1273 _LIBCPP_ALWAYS_INLINE
1274 _OutputIterator
1275 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1276 {
1277 for (; __nb < __ne; ++__nb, ++__s)
1278 *__s = *__nb;
1279 return __s;
1280 }
1281};
1282
1283template <>
1284struct __widen_from_utf8<16>
1285 : public codecvt<char16_t, char, mbstate_t>
1286{
1287 _LIBCPP_ALWAYS_INLINE
1288 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1289
1290 ~__widen_from_utf8();
1291
1292 template <class _OutputIterator>
1293 _LIBCPP_ALWAYS_INLINE
1294 _OutputIterator
1295 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1296 {
1297 result __r = ok;
1298 mbstate_t __mb;
1299 while (__nb < __ne && __r != error)
1300 {
1301 const int __sz = 32;
1302 char16_t __buf[__sz];
1303 char16_t* __bn;
1304 const char* __nn = __nb;
1305 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1306 __buf, __buf+__sz, __bn);
1307 if (__r == codecvt_base::error || __nn == __nb)
1308 __throw_runtime_error("locale not supported");
1309 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1310 *__s = (wchar_t)*__p;
1311 __nb = __nn;
1312 }
1313 return __s;
1314 }
1315};
1316
1317template <>
1318struct __widen_from_utf8<32>
1319 : public codecvt<char32_t, char, mbstate_t>
1320{
1321 _LIBCPP_ALWAYS_INLINE
1322 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1323
1324 ~__widen_from_utf8();
1325
1326 template <class _OutputIterator>
1327 _LIBCPP_ALWAYS_INLINE
1328 _OutputIterator
1329 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1330 {
1331 result __r = ok;
1332 mbstate_t __mb;
1333 while (__nb < __ne && __r != error)
1334 {
1335 const int __sz = 32;
1336 char32_t __buf[__sz];
1337 char32_t* __bn;
1338 const char* __nn = __nb;
1339 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1340 __buf, __buf+__sz, __bn);
1341 if (__r == codecvt_base::error || __nn == __nb)
1342 __throw_runtime_error("locale not supported");
1343 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1344 *__s = (wchar_t)*__p;
1345 __nb = __nn;
1346 }
1347 return __s;
1348 }
1349};
1350
1351// template <class charT> class numpunct
1352
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001353template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001354
1355template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001356class _LIBCPP_TYPE_VIS numpunct<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001357 : public locale::facet
1358{
1359public:
1360 typedef char char_type;
1361 typedef basic_string<char_type> string_type;
1362
1363 explicit numpunct(size_t __refs = 0);
1364
1365 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1366 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1367 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1368 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1369 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1370
1371 static locale::id id;
1372
1373protected:
1374 ~numpunct();
1375 virtual char_type do_decimal_point() const;
1376 virtual char_type do_thousands_sep() const;
1377 virtual string do_grouping() const;
1378 virtual string_type do_truename() const;
1379 virtual string_type do_falsename() const;
1380
1381 char_type __decimal_point_;
1382 char_type __thousands_sep_;
1383 string __grouping_;
1384};
1385
1386template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001387class _LIBCPP_TYPE_VIS numpunct<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001388 : public locale::facet
1389{
1390public:
1391 typedef wchar_t char_type;
1392 typedef basic_string<char_type> string_type;
1393
1394 explicit numpunct(size_t __refs = 0);
1395
1396 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1397 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1398 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1399 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1400 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1401
1402 static locale::id id;
1403
1404protected:
1405 ~numpunct();
1406 virtual char_type do_decimal_point() const;
1407 virtual char_type do_thousands_sep() const;
1408 virtual string do_grouping() const;
1409 virtual string_type do_truename() const;
1410 virtual string_type do_falsename() const;
1411
1412 char_type __decimal_point_;
1413 char_type __thousands_sep_;
1414 string __grouping_;
1415};
1416
1417// template <class charT> class numpunct_byname
1418
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001419template <class charT> class _LIBCPP_TYPE_VIS_ONLY numpunct_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001420
1421template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001422class _LIBCPP_TYPE_VIS numpunct_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001423: public numpunct<char>
1424{
1425public:
1426 typedef char char_type;
1427 typedef basic_string<char_type> string_type;
1428
1429 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1430 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1431
1432protected:
1433 ~numpunct_byname();
1434
1435private:
1436 void __init(const char*);
1437};
1438
1439template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001440class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001441: public numpunct<wchar_t>
1442{
1443public:
1444 typedef wchar_t char_type;
1445 typedef basic_string<char_type> string_type;
1446
1447 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1448 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1449
1450protected:
1451 ~numpunct_byname();
1452
1453private:
1454 void __init(const char*);
1455};
1456
1457_LIBCPP_END_NAMESPACE_STD
1458
1459#endif // _LIBCPP___LOCALE