blob: b1e07113e7d4890866c889be59da976164a692fb [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 Hinnant92a07002011-09-22 19:10:18 +000022#if _WIN32
Howard Hinnant14fa9f92011-09-29 20:33:10 +000023# include <support/win32/locale_win32.h>
David Chisnall997e4542012-02-29 13:05:08 +000024#elif (__GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__)
Howard Hinnant92a07002011-09-22 19:10:18 +000025# include <xlocale.h>
Howard Hinnant11624452011-10-11 16:00:46 +000026#endif // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD_
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000027
Howard Hinnant08e17472011-10-17 20:05:10 +000028#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000029#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000030#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000031
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34class locale;
35
Howard Hinnantc9834542011-05-31 15:34:58 +000036template <class _Facet> bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000037template <class _Facet> const _Facet& use_facet(const locale&);
38
Howard Hinnantb0be42b2010-09-21 18:58:51 +000039class _LIBCPP_VISIBLE locale
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000040{
41public:
42 // types:
43 class facet;
44 class id;
45
46 typedef int category;
47 static const category // values assigned here are for exposition only
48 none = 0,
49 collate = LC_COLLATE_MASK,
50 ctype = LC_CTYPE_MASK,
51 monetary = LC_MONETARY_MASK,
52 numeric = LC_NUMERIC_MASK,
53 time = LC_TIME_MASK,
54 messages = LC_MESSAGES_MASK,
55 all = collate | ctype | monetary | numeric | time | messages;
56
57 // construct/copy/destroy:
Howard Hinnantc9834542011-05-31 15:34:58 +000058 locale() _NOEXCEPT;
59 locale(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000060 explicit locale(const char*);
61 explicit locale(const string&);
62 locale(const locale&, const char*, category);
63 locale(const locale&, const string&, category);
Howard Hinnant2d72b1e2010-12-17 14:46:43 +000064 template <class _Facet>
65 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000066 locale(const locale&, const locale&, category);
67
Howard Hinnantc9834542011-05-31 15:34:58 +000068 ~locale();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000069
Howard Hinnantc9834542011-05-31 15:34:58 +000070 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071
72 template <class _Facet> locale combine(const locale&) const;
73
74 // locale operations:
75 string name() const;
76 bool operator==(const locale&) const;
77 bool operator!=(const locale& __y) const {return !(*this == __y);}
78 template <class _CharT, class _Traits, class _Allocator>
79 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
80 const basic_string<_CharT, _Traits, _Allocator>&) const;
81
82 // global locale objects:
83 static locale global(const locale&);
84 static const locale& classic();
85
86private:
87 class __imp;
88 __imp* __locale_;
89
90 void __install_ctor(const locale&, facet*, long);
91 static locale& __global();
92 bool has_facet(id&) const;
93 const facet* use_facet(id&) const;
94
Howard Hinnantc9834542011-05-31 15:34:58 +000095 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000096 template <class _Facet> friend const _Facet& use_facet(const locale&);
97};
98
Howard Hinnantb0be42b2010-09-21 18:58:51 +000099class _LIBCPP_VISIBLE locale::facet
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000100 : public __shared_count
101{
102protected:
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000103 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000104 explicit facet(size_t __refs = 0)
105 : __shared_count(static_cast<long>(__refs)-1) {}
106
107 virtual ~facet();
108
109// facet(const facet&) = delete; // effectively done in __shared_count
110// void operator=(const facet&) = delete;
111private:
Howard Hinnant1694d232011-05-28 14:41:13 +0000112 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000113};
114
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000115class _LIBCPP_VISIBLE locale::id
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000116{
117 once_flag __flag_;
118 int32_t __id_;
Howard Hinnant324bb032010-08-22 00:02:43 +0000119
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000120 static int32_t __next_id;
121public:
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000122 _LIBCPP_INLINE_VISIBILITY id() {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000123private:
124 void __init();
125 void operator=(const id&); // = delete;
126 id(const id&); // = delete;
127public: // only needed for tests
128 long __get();
129
130 friend class locale;
131 friend class locale::__imp;
132};
133
134template <class _Facet>
135inline _LIBCPP_INLINE_VISIBILITY
136locale::locale(const locale& __other, _Facet* __f)
137{
138 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
139}
140
141template <class _Facet>
142locale
143locale::combine(const locale& __other) const
144{
Howard Hinnantd4444702010-08-11 17:04:31 +0000145#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +0000146 if (!_VSTD::has_facet<_Facet>(__other))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000147 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnant324bb032010-08-22 00:02:43 +0000148#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +0000149 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000150}
151
152template <class _Facet>
153inline _LIBCPP_INLINE_VISIBILITY
154bool
Howard Hinnantc9834542011-05-31 15:34:58 +0000155has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000156{
157 return __l.has_facet(_Facet::id);
158}
159
160template <class _Facet>
161inline _LIBCPP_INLINE_VISIBILITY
162const _Facet&
163use_facet(const locale& __l)
164{
165 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
166}
167
168// template <class _CharT> class collate;
169
170template <class _CharT>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000171class _LIBCPP_VISIBLE collate
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000172 : public locale::facet
173{
174public:
175 typedef _CharT char_type;
176 typedef basic_string<char_type> string_type;
177
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000178 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000179 explicit collate(size_t __refs = 0)
180 : locale::facet(__refs) {}
181
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000182 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000183 int compare(const char_type* __lo1, const char_type* __hi1,
184 const char_type* __lo2, const char_type* __hi2) const
185 {
186 return do_compare(__lo1, __hi1, __lo2, __hi2);
187 }
188
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000190 string_type transform(const char_type* __lo, const char_type* __hi) const
191 {
192 return do_transform(__lo, __hi);
193 }
194
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000195 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000196 long hash(const char_type* __lo, const char_type* __hi) const
197 {
198 return do_hash(__lo, __hi);
199 }
200
201 static locale::id id;
202
203protected:
204 ~collate();
205 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
206 const char_type* __lo2, const char_type* __hi2) const;
207 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
208 {return string_type(__lo, __hi);}
209 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
210};
211
212template <class _CharT> locale::id collate<_CharT>::id;
213
214template <class _CharT>
215collate<_CharT>::~collate()
216{
217}
218
219template <class _CharT>
220int
221collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
222 const char_type* __lo2, const char_type* __hi2) const
223{
224 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
225 {
226 if (__lo1 == __hi1 || *__lo1 < *__lo2)
227 return -1;
228 if (*__lo2 < *__lo1)
229 return 1;
230 }
231 return __lo1 != __hi1;
232}
233
234template <class _CharT>
235long
Howard Hinnant11624452011-10-11 16:00:46 +0000236collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000237{
Howard Hinnant11624452011-10-11 16:00:46 +0000238 size_t __h = 0;
239 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
240 const size_t __mask = size_t(0xF) << (__sr + 4);
241 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000242 {
Howard Hinnantec3773c2011-12-01 20:21:04 +0000243 __h = (__h << 4) + static_cast<size_t>(*__p);
Howard Hinnant11624452011-10-11 16:00:46 +0000244 size_t __g = __h & __mask;
245 __h ^= __g | (__g >> __sr);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000246 }
Howard Hinnant11624452011-10-11 16:00:46 +0000247 return static_cast<long>(__h);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000248}
249
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000250extern template class _LIBCPP_VISIBLE collate<char>;
251extern template class _LIBCPP_VISIBLE collate<wchar_t>;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000252
253// template <class CharT> class collate_byname;
254
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000255template <class _CharT> class _LIBCPP_VISIBLE collate_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000256
257template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000258class _LIBCPP_VISIBLE collate_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000259 : public collate<char>
260{
261 locale_t __l;
262public:
263 typedef char char_type;
264 typedef basic_string<char_type> string_type;
265
266 explicit collate_byname(const char* __n, size_t __refs = 0);
267 explicit collate_byname(const string& __n, size_t __refs = 0);
268
269protected:
270 ~collate_byname();
271 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
272 const char_type* __lo2, const char_type* __hi2) const;
273 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
274};
275
276template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000277class _LIBCPP_VISIBLE collate_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000278 : public collate<wchar_t>
279{
280 locale_t __l;
281public:
282 typedef wchar_t char_type;
283 typedef basic_string<char_type> string_type;
284
285 explicit collate_byname(const char* __n, size_t __refs = 0);
286 explicit collate_byname(const string& __n, size_t __refs = 0);
287
288protected:
289 ~collate_byname();
290
291 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
292 const char_type* __lo2, const char_type* __hi2) const;
293 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
294};
295
296template <class _CharT, class _Traits, class _Allocator>
297bool
298locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
299 const basic_string<_CharT, _Traits, _Allocator>& __y) const
300{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000301 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000302 __x.data(), __x.data() + __x.size(),
303 __y.data(), __y.data() + __y.size()) < 0;
304}
305
306// template <class charT> class ctype
307
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000308class _LIBCPP_VISIBLE ctype_base
309{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000310public:
David Chisnallc512df12011-09-21 08:39:44 +0000311#if __GLIBC__
Sean Hunt62a6ac32011-07-09 00:56:23 +0000312 typedef unsigned short mask;
Howard Hinnantadff4892010-05-24 17:49:41 +0000313 static const mask space = _ISspace;
314 static const mask print = _ISprint;
315 static const mask cntrl = _IScntrl;
316 static const mask upper = _ISupper;
317 static const mask lower = _ISlower;
318 static const mask alpha = _ISalpha;
319 static const mask digit = _ISdigit;
320 static const mask punct = _ISpunct;
321 static const mask xdigit = _ISxdigit;
322 static const mask blank = _ISblank;
Howard Hinnant92a07002011-09-22 19:10:18 +0000323#elif _WIN32
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000324 typedef unsigned short mask;
Howard Hinnant92a07002011-09-22 19:10:18 +0000325 static const mask space = _SPACE;
326 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
327 static const mask cntrl = _CONTROL;
328 static const mask upper = _UPPER;
329 static const mask lower = _LOWER;
330 static const mask alpha = _ALPHA;
331 static const mask digit = _DIGIT;
332 static const mask punct = _PUNCT;
333 static const mask xdigit = _HEX;
334 static const mask blank = _BLANK;
Howard Hinnant11624452011-10-11 16:00:46 +0000335#elif (__APPLE__ || __FreeBSD__)
David Chisnallc512df12011-09-21 08:39:44 +0000336#if __APPLE__
337 typedef __uint32_t mask;
338#elif __FreeBSD__
339 typedef unsigned long mask;
340#endif
341 static const mask space = _CTYPE_S;
342 static const mask print = _CTYPE_R;
343 static const mask cntrl = _CTYPE_C;
344 static const mask upper = _CTYPE_U;
345 static const mask lower = _CTYPE_L;
346 static const mask alpha = _CTYPE_A;
347 static const mask digit = _CTYPE_D;
348 static const mask punct = _CTYPE_P;
349 static const mask xdigit = _CTYPE_X;
350 static const mask blank = _CTYPE_B;
David Chisnall997e4542012-02-29 13:05:08 +0000351#elif __sun__
352 typedef unsigned int mask;
353 static const mask space = _ISSPACE;
354 static const mask print = _ISPRINT;
355 static const mask cntrl = _ISCNTRL;
356 static const mask upper = _ISUPPER;
357 static const mask lower = _ISLOWER;
358 static const mask alpha = _ISALPHA;
359 static const mask digit = _ISDIGIT;
360 static const mask punct = _ISPUNCT;
361 static const mask xdigit = _ISXDIGIT;
362 static const mask blank = _ISBLANK;
363#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __sun__
Howard Hinnant11624452011-10-11 16:00:46 +0000364 typedef unsigned long mask;
365 static const mask space = 1<<0;
366 static const mask print = 1<<1;
367 static const mask cntrl = 1<<2;
368 static const mask upper = 1<<3;
369 static const mask lower = 1<<4;
370 static const mask alpha = 1<<5;
371 static const mask digit = 1<<6;
372 static const mask punct = 1<<7;
373 static const mask xdigit = 1<<8;
374 static const mask blank = 1<<9;
375#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000376 static const mask alnum = alpha | digit;
377 static const mask graph = alnum | punct;
378
379 _LIBCPP_ALWAYS_INLINE ctype_base() {}
380};
381
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000382template <class _CharT> class _LIBCPP_VISIBLE ctype;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000383
384template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000385class _LIBCPP_VISIBLE ctype<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000386 : public locale::facet,
387 public ctype_base
388{
389public:
390 typedef wchar_t char_type;
Howard Hinnant324bb032010-08-22 00:02:43 +0000391
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000392 _LIBCPP_ALWAYS_INLINE
393 explicit ctype(size_t __refs = 0)
394 : locale::facet(__refs) {}
395
396 _LIBCPP_ALWAYS_INLINE
397 bool is(mask __m, char_type __c) const
398 {
399 return do_is(__m, __c);
400 }
401
402 _LIBCPP_ALWAYS_INLINE
403 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
404 {
405 return do_is(__low, __high, __vec);
406 }
407
408 _LIBCPP_ALWAYS_INLINE
409 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
410 {
411 return do_scan_is(__m, __low, __high);
412 }
413
414 _LIBCPP_ALWAYS_INLINE
415 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
416 {
417 return do_scan_not(__m, __low, __high);
418 }
419
420 _LIBCPP_ALWAYS_INLINE
421 char_type toupper(char_type __c) const
422 {
423 return do_toupper(__c);
424 }
425
426 _LIBCPP_ALWAYS_INLINE
427 const char_type* toupper(char_type* __low, const char_type* __high) const
428 {
429 return do_toupper(__low, __high);
430 }
431
432 _LIBCPP_ALWAYS_INLINE
433 char_type tolower(char_type __c) const
434 {
435 return do_tolower(__c);
436 }
437
438 _LIBCPP_ALWAYS_INLINE
439 const char_type* tolower(char_type* __low, const char_type* __high) const
440 {
441 return do_tolower(__low, __high);
442 }
443
444 _LIBCPP_ALWAYS_INLINE
445 char_type widen(char __c) const
446 {
447 return do_widen(__c);
448 }
449
450 _LIBCPP_ALWAYS_INLINE
451 const char* widen(const char* __low, const char* __high, char_type* __to) const
452 {
453 return do_widen(__low, __high, __to);
454 }
455
456 _LIBCPP_ALWAYS_INLINE
457 char narrow(char_type __c, char __dfault) const
458 {
459 return do_narrow(__c, __dfault);
460 }
461
462 _LIBCPP_ALWAYS_INLINE
463 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
464 {
465 return do_narrow(__low, __high, __dfault, __to);
466 }
467
468 static locale::id id;
469
470protected:
471 ~ctype();
472 virtual bool do_is(mask __m, char_type __c) const;
473 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
474 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
475 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
476 virtual char_type do_toupper(char_type) const;
477 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
478 virtual char_type do_tolower(char_type) const;
479 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
480 virtual char_type do_widen(char) const;
481 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
482 virtual char do_narrow(char_type, char __dfault) const;
483 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
484};
485
486template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000487class _LIBCPP_VISIBLE ctype<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000488 : public locale::facet, public ctype_base
489{
490 const mask* __tab_;
491 bool __del_;
492public:
493 typedef char char_type;
494
495 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
496
497 _LIBCPP_ALWAYS_INLINE
498 bool is(mask __m, char_type __c) const
499 {
Howard Hinnantec3773c2011-12-01 20:21:04 +0000500 return isascii(__c) ? __tab_[static_cast<int>(__c)] & __m : false;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000501 }
502
503 _LIBCPP_ALWAYS_INLINE
504 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
505 {
506 for (; __low != __high; ++__low, ++__vec)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000507 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000508 return __low;
509 }
510
511 _LIBCPP_ALWAYS_INLINE
512 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
513 {
514 for (; __low != __high; ++__low)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000515 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000516 break;
517 return __low;
518 }
519
520 _LIBCPP_ALWAYS_INLINE
521 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
522 {
523 for (; __low != __high; ++__low)
Howard Hinnantec3773c2011-12-01 20:21:04 +0000524 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000525 break;
526 return __low;
527 }
528
529 _LIBCPP_ALWAYS_INLINE
530 char_type toupper(char_type __c) const
531 {
532 return do_toupper(__c);
533 }
534
535 _LIBCPP_ALWAYS_INLINE
536 const char_type* toupper(char_type* __low, const char_type* __high) const
537 {
538 return do_toupper(__low, __high);
539 }
540
541 _LIBCPP_ALWAYS_INLINE
542 char_type tolower(char_type __c) const
543 {
544 return do_tolower(__c);
545 }
546
547 _LIBCPP_ALWAYS_INLINE
548 const char_type* tolower(char_type* __low, const char_type* __high) const
549 {
550 return do_tolower(__low, __high);
551 }
552
553 _LIBCPP_ALWAYS_INLINE
554 char_type widen(char __c) const
555 {
556 return do_widen(__c);
557 }
558
559 _LIBCPP_ALWAYS_INLINE
560 const char* widen(const char* __low, const char* __high, char_type* __to) const
561 {
562 return do_widen(__low, __high, __to);
563 }
564
565 _LIBCPP_ALWAYS_INLINE
566 char narrow(char_type __c, char __dfault) const
567 {
568 return do_narrow(__c, __dfault);
569 }
570
571 _LIBCPP_ALWAYS_INLINE
572 const char* 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
Howard Hinnantadff4892010-05-24 17:49:41 +0000579#ifdef _CACHED_RUNES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000580 static const size_t table_size = _CACHED_RUNES;
Howard Hinnantadff4892010-05-24 17:49:41 +0000581#else
582 static const size_t table_size = 256; // FIXME: Don't hardcode this.
583#endif
Howard Hinnantc9834542011-05-31 15:34:58 +0000584 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
585 static const mask* classic_table() _NOEXCEPT;
Howard Hinnant3c466fc2011-09-29 13:33:15 +0000586#if defined(__GLIBC__)
Sean Hunt62a6ac32011-07-09 00:56:23 +0000587 static const int* __classic_upper_table() _NOEXCEPT;
588 static const int* __classic_lower_table() _NOEXCEPT;
Sean Hunte59f7242011-07-09 01:09:31 +0000589#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000590
591protected:
592 ~ctype();
593 virtual char_type do_toupper(char_type __c) const;
594 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
595 virtual char_type do_tolower(char_type __c) const;
596 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
597 virtual char_type do_widen(char __c) const;
598 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
599 virtual char do_narrow(char_type __c, char __dfault) const;
600 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
601};
602
603// template <class CharT> class ctype_byname;
604
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000605template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000606
607template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000608class _LIBCPP_VISIBLE ctype_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000609 : public ctype<char>
610{
611 locale_t __l;
612
613public:
614 explicit ctype_byname(const char*, size_t = 0);
615 explicit ctype_byname(const string&, size_t = 0);
616
617protected:
618 ~ctype_byname();
619 virtual char_type do_toupper(char_type) const;
620 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
621 virtual char_type do_tolower(char_type) const;
622 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
623};
624
625template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000626class _LIBCPP_VISIBLE ctype_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000627 : public ctype<wchar_t>
628{
629 locale_t __l;
630
631public:
632 explicit ctype_byname(const char*, size_t = 0);
633 explicit ctype_byname(const string&, size_t = 0);
634
635protected:
636 ~ctype_byname();
637 virtual bool do_is(mask __m, char_type __c) const;
638 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
639 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
640 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
641 virtual char_type do_toupper(char_type) const;
642 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
643 virtual char_type do_tolower(char_type) const;
644 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
645 virtual char_type do_widen(char) const;
646 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
647 virtual char do_narrow(char_type, char __dfault) const;
648 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
649};
650
651template <class _CharT>
652inline _LIBCPP_INLINE_VISIBILITY
653bool
654isspace(_CharT __c, const locale& __loc)
655{
656 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
657}
658
659template <class _CharT>
660inline _LIBCPP_INLINE_VISIBILITY
661bool
662isprint(_CharT __c, const locale& __loc)
663{
664 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
665}
666
667template <class _CharT>
668inline _LIBCPP_INLINE_VISIBILITY
669bool
670iscntrl(_CharT __c, const locale& __loc)
671{
672 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
673}
674
675template <class _CharT>
676inline _LIBCPP_INLINE_VISIBILITY
677bool
678isupper(_CharT __c, const locale& __loc)
679{
680 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
681}
682
683template <class _CharT>
684inline _LIBCPP_INLINE_VISIBILITY
685bool
686islower(_CharT __c, const locale& __loc)
687{
688 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
689}
690
691template <class _CharT>
692inline _LIBCPP_INLINE_VISIBILITY
693bool
694isalpha(_CharT __c, const locale& __loc)
695{
696 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
697}
698
699template <class _CharT>
700inline _LIBCPP_INLINE_VISIBILITY
701bool
702isdigit(_CharT __c, const locale& __loc)
703{
704 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
705}
706
707template <class _CharT>
708inline _LIBCPP_INLINE_VISIBILITY
709bool
710ispunct(_CharT __c, const locale& __loc)
711{
712 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
713}
714
715template <class _CharT>
716inline _LIBCPP_INLINE_VISIBILITY
717bool
718isxdigit(_CharT __c, const locale& __loc)
719{
720 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
721}
722
723template <class _CharT>
724inline _LIBCPP_INLINE_VISIBILITY
725bool
726isalnum(_CharT __c, const locale& __loc)
727{
728 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
729}
730
731template <class _CharT>
732inline _LIBCPP_INLINE_VISIBILITY
733bool
734isgraph(_CharT __c, const locale& __loc)
735{
736 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
737}
738
739template <class _CharT>
740inline _LIBCPP_INLINE_VISIBILITY
741_CharT
742toupper(_CharT __c, const locale& __loc)
743{
744 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
745}
746
747template <class _CharT>
748inline _LIBCPP_INLINE_VISIBILITY
749_CharT
750tolower(_CharT __c, const locale& __loc)
751{
752 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
753}
754
755// codecvt_base
756
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000757class _LIBCPP_VISIBLE codecvt_base
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000758{
759public:
760 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
761 enum result {ok, partial, error, noconv};
762};
763
764// template <class internT, class externT, class stateT> class codecvt;
765
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000766template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000767
768// template <> class codecvt<char, char, mbstate_t>
769
770template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000771class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000772 : public locale::facet,
773 public codecvt_base
774{
775public:
776 typedef char intern_type;
777 typedef char extern_type;
778 typedef mbstate_t state_type;
779
780 _LIBCPP_ALWAYS_INLINE
781 explicit codecvt(size_t __refs = 0)
782 : locale::facet(__refs) {}
783
784 _LIBCPP_ALWAYS_INLINE
785 result out(state_type& __st,
786 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
787 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
788 {
789 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
790 }
791
792 _LIBCPP_ALWAYS_INLINE
793 result unshift(state_type& __st,
794 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
795 {
796 return do_unshift(__st, __to, __to_end, __to_nxt);
797 }
798
799 _LIBCPP_ALWAYS_INLINE
800 result in(state_type& __st,
801 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
802 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
803 {
804 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
805 }
806
807 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000808 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000809 {
810 return do_encoding();
811 }
812
813 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000814 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000815 {
816 return do_always_noconv();
817 }
818
819 _LIBCPP_ALWAYS_INLINE
820 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
821 {
822 return do_length(__st, __frm, __end, __mx);
823 }
824
825 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000826 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000827 {
828 return do_max_length();
829 }
830
831 static locale::id id;
832
833protected:
834 _LIBCPP_ALWAYS_INLINE
835 explicit codecvt(const char*, size_t __refs = 0)
836 : locale::facet(__refs) {}
837
838 ~codecvt();
839
840 virtual result do_out(state_type& __st,
841 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
842 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
843 virtual result do_in(state_type& __st,
844 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
845 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
846 virtual result do_unshift(state_type& __st,
847 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000848 virtual int do_encoding() const _NOEXCEPT;
849 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000850 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 +0000851 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000852};
853
854// template <> class codecvt<wchar_t, char, mbstate_t>
855
856template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000857class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000858 : public locale::facet,
859 public codecvt_base
860{
861 locale_t __l;
862public:
863 typedef wchar_t intern_type;
864 typedef char extern_type;
865 typedef mbstate_t state_type;
866
867 explicit codecvt(size_t __refs = 0);
868
869 _LIBCPP_ALWAYS_INLINE
870 result out(state_type& __st,
871 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
872 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
873 {
874 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
875 }
876
877 _LIBCPP_ALWAYS_INLINE
878 result unshift(state_type& __st,
879 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
880 {
881 return do_unshift(__st, __to, __to_end, __to_nxt);
882 }
883
884 _LIBCPP_ALWAYS_INLINE
885 result in(state_type& __st,
886 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
887 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
888 {
889 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
890 }
891
892 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000893 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000894 {
895 return do_encoding();
896 }
897
898 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000899 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000900 {
901 return do_always_noconv();
902 }
903
904 _LIBCPP_ALWAYS_INLINE
905 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
906 {
907 return do_length(__st, __frm, __end, __mx);
908 }
909
910 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000911 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000912 {
913 return do_max_length();
914 }
915
916 static locale::id id;
917
918protected:
919 explicit codecvt(const char*, size_t __refs = 0);
920
921 ~codecvt();
922
923 virtual result do_out(state_type& __st,
924 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
925 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
926 virtual result do_in(state_type& __st,
927 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
928 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
929 virtual result do_unshift(state_type& __st,
930 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000931 virtual int do_encoding() const _NOEXCEPT;
932 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000933 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 +0000934 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000935};
936
937// template <> class codecvt<char16_t, char, mbstate_t>
938
939template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000940class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000941 : public locale::facet,
942 public codecvt_base
943{
944public:
945 typedef char16_t intern_type;
946 typedef char extern_type;
947 typedef mbstate_t state_type;
948
949 _LIBCPP_ALWAYS_INLINE
950 explicit codecvt(size_t __refs = 0)
951 : locale::facet(__refs) {}
952
953 _LIBCPP_ALWAYS_INLINE
954 result out(state_type& __st,
955 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
956 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
957 {
958 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
959 }
960
961 _LIBCPP_ALWAYS_INLINE
962 result unshift(state_type& __st,
963 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
964 {
965 return do_unshift(__st, __to, __to_end, __to_nxt);
966 }
967
968 _LIBCPP_ALWAYS_INLINE
969 result in(state_type& __st,
970 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
971 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
972 {
973 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
974 }
975
976 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000977 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000978 {
979 return do_encoding();
980 }
981
982 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000983 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000984 {
985 return do_always_noconv();
986 }
987
988 _LIBCPP_ALWAYS_INLINE
989 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
990 {
991 return do_length(__st, __frm, __end, __mx);
992 }
993
994 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000995 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000996 {
997 return do_max_length();
998 }
999
1000 static locale::id id;
1001
1002protected:
1003 _LIBCPP_ALWAYS_INLINE
1004 explicit codecvt(const char*, size_t __refs = 0)
1005 : locale::facet(__refs) {}
1006
1007 ~codecvt();
1008
1009 virtual result do_out(state_type& __st,
1010 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1011 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1012 virtual result do_in(state_type& __st,
1013 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1014 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1015 virtual result do_unshift(state_type& __st,
1016 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +00001017 virtual int do_encoding() const _NOEXCEPT;
1018 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001019 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 +00001020 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001021};
1022
1023// template <> class codecvt<char32_t, char, mbstate_t>
1024
1025template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001026class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001027 : public locale::facet,
1028 public codecvt_base
1029{
1030public:
1031 typedef char32_t intern_type;
1032 typedef char extern_type;
1033 typedef mbstate_t state_type;
1034
1035 _LIBCPP_ALWAYS_INLINE
1036 explicit codecvt(size_t __refs = 0)
1037 : locale::facet(__refs) {}
1038
1039 _LIBCPP_ALWAYS_INLINE
1040 result out(state_type& __st,
1041 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1042 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1043 {
1044 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1045 }
1046
1047 _LIBCPP_ALWAYS_INLINE
1048 result unshift(state_type& __st,
1049 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1050 {
1051 return do_unshift(__st, __to, __to_end, __to_nxt);
1052 }
1053
1054 _LIBCPP_ALWAYS_INLINE
1055 result in(state_type& __st,
1056 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1057 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1058 {
1059 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1060 }
1061
1062 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001063 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001064 {
1065 return do_encoding();
1066 }
1067
1068 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001069 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001070 {
1071 return do_always_noconv();
1072 }
1073
1074 _LIBCPP_ALWAYS_INLINE
1075 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1076 {
1077 return do_length(__st, __frm, __end, __mx);
1078 }
1079
1080 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001081 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001082 {
1083 return do_max_length();
1084 }
1085
1086 static locale::id id;
1087
1088protected:
1089 _LIBCPP_ALWAYS_INLINE
1090 explicit codecvt(const char*, size_t __refs = 0)
1091 : locale::facet(__refs) {}
1092
1093 ~codecvt();
1094
1095 virtual result do_out(state_type& __st,
1096 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1097 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1098 virtual result do_in(state_type& __st,
1099 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1100 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1101 virtual result do_unshift(state_type& __st,
1102 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +00001103 virtual int do_encoding() const _NOEXCEPT;
1104 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001105 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 +00001106 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001107};
1108
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001109// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1110
1111template <class _InternT, class _ExternT, class _StateT>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001112class _LIBCPP_VISIBLE codecvt_byname
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001113 : public codecvt<_InternT, _ExternT, _StateT>
1114{
1115public:
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001116 _LIBCPP_ALWAYS_INLINE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001117 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1118 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001119 _LIBCPP_ALWAYS_INLINE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001120 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1121 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1122protected:
1123 ~codecvt_byname();
1124};
1125
1126template <class _InternT, class _ExternT, class _StateT>
1127codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1128{
1129}
1130
1131extern template class codecvt_byname<char, char, mbstate_t>;
1132extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1133extern template class codecvt_byname<char16_t, char, mbstate_t>;
1134extern template class codecvt_byname<char32_t, char, mbstate_t>;
1135
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001136_LIBCPP_VISIBLE void __throw_runtime_error(const char*);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001137
Howard Hinnant99968442011-11-29 18:15:50 +00001138template <size_t _Np>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001139struct __narrow_to_utf8
1140{
1141 template <class _OutputIterator, class _CharT>
1142 _OutputIterator
1143 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1144};
1145
1146template <>
1147struct __narrow_to_utf8<8>
1148{
1149 template <class _OutputIterator, class _CharT>
1150 _LIBCPP_ALWAYS_INLINE
1151 _OutputIterator
1152 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1153 {
1154 for (; __wb < __we; ++__wb, ++__s)
1155 *__s = *__wb;
1156 return __s;
1157 }
1158};
1159
1160template <>
1161struct __narrow_to_utf8<16>
1162 : public codecvt<char16_t, char, mbstate_t>
1163{
1164 _LIBCPP_ALWAYS_INLINE
1165 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1166
1167 ~__narrow_to_utf8();
1168
1169 template <class _OutputIterator, class _CharT>
1170 _LIBCPP_ALWAYS_INLINE
1171 _OutputIterator
1172 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1173 {
1174 result __r = ok;
1175 mbstate_t __mb;
1176 while (__wb < __we && __r != error)
1177 {
1178 const int __sz = 32;
1179 char __buf[__sz];
1180 char* __bn;
1181 const char16_t* __wn = (const char16_t*)__wb;
1182 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1183 __buf, __buf+__sz, __bn);
1184 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1185 __throw_runtime_error("locale not supported");
1186 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1187 *__s = *__p;
1188 __wb = (const _CharT*)__wn;
1189 }
1190 return __s;
1191 }
1192};
1193
1194template <>
1195struct __narrow_to_utf8<32>
1196 : public codecvt<char32_t, char, mbstate_t>
1197{
1198 _LIBCPP_ALWAYS_INLINE
1199 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1200
1201 ~__narrow_to_utf8();
1202
1203 template <class _OutputIterator, class _CharT>
1204 _LIBCPP_ALWAYS_INLINE
1205 _OutputIterator
1206 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1207 {
1208 result __r = ok;
1209 mbstate_t __mb;
1210 while (__wb < __we && __r != error)
1211 {
1212 const int __sz = 32;
1213 char __buf[__sz];
1214 char* __bn;
1215 const char32_t* __wn = (const char32_t*)__wb;
1216 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1217 __buf, __buf+__sz, __bn);
1218 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1219 __throw_runtime_error("locale not supported");
1220 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1221 *__s = *__p;
1222 __wb = (const _CharT*)__wn;
1223 }
1224 return __s;
1225 }
1226};
1227
Howard Hinnant99968442011-11-29 18:15:50 +00001228template <size_t _Np>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001229struct __widen_from_utf8
1230{
1231 template <class _OutputIterator>
1232 _OutputIterator
1233 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1234};
1235
1236template <>
1237struct __widen_from_utf8<8>
1238{
1239 template <class _OutputIterator>
1240 _LIBCPP_ALWAYS_INLINE
1241 _OutputIterator
1242 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1243 {
1244 for (; __nb < __ne; ++__nb, ++__s)
1245 *__s = *__nb;
1246 return __s;
1247 }
1248};
1249
1250template <>
1251struct __widen_from_utf8<16>
1252 : public codecvt<char16_t, char, mbstate_t>
1253{
1254 _LIBCPP_ALWAYS_INLINE
1255 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1256
1257 ~__widen_from_utf8();
1258
1259 template <class _OutputIterator>
1260 _LIBCPP_ALWAYS_INLINE
1261 _OutputIterator
1262 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1263 {
1264 result __r = ok;
1265 mbstate_t __mb;
1266 while (__nb < __ne && __r != error)
1267 {
1268 const int __sz = 32;
1269 char16_t __buf[__sz];
1270 char16_t* __bn;
1271 const char* __nn = __nb;
1272 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1273 __buf, __buf+__sz, __bn);
1274 if (__r == codecvt_base::error || __nn == __nb)
1275 __throw_runtime_error("locale not supported");
1276 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1277 *__s = (wchar_t)*__p;
1278 __nb = __nn;
1279 }
1280 return __s;
1281 }
1282};
1283
1284template <>
1285struct __widen_from_utf8<32>
1286 : public codecvt<char32_t, char, mbstate_t>
1287{
1288 _LIBCPP_ALWAYS_INLINE
1289 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1290
1291 ~__widen_from_utf8();
1292
1293 template <class _OutputIterator>
1294 _LIBCPP_ALWAYS_INLINE
1295 _OutputIterator
1296 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1297 {
1298 result __r = ok;
1299 mbstate_t __mb;
1300 while (__nb < __ne && __r != error)
1301 {
1302 const int __sz = 32;
1303 char32_t __buf[__sz];
1304 char32_t* __bn;
1305 const char* __nn = __nb;
1306 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1307 __buf, __buf+__sz, __bn);
1308 if (__r == codecvt_base::error || __nn == __nb)
1309 __throw_runtime_error("locale not supported");
1310 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1311 *__s = (wchar_t)*__p;
1312 __nb = __nn;
1313 }
1314 return __s;
1315 }
1316};
1317
1318// template <class charT> class numpunct
1319
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001320template <class _CharT> class _LIBCPP_VISIBLE numpunct;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001321
1322template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001323class _LIBCPP_VISIBLE numpunct<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001324 : public locale::facet
1325{
1326public:
1327 typedef char char_type;
1328 typedef basic_string<char_type> string_type;
1329
1330 explicit numpunct(size_t __refs = 0);
1331
1332 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1333 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1334 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1335 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1336 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1337
1338 static locale::id id;
1339
1340protected:
1341 ~numpunct();
1342 virtual char_type do_decimal_point() const;
1343 virtual char_type do_thousands_sep() const;
1344 virtual string do_grouping() const;
1345 virtual string_type do_truename() const;
1346 virtual string_type do_falsename() const;
1347
1348 char_type __decimal_point_;
1349 char_type __thousands_sep_;
1350 string __grouping_;
1351};
1352
1353template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001354class _LIBCPP_VISIBLE numpunct<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001355 : public locale::facet
1356{
1357public:
1358 typedef wchar_t char_type;
1359 typedef basic_string<char_type> string_type;
1360
1361 explicit numpunct(size_t __refs = 0);
1362
1363 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1364 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1365 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1366 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1367 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1368
1369 static locale::id id;
1370
1371protected:
1372 ~numpunct();
1373 virtual char_type do_decimal_point() const;
1374 virtual char_type do_thousands_sep() const;
1375 virtual string do_grouping() const;
1376 virtual string_type do_truename() const;
1377 virtual string_type do_falsename() const;
1378
1379 char_type __decimal_point_;
1380 char_type __thousands_sep_;
1381 string __grouping_;
1382};
1383
1384// template <class charT> class numpunct_byname
1385
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001386template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001387
1388template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001389class _LIBCPP_VISIBLE numpunct_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001390: public numpunct<char>
1391{
1392public:
1393 typedef char char_type;
1394 typedef basic_string<char_type> string_type;
1395
1396 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1397 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1398
1399protected:
1400 ~numpunct_byname();
1401
1402private:
1403 void __init(const char*);
1404};
1405
1406template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001407class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001408: public numpunct<wchar_t>
1409{
1410public:
1411 typedef wchar_t char_type;
1412 typedef basic_string<char_type> string_type;
1413
1414 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1415 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1416
1417protected:
1418 ~numpunct_byname();
1419
1420private:
1421 void __init(const char*);
1422};
1423
1424_LIBCPP_END_NAMESPACE_STD
1425
1426#endif // _LIBCPP___LOCALE