Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / c++ / __locale

History | View | Annotate | Download (44.5 KB)

1
// -*- C++ -*-
2
//===----------------------------------------------------------------------===//
3
//
4
//                     The LLVM Compiler Infrastructure
5
//
6
// This file is dual licensed under the MIT and the University of Illinois Open
7
// Source Licenses. See LICENSE.TXT for details.
8
//
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>
21
#include <locale.h>
22
#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
23
# include <support/win32/locale_win32.h>
24
#elif defined(_AIX)
25
# include <support/ibm/xlocale.h>
26
#elif defined(__ANDROID__)
27
// 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(__sun__)
33
# include <xlocale.h>
34
# include <support/solaris/xlocale.h>
35
#elif defined(_NEWLIB_VERSION)
36
# include <support/newlib/xlocale.h>
37
#elif (defined(__GLIBC__) || defined(__APPLE__)      || defined(__FreeBSD__) \
38
    || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
39
# include <xlocale.h>
40
#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
41

    
42
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
43
#pragma GCC system_header
44
#endif
45

    
46
_LIBCPP_BEGIN_NAMESPACE_STD
47

    
48
class _LIBCPP_TYPE_VIS locale;
49

    
50
template <class _Facet>
51
_LIBCPP_INLINE_VISIBILITY
52
bool
53
has_facet(const locale&) _NOEXCEPT;
54

    
55
template <class _Facet>
56
_LIBCPP_INLINE_VISIBILITY
57
const _Facet&
58
use_facet(const locale&);
59

    
60
class _LIBCPP_TYPE_VIS locale
61
{
62
public:
63
    // types:
64
    class _LIBCPP_TYPE_VIS facet;
65
    class _LIBCPP_TYPE_VIS id;
66

    
67
    typedef int category;
68
    static const category // values assigned here are for exposition only
69
        none     = 0,
70
        collate  = LC_COLLATE_MASK,
71
        ctype    = LC_CTYPE_MASK,
72
        monetary = LC_MONETARY_MASK,
73
        numeric  = LC_NUMERIC_MASK,
74
        time     = LC_TIME_MASK,
75
        messages = LC_MESSAGES_MASK,
76
        all = collate | ctype | monetary | numeric | time | messages;
77

    
78
    // construct/copy/destroy:
79
    locale()  _NOEXCEPT;
80
    locale(const locale&)  _NOEXCEPT;
81
    explicit locale(const char*);
82
    explicit locale(const string&);
83
    locale(const locale&, const char*, category);
84
    locale(const locale&, const string&, category);
85
    template <class _Facet>
86
        _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
87
    locale(const locale&, const locale&, category);
88

    
89
    ~locale();
90

    
91
    const locale& operator=(const locale&)  _NOEXCEPT;
92

    
93
    template <class _Facet> locale combine(const locale&) const;
94

    
95
    // locale operations:
96
    string name() const;
97
    bool operator==(const locale&) const;
98
    bool operator!=(const locale& __y) const {return !(*this == __y);}
99
    template <class _CharT, class _Traits, class _Allocator>
100
      bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
101
                      const basic_string<_CharT, _Traits, _Allocator>&) const;
102

    
103
    // global locale objects:
104
    static locale global(const locale&);
105
    static const locale& classic();
106

    
107
private:
108
    class __imp;
109
    __imp* __locale_;
110

    
111
    void __install_ctor(const locale&, facet*, long);
112
    static locale& __global();
113
    bool has_facet(id&) const;
114
    const facet* use_facet(id&) const;
115

    
116
    template <class _Facet> friend bool has_facet(const locale&)  _NOEXCEPT;
117
    template <class _Facet> friend const _Facet& use_facet(const locale&);
118
};
119

    
120
class _LIBCPP_TYPE_VIS locale::facet
121
    : public __shared_count
122
{
123
protected:
124
    _LIBCPP_INLINE_VISIBILITY
125
    explicit facet(size_t __refs = 0)
126
        : __shared_count(static_cast<long>(__refs)-1) {}
127

    
128
    virtual ~facet();
129

    
130
//    facet(const facet&) = delete;     // effectively done in __shared_count
131
//    void operator=(const facet&) = delete;
132
private:
133
    virtual void __on_zero_shared() _NOEXCEPT;
134
};
135

    
136
class _LIBCPP_TYPE_VIS locale::id
137
{
138
    once_flag      __flag_;
139
    int32_t        __id_;
140

    
141
    static int32_t __next_id;
142
public:
143
    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
144
private:
145
    void __init();
146
    void operator=(const id&); // = delete;
147
    id(const id&); // = delete;
148
public:  // only needed for tests
149
    long __get();
150

    
151
    friend class locale;
152
    friend class locale::__imp;
153
};
154

    
155
template <class _Facet>
156
inline _LIBCPP_INLINE_VISIBILITY
157
locale::locale(const locale& __other, _Facet* __f)
158
{
159
    __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
160
}
161

    
162
template <class _Facet>
163
locale
164
locale::combine(const locale& __other) const
165
{
166
#ifndef _LIBCPP_NO_EXCEPTIONS
167
    if (!_VSTD::has_facet<_Facet>(__other))
168
        throw runtime_error("locale::combine: locale missing facet");
169
#endif  // _LIBCPP_NO_EXCEPTIONS
170
    return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
171
}
172

    
173
template <class _Facet>
174
inline _LIBCPP_INLINE_VISIBILITY
175
bool
176
has_facet(const locale& __l)  _NOEXCEPT
177
{
178
    return __l.has_facet(_Facet::id);
179
}
180

    
181
template <class _Facet>
182
inline _LIBCPP_INLINE_VISIBILITY
183
const _Facet&
184
use_facet(const locale& __l)
185
{
186
    return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
187
}
188

    
189
// template <class _CharT> class collate;
190

    
191
template <class _CharT>
192
class _LIBCPP_TYPE_VIS_ONLY collate
193
    : public locale::facet
194
{
195
public:
196
    typedef _CharT char_type;
197
    typedef basic_string<char_type> string_type;
198

    
199
    _LIBCPP_INLINE_VISIBILITY
200
    explicit collate(size_t __refs = 0)
201
        : locale::facet(__refs) {}
202

    
203
    _LIBCPP_INLINE_VISIBILITY
204
    int compare(const char_type* __lo1, const char_type* __hi1,
205
                const char_type* __lo2, const char_type* __hi2) const
206
    {
207
        return do_compare(__lo1, __hi1, __lo2, __hi2);
208
    }
209

    
210
    _LIBCPP_INLINE_VISIBILITY
211
    string_type transform(const char_type* __lo, const char_type* __hi) const
212
    {
213
        return do_transform(__lo, __hi);
214
    }
215

    
216
    _LIBCPP_INLINE_VISIBILITY
217
    long hash(const char_type* __lo, const char_type* __hi) const
218
    {
219
        return do_hash(__lo, __hi);
220
    }
221

    
222
    static locale::id id;
223

    
224
protected:
225
    ~collate();
226
    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
227
                           const char_type* __lo2, const char_type* __hi2) const;
228
    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
229
        {return string_type(__lo, __hi);}
230
    virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
231
};
232

    
233
template <class _CharT> locale::id collate<_CharT>::id;
234

    
235
template <class _CharT>
236
collate<_CharT>::~collate()
237
{
238
}
239

    
240
template <class _CharT>
241
int
242
collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
243
                            const char_type* __lo2, const char_type* __hi2) const
244
{
245
    for (; __lo2 != __hi2; ++__lo1, ++__lo2)
246
    {
247
        if (__lo1 == __hi1 || *__lo1 < *__lo2)
248
            return -1;
249
        if (*__lo2 < *__lo1)
250
            return 1;
251
    }
252
    return __lo1 != __hi1;
253
}
254

    
255
template <class _CharT>
256
long
257
collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
258
{
259
    size_t __h = 0;
260
    const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
261
    const size_t __mask = size_t(0xF) << (__sr + 4);
262
    for(const char_type* __p = __lo; __p != __hi; ++__p)
263
    {
264
        __h = (__h << 4) + static_cast<size_t>(*__p);
265
        size_t __g = __h & __mask;
266
        __h ^= __g | (__g >> __sr);
267
    }
268
    return static_cast<long>(__h);
269
}
270

    
271
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)
272
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)
273

    
274
// template <class CharT> class collate_byname;
275

    
276
template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY collate_byname;
277

    
278
template <>
279
class _LIBCPP_TYPE_VIS collate_byname<char>
280
    : public collate<char>
281
{
282
    locale_t __l;
283
public:
284
    typedef char char_type;
285
    typedef basic_string<char_type> string_type;
286

    
287
    explicit collate_byname(const char* __n, size_t __refs = 0);
288
    explicit collate_byname(const string& __n, size_t __refs = 0);
289

    
290
protected:
291
    ~collate_byname();
292
    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
293
                           const char_type* __lo2, const char_type* __hi2) const;
294
    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
295
};
296

    
297
template <>
298
class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
299
    : public collate<wchar_t>
300
{
301
    locale_t __l;
302
public:
303
    typedef wchar_t char_type;
304
    typedef basic_string<char_type> string_type;
305

    
306
    explicit collate_byname(const char* __n, size_t __refs = 0);
307
    explicit collate_byname(const string& __n, size_t __refs = 0);
308

    
309
protected:
310
    ~collate_byname();
311

    
312
    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
313
                           const char_type* __lo2, const char_type* __hi2) const;
314
    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
315
};
316

    
317
template <class _CharT, class _Traits, class _Allocator>
318
bool
319
locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
320
                   const basic_string<_CharT, _Traits, _Allocator>& __y) const
321
{
322
    return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
323
                                       __x.data(), __x.data() + __x.size(),
324
                                       __y.data(), __y.data() + __y.size()) < 0;
325
}
326

    
327
// template <class charT> class ctype
328

    
329
class _LIBCPP_TYPE_VIS ctype_base
330
{
331
public:
332
#ifdef __GLIBC__
333
    typedef unsigned short mask;
334
    static const mask space  = _ISspace;
335
    static const mask print  = _ISprint;
336
    static const mask cntrl  = _IScntrl;
337
    static const mask upper  = _ISupper;
338
    static const mask lower  = _ISlower;
339
    static const mask alpha  = _ISalpha;
340
    static const mask digit  = _ISdigit;
341
    static const mask punct  = _ISpunct;
342
    static const mask xdigit = _ISxdigit;
343
    static const mask blank  = _ISblank;
344
#elif defined(_WIN32)
345
    typedef unsigned short mask;
346
    static const mask space  = _SPACE;
347
    static const mask print  = _BLANK|_PUNCT|_ALPHA|_DIGIT;
348
    static const mask cntrl  = _CONTROL;
349
    static const mask upper  = _UPPER;
350
    static const mask lower  = _LOWER;
351
    static const mask alpha  = _ALPHA;
352
    static const mask digit  = _DIGIT;
353
    static const mask punct  = _PUNCT;
354
    static const mask xdigit = _HEX;
355
    static const mask blank  = _BLANK;
356
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
357
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
358
# ifdef __APPLE__
359
    typedef __uint32_t mask;
360
# elif defined(__FreeBSD__)
361
    typedef unsigned long mask;
362
# elif defined(__EMSCRIPTEN__) ||  defined(__NetBSD__) || defined(__minix)
363
    typedef unsigned short mask;
364
# endif
365
    static const mask space  = _CTYPE_S;
366
    static const mask print  = _CTYPE_R;
367
    static const mask cntrl  = _CTYPE_C;
368
    static const mask upper  = _CTYPE_U;
369
    static const mask lower  = _CTYPE_L;
370
    static const mask alpha  = _CTYPE_A;
371
    static const mask digit  = _CTYPE_D;
372
    static const mask punct  = _CTYPE_P;
373
    static const mask xdigit = _CTYPE_X;
374

    
375
# if defined(__NetBSD__) || defined(__minix)
376
    static const mask blank  = _CTYPE_BL;
377
# else
378
    static const mask blank  = _CTYPE_B;
379
# endif
380
#elif defined(__sun__) || defined(_AIX)
381
    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;
392
#elif defined(_NEWLIB_VERSION)
393
    // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
394
    typedef char mask;
395
    static const mask space  = _S;
396
    static const mask print  = _P | _U | _L | _N | _B;
397
    static const mask cntrl  = _C;
398
    static const mask upper  = _U;
399
    static const mask lower  = _L;
400
    static const mask alpha  = _U | _L;
401
    static const mask digit  = _N;
402
    static const mask punct  = _P;
403
    static const mask xdigit = _X | _N;
404
    static const mask blank  = _B;
405
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
406
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
407
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
408
#else
409
    typedef unsigned long mask;
410
    static const mask space  = 1<<0;
411
    static const mask print  = 1<<1;
412
    static const mask cntrl  = 1<<2;
413
    static const mask upper  = 1<<3;
414
    static const mask lower  = 1<<4;
415
    static const mask alpha  = 1<<5;
416
    static const mask digit  = 1<<6;
417
    static const mask punct  = 1<<7;
418
    static const mask xdigit = 1<<8;
419
    static const mask blank  = 1<<9;
420
#endif
421
    static const mask alnum  = alpha | digit;
422
    static const mask graph  = alnum | punct;
423

    
424
    _LIBCPP_ALWAYS_INLINE ctype_base() {}
425
};
426

    
427
template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;
428

    
429
template <>
430
class _LIBCPP_TYPE_VIS ctype<wchar_t>
431
    : public locale::facet,
432
      public ctype_base
433
{
434
public:
435
    typedef wchar_t char_type;
436

    
437
    _LIBCPP_ALWAYS_INLINE
438
    explicit ctype(size_t __refs = 0)
439
        : locale::facet(__refs) {}
440

    
441
    _LIBCPP_ALWAYS_INLINE
442
    bool is(mask __m, char_type __c) const
443
    {
444
        return do_is(__m, __c);
445
    }
446

    
447
    _LIBCPP_ALWAYS_INLINE
448
    const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
449
    {
450
        return do_is(__low, __high, __vec);
451
    }
452

    
453
    _LIBCPP_ALWAYS_INLINE
454
    const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
455
    {
456
        return do_scan_is(__m, __low, __high);
457
    }
458

    
459
    _LIBCPP_ALWAYS_INLINE
460
    const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
461
    {
462
        return do_scan_not(__m, __low, __high);
463
    }
464

    
465
    _LIBCPP_ALWAYS_INLINE
466
    char_type toupper(char_type __c) const
467
    {
468
        return do_toupper(__c);
469
    }
470

    
471
    _LIBCPP_ALWAYS_INLINE
472
    const char_type* toupper(char_type* __low, const char_type* __high) const
473
    {
474
        return do_toupper(__low, __high);
475
    }
476

    
477
    _LIBCPP_ALWAYS_INLINE
478
    char_type tolower(char_type __c) const
479
    {
480
        return do_tolower(__c);
481
    }
482

    
483
    _LIBCPP_ALWAYS_INLINE
484
    const char_type* tolower(char_type* __low, const char_type* __high) const
485
    {
486
        return do_tolower(__low, __high);
487
    }
488

    
489
    _LIBCPP_ALWAYS_INLINE
490
    char_type widen(char __c) const
491
    {
492
        return do_widen(__c);
493
    }
494

    
495
    _LIBCPP_ALWAYS_INLINE
496
    const char* widen(const char* __low, const char* __high, char_type* __to) const
497
    {
498
        return do_widen(__low, __high, __to);
499
    }
500

    
501
    _LIBCPP_ALWAYS_INLINE
502
    char narrow(char_type __c, char __dfault) const
503
    {
504
        return do_narrow(__c, __dfault);
505
    }
506

    
507
    _LIBCPP_ALWAYS_INLINE
508
    const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
509
    {
510
        return do_narrow(__low, __high, __dfault, __to);
511
    }
512

    
513
    static locale::id id;
514

    
515
protected:
516
    ~ctype();
517
    virtual bool do_is(mask __m, char_type __c) const;
518
    virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
519
    virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
520
    virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
521
    virtual char_type do_toupper(char_type) const;
522
    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
523
    virtual char_type do_tolower(char_type) const;
524
    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
525
    virtual char_type do_widen(char) const;
526
    virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
527
    virtual char do_narrow(char_type, char __dfault) const;
528
    virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
529
};
530

    
531
template <>
532
class _LIBCPP_TYPE_VIS ctype<char>
533
    : public locale::facet, public ctype_base
534
{
535
    const mask* __tab_;
536
    bool        __del_;
537
public:
538
    typedef char char_type;
539

    
540
    explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
541

    
542
    _LIBCPP_ALWAYS_INLINE
543
    bool is(mask __m, char_type __c) const
544
    {
545
        return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
546
    }
547

    
548
    _LIBCPP_ALWAYS_INLINE
549
    const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
550
    {
551
        for (; __low != __high; ++__low, ++__vec)
552
            *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
553
        return __low;
554
    }
555

    
556
    _LIBCPP_ALWAYS_INLINE
557
    const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
558
    {
559
        for (; __low != __high; ++__low)
560
            if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
561
                break;
562
        return __low;
563
    }
564

    
565
    _LIBCPP_ALWAYS_INLINE
566
    const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
567
    {
568
        for (; __low != __high; ++__low)
569
            if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
570
                break;
571
        return __low;
572
    }
573

    
574
    _LIBCPP_ALWAYS_INLINE
575
    char_type toupper(char_type __c) const
576
    {
577
        return do_toupper(__c);
578
    }
579

    
580
    _LIBCPP_ALWAYS_INLINE
581
    const char_type* toupper(char_type* __low, const char_type* __high) const
582
    {
583
        return do_toupper(__low, __high);
584
    }
585

    
586
    _LIBCPP_ALWAYS_INLINE
587
    char_type tolower(char_type __c) const
588
    {
589
        return do_tolower(__c);
590
    }
591

    
592
    _LIBCPP_ALWAYS_INLINE
593
    const char_type* tolower(char_type* __low, const char_type* __high) const
594
    {
595
        return do_tolower(__low, __high);
596
    }
597

    
598
    _LIBCPP_ALWAYS_INLINE
599
    char_type widen(char __c) const
600
    {
601
        return do_widen(__c);
602
    }
603

    
604
    _LIBCPP_ALWAYS_INLINE
605
    const char* widen(const char* __low, const char* __high, char_type* __to) const
606
    {
607
        return do_widen(__low, __high, __to);
608
    }
609

    
610
    _LIBCPP_ALWAYS_INLINE
611
    char narrow(char_type __c, char __dfault) const
612
    {
613
        return do_narrow(__c, __dfault);
614
    }
615

    
616
    _LIBCPP_ALWAYS_INLINE
617
    const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
618
    {
619
        return do_narrow(__low, __high, __dfault, __to);
620
    }
621

    
622
    static locale::id id;
623

    
624
#ifdef _CACHED_RUNES
625
    static const size_t table_size = _CACHED_RUNES;
626
#else
627
    static const size_t table_size = 256;  // FIXME: Don't hardcode this.
628
#endif
629
    _LIBCPP_ALWAYS_INLINE const mask* table() const  _NOEXCEPT {return __tab_;}
630
    static const mask* classic_table()  _NOEXCEPT;
631
#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
632
    static const int* __classic_upper_table() _NOEXCEPT;
633
    static const int* __classic_lower_table() _NOEXCEPT;
634
#endif
635
#if defined(__NetBSD__) || defined(__minix)
636
    static const short* __classic_upper_table() _NOEXCEPT;
637
    static const short* __classic_lower_table() _NOEXCEPT;
638
#endif
639

    
640
protected:
641
    ~ctype();
642
    virtual char_type do_toupper(char_type __c) const;
643
    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
644
    virtual char_type do_tolower(char_type __c) const;
645
    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
646
    virtual char_type do_widen(char __c) const;
647
    virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
648
    virtual char do_narrow(char_type __c, char __dfault) const;
649
    virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
650
};
651

    
652
// template <class CharT> class ctype_byname;
653

    
654
template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype_byname;
655

    
656
template <>
657
class _LIBCPP_TYPE_VIS ctype_byname<char>
658
    : public ctype<char>
659
{
660
    locale_t __l;
661

    
662
public:
663
    explicit ctype_byname(const char*, size_t = 0);
664
    explicit ctype_byname(const string&, size_t = 0);
665

    
666
protected:
667
    ~ctype_byname();
668
    virtual char_type do_toupper(char_type) const;
669
    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
670
    virtual char_type do_tolower(char_type) const;
671
    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
672
};
673

    
674
template <>
675
class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
676
    : public ctype<wchar_t>
677
{
678
    locale_t __l;
679

    
680
public:
681
    explicit ctype_byname(const char*, size_t = 0);
682
    explicit ctype_byname(const string&, size_t = 0);
683

    
684
protected:
685
    ~ctype_byname();
686
    virtual bool do_is(mask __m, char_type __c) const;
687
    virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
688
    virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
689
    virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
690
    virtual char_type do_toupper(char_type) const;
691
    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
692
    virtual char_type do_tolower(char_type) const;
693
    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
694
    virtual char_type do_widen(char) const;
695
    virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
696
    virtual char do_narrow(char_type, char __dfault) const;
697
    virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
698
};
699

    
700
template <class _CharT>
701
inline _LIBCPP_INLINE_VISIBILITY
702
bool
703
isspace(_CharT __c, const locale& __loc)
704
{
705
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
706
}
707

    
708
template <class _CharT>
709
inline _LIBCPP_INLINE_VISIBILITY
710
bool
711
isprint(_CharT __c, const locale& __loc)
712
{
713
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
714
}
715

    
716
template <class _CharT>
717
inline _LIBCPP_INLINE_VISIBILITY
718
bool
719
iscntrl(_CharT __c, const locale& __loc)
720
{
721
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
722
}
723

    
724
template <class _CharT>
725
inline _LIBCPP_INLINE_VISIBILITY
726
bool
727
isupper(_CharT __c, const locale& __loc)
728
{
729
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
730
}
731

    
732
template <class _CharT>
733
inline _LIBCPP_INLINE_VISIBILITY
734
bool
735
islower(_CharT __c, const locale& __loc)
736
{
737
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
738
}
739

    
740
template <class _CharT>
741
inline _LIBCPP_INLINE_VISIBILITY
742
bool
743
isalpha(_CharT __c, const locale& __loc)
744
{
745
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
746
}
747

    
748
template <class _CharT>
749
inline _LIBCPP_INLINE_VISIBILITY
750
bool
751
isdigit(_CharT __c, const locale& __loc)
752
{
753
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
754
}
755

    
756
template <class _CharT>
757
inline _LIBCPP_INLINE_VISIBILITY
758
bool
759
ispunct(_CharT __c, const locale& __loc)
760
{
761
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
762
}
763

    
764
template <class _CharT>
765
inline _LIBCPP_INLINE_VISIBILITY
766
bool
767
isxdigit(_CharT __c, const locale& __loc)
768
{
769
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
770
}
771

    
772
template <class _CharT>
773
inline _LIBCPP_INLINE_VISIBILITY
774
bool
775
isalnum(_CharT __c, const locale& __loc)
776
{
777
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
778
}
779

    
780
template <class _CharT>
781
inline _LIBCPP_INLINE_VISIBILITY
782
bool
783
isgraph(_CharT __c, const locale& __loc)
784
{
785
    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
786
}
787

    
788
template <class _CharT>
789
inline _LIBCPP_INLINE_VISIBILITY
790
_CharT
791
toupper(_CharT __c, const locale& __loc)
792
{
793
    return use_facet<ctype<_CharT> >(__loc).toupper(__c);
794
}
795

    
796
template <class _CharT>
797
inline _LIBCPP_INLINE_VISIBILITY
798
_CharT
799
tolower(_CharT __c, const locale& __loc)
800
{
801
    return use_facet<ctype<_CharT> >(__loc).tolower(__c);
802
}
803

    
804
// codecvt_base
805

    
806
class _LIBCPP_TYPE_VIS codecvt_base
807
{
808
public:
809
    _LIBCPP_ALWAYS_INLINE codecvt_base() {}
810
    enum result {ok, partial, error, noconv};
811
};
812

    
813
// template <class internT, class externT, class stateT> class codecvt;
814

    
815
template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS_ONLY codecvt;
816

    
817
// template <> class codecvt<char, char, mbstate_t>
818

    
819
template <>
820
class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
821
    : public locale::facet,
822
      public codecvt_base
823
{
824
public:
825
    typedef char      intern_type;
826
    typedef char      extern_type;
827
    typedef mbstate_t state_type;
828

    
829
    _LIBCPP_ALWAYS_INLINE
830
    explicit codecvt(size_t __refs = 0)
831
        : locale::facet(__refs) {}
832

    
833
    _LIBCPP_ALWAYS_INLINE
834
    result out(state_type& __st,
835
               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
836
               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
837
    {
838
        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
839
    }
840

    
841
    _LIBCPP_ALWAYS_INLINE
842
    result unshift(state_type& __st,
843
                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
844
    {
845
        return do_unshift(__st, __to, __to_end, __to_nxt);
846
    }
847

    
848
    _LIBCPP_ALWAYS_INLINE
849
    result in(state_type& __st,
850
              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
851
              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
852
    {
853
        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
854
    }
855

    
856
    _LIBCPP_ALWAYS_INLINE
857
    int encoding() const  _NOEXCEPT
858
    {
859
        return do_encoding();
860
    }
861

    
862
    _LIBCPP_ALWAYS_INLINE
863
    bool always_noconv() const  _NOEXCEPT
864
    {
865
        return do_always_noconv();
866
    }
867

    
868
    _LIBCPP_ALWAYS_INLINE
869
    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
870
    {
871
        return do_length(__st, __frm, __end, __mx);
872
    }
873

    
874
    _LIBCPP_ALWAYS_INLINE
875
    int max_length() const  _NOEXCEPT
876
    {
877
        return do_max_length();
878
    }
879

    
880
    static locale::id id;
881

    
882
protected:
883
    _LIBCPP_ALWAYS_INLINE
884
    explicit codecvt(const char*, size_t __refs = 0)
885
        : locale::facet(__refs) {}
886

    
887
    ~codecvt();
888

    
889
    virtual result do_out(state_type& __st,
890
                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
891
                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
892
    virtual result do_in(state_type& __st,
893
                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
894
                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
895
    virtual result do_unshift(state_type& __st,
896
                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
897
    virtual int do_encoding() const  _NOEXCEPT;
898
    virtual bool do_always_noconv() const  _NOEXCEPT;
899
    virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
900
    virtual int do_max_length() const  _NOEXCEPT;
901
};
902

    
903
// template <> class codecvt<wchar_t, char, mbstate_t>
904

    
905
template <>
906
class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
907
    : public locale::facet,
908
      public codecvt_base
909
{
910
    locale_t __l;
911
public:
912
    typedef wchar_t   intern_type;
913
    typedef char      extern_type;
914
    typedef mbstate_t state_type;
915

    
916
    explicit codecvt(size_t __refs = 0);
917

    
918
    _LIBCPP_ALWAYS_INLINE
919
    result out(state_type& __st,
920
               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
921
               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
922
    {
923
        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
924
    }
925

    
926
    _LIBCPP_ALWAYS_INLINE
927
    result unshift(state_type& __st,
928
                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
929
    {
930
        return do_unshift(__st, __to, __to_end, __to_nxt);
931
    }
932

    
933
    _LIBCPP_ALWAYS_INLINE
934
    result in(state_type& __st,
935
              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
936
              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
937
    {
938
        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
939
    }
940

    
941
    _LIBCPP_ALWAYS_INLINE
942
    int encoding() const  _NOEXCEPT
943
    {
944
        return do_encoding();
945
    }
946

    
947
    _LIBCPP_ALWAYS_INLINE
948
    bool always_noconv() const  _NOEXCEPT
949
    {
950
        return do_always_noconv();
951
    }
952

    
953
    _LIBCPP_ALWAYS_INLINE
954
    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
955
    {
956
        return do_length(__st, __frm, __end, __mx);
957
    }
958

    
959
    _LIBCPP_ALWAYS_INLINE
960
    int max_length() const  _NOEXCEPT
961
    {
962
        return do_max_length();
963
    }
964

    
965
    static locale::id id;
966

    
967
protected:
968
    explicit codecvt(const char*, size_t __refs = 0);
969

    
970
    ~codecvt();
971

    
972
    virtual result do_out(state_type& __st,
973
                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
974
                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
975
    virtual result do_in(state_type& __st,
976
                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
977
                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
978
    virtual result do_unshift(state_type& __st,
979
                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
980
    virtual int do_encoding() const  _NOEXCEPT;
981
    virtual bool do_always_noconv() const  _NOEXCEPT;
982
    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
983
    virtual int do_max_length() const  _NOEXCEPT;
984
};
985

    
986
// template <> class codecvt<char16_t, char, mbstate_t>
987

    
988
template <>
989
class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
990
    : public locale::facet,
991
      public codecvt_base
992
{
993
public:
994
    typedef char16_t  intern_type;
995
    typedef char      extern_type;
996
    typedef mbstate_t state_type;
997

    
998
    _LIBCPP_ALWAYS_INLINE
999
    explicit codecvt(size_t __refs = 0)
1000
        : locale::facet(__refs) {}
1001

    
1002
    _LIBCPP_ALWAYS_INLINE
1003
    result out(state_type& __st,
1004
               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1005
               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1006
    {
1007
        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1008
    }
1009

    
1010
    _LIBCPP_ALWAYS_INLINE
1011
    result unshift(state_type& __st,
1012
                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1013
    {
1014
        return do_unshift(__st, __to, __to_end, __to_nxt);
1015
    }
1016

    
1017
    _LIBCPP_ALWAYS_INLINE
1018
    result in(state_type& __st,
1019
              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1020
              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1021
    {
1022
        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1023
    }
1024

    
1025
    _LIBCPP_ALWAYS_INLINE
1026
    int encoding() const  _NOEXCEPT
1027
    {
1028
        return do_encoding();
1029
    }
1030

    
1031
    _LIBCPP_ALWAYS_INLINE
1032
    bool always_noconv() const  _NOEXCEPT
1033
    {
1034
        return do_always_noconv();
1035
    }
1036

    
1037
    _LIBCPP_ALWAYS_INLINE
1038
    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1039
    {
1040
        return do_length(__st, __frm, __end, __mx);
1041
    }
1042

    
1043
    _LIBCPP_ALWAYS_INLINE
1044
    int max_length() const  _NOEXCEPT
1045
    {
1046
        return do_max_length();
1047
    }
1048

    
1049
    static locale::id id;
1050

    
1051
protected:
1052
    _LIBCPP_ALWAYS_INLINE
1053
    explicit codecvt(const char*, size_t __refs = 0)
1054
        : locale::facet(__refs) {}
1055

    
1056
    ~codecvt();
1057

    
1058
    virtual result do_out(state_type& __st,
1059
                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1060
                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1061
    virtual result do_in(state_type& __st,
1062
                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1063
                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1064
    virtual result do_unshift(state_type& __st,
1065
                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1066
    virtual int do_encoding() const  _NOEXCEPT;
1067
    virtual bool do_always_noconv() const  _NOEXCEPT;
1068
    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1069
    virtual int do_max_length() const  _NOEXCEPT;
1070
};
1071

    
1072
// template <> class codecvt<char32_t, char, mbstate_t>
1073

    
1074
template <>
1075
class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
1076
    : public locale::facet,
1077
      public codecvt_base
1078
{
1079
public:
1080
    typedef char32_t  intern_type;
1081
    typedef char      extern_type;
1082
    typedef mbstate_t state_type;
1083

    
1084
    _LIBCPP_ALWAYS_INLINE
1085
    explicit codecvt(size_t __refs = 0)
1086
        : locale::facet(__refs) {}
1087

    
1088
    _LIBCPP_ALWAYS_INLINE
1089
    result out(state_type& __st,
1090
               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1091
               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1092
    {
1093
        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1094
    }
1095

    
1096
    _LIBCPP_ALWAYS_INLINE
1097
    result unshift(state_type& __st,
1098
                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1099
    {
1100
        return do_unshift(__st, __to, __to_end, __to_nxt);
1101
    }
1102

    
1103
    _LIBCPP_ALWAYS_INLINE
1104
    result in(state_type& __st,
1105
              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1106
              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1107
    {
1108
        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1109
    }
1110

    
1111
    _LIBCPP_ALWAYS_INLINE
1112
    int encoding() const  _NOEXCEPT
1113
    {
1114
        return do_encoding();
1115
    }
1116

    
1117
    _LIBCPP_ALWAYS_INLINE
1118
    bool always_noconv() const  _NOEXCEPT
1119
    {
1120
        return do_always_noconv();
1121
    }
1122

    
1123
    _LIBCPP_ALWAYS_INLINE
1124
    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1125
    {
1126
        return do_length(__st, __frm, __end, __mx);
1127
    }
1128

    
1129
    _LIBCPP_ALWAYS_INLINE
1130
    int max_length() const  _NOEXCEPT
1131
    {
1132
        return do_max_length();
1133
    }
1134

    
1135
    static locale::id id;
1136

    
1137
protected:
1138
    _LIBCPP_ALWAYS_INLINE
1139
    explicit codecvt(const char*, size_t __refs = 0)
1140
        : locale::facet(__refs) {}
1141

    
1142
    ~codecvt();
1143

    
1144
    virtual result do_out(state_type& __st,
1145
                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1146
                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1147
    virtual result do_in(state_type& __st,
1148
                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1149
                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1150
    virtual result do_unshift(state_type& __st,
1151
                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1152
    virtual int do_encoding() const  _NOEXCEPT;
1153
    virtual bool do_always_noconv() const  _NOEXCEPT;
1154
    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1155
    virtual int do_max_length() const  _NOEXCEPT;
1156
};
1157

    
1158
// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1159

    
1160
template <class _InternT, class _ExternT, class _StateT>
1161
class _LIBCPP_TYPE_VIS_ONLY codecvt_byname
1162
    : public codecvt<_InternT, _ExternT, _StateT>
1163
{
1164
public:
1165
    _LIBCPP_ALWAYS_INLINE
1166
    explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1167
        : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
1168
    _LIBCPP_ALWAYS_INLINE
1169
    explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1170
        : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1171
protected:
1172
    ~codecvt_byname();
1173
};
1174

    
1175
template <class _InternT, class _ExternT, class _StateT>
1176
codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1177
{
1178
}
1179

    
1180
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
1181
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
1182
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
1183
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
1184

    
1185
_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
1186

    
1187
template <size_t _Np>
1188
struct __narrow_to_utf8
1189
{
1190
    template <class _OutputIterator, class _CharT>
1191
    _OutputIterator
1192
    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1193
};
1194

    
1195
template <>
1196
struct __narrow_to_utf8<8>
1197
{
1198
    template <class _OutputIterator, class _CharT>
1199
    _LIBCPP_ALWAYS_INLINE
1200
    _OutputIterator
1201
    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1202
    {
1203
        for (; __wb < __we; ++__wb, ++__s)
1204
            *__s = *__wb;
1205
        return __s;
1206
    }
1207
};
1208

    
1209
template <>
1210
struct __narrow_to_utf8<16>
1211
    : public codecvt<char16_t, char, mbstate_t>
1212
{
1213
    _LIBCPP_ALWAYS_INLINE
1214
    __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1215

    
1216
    ~__narrow_to_utf8();
1217

    
1218
    template <class _OutputIterator, class _CharT>
1219
    _LIBCPP_ALWAYS_INLINE
1220
    _OutputIterator
1221
    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1222
    {
1223
        result __r = ok;
1224
        mbstate_t __mb;
1225
        while (__wb < __we && __r != error)
1226
        {
1227
            const int __sz = 32;
1228
            char __buf[__sz];
1229
            char* __bn;
1230
            const char16_t* __wn = (const char16_t*)__wb;
1231
            __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1232
                         __buf, __buf+__sz, __bn);
1233
            if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1234
                __throw_runtime_error("locale not supported");
1235
            for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1236
                *__s = *__p;
1237
            __wb = (const _CharT*)__wn;
1238
        }
1239
        return __s;
1240
    }
1241
};
1242

    
1243
template <>
1244
struct __narrow_to_utf8<32>
1245
    : public codecvt<char32_t, char, mbstate_t>
1246
{
1247
    _LIBCPP_ALWAYS_INLINE
1248
    __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1249

    
1250
    ~__narrow_to_utf8();
1251

    
1252
    template <class _OutputIterator, class _CharT>
1253
    _LIBCPP_ALWAYS_INLINE
1254
    _OutputIterator
1255
    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1256
    {
1257
        result __r = ok;
1258
        mbstate_t __mb;
1259
        while (__wb < __we && __r != error)
1260
        {
1261
            const int __sz = 32;
1262
            char __buf[__sz];
1263
            char* __bn;
1264
            const char32_t* __wn = (const char32_t*)__wb;
1265
            __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1266
                         __buf, __buf+__sz, __bn);
1267
            if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1268
                __throw_runtime_error("locale not supported");
1269
            for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1270
                *__s = *__p;
1271
            __wb = (const _CharT*)__wn;
1272
        }
1273
        return __s;
1274
    }
1275
};
1276

    
1277
template <size_t _Np>
1278
struct __widen_from_utf8
1279
{
1280
    template <class _OutputIterator>
1281
    _OutputIterator
1282
    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1283
};
1284

    
1285
template <>
1286
struct __widen_from_utf8<8>
1287
{
1288
    template <class _OutputIterator>
1289
    _LIBCPP_ALWAYS_INLINE
1290
    _OutputIterator
1291
    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1292
    {
1293
        for (; __nb < __ne; ++__nb, ++__s)
1294
            *__s = *__nb;
1295
        return __s;
1296
    }
1297
};
1298

    
1299
template <>
1300
struct __widen_from_utf8<16>
1301
    : public codecvt<char16_t, char, mbstate_t>
1302
{
1303
    _LIBCPP_ALWAYS_INLINE
1304
    __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1305

    
1306
    ~__widen_from_utf8();
1307

    
1308
    template <class _OutputIterator>
1309
    _LIBCPP_ALWAYS_INLINE
1310
    _OutputIterator
1311
    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1312
    {
1313
        result __r = ok;
1314
        mbstate_t __mb;
1315
        while (__nb < __ne && __r != error)
1316
        {
1317
            const int __sz = 32;
1318
            char16_t __buf[__sz];
1319
            char16_t* __bn;
1320
            const char* __nn = __nb;
1321
            __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1322
                        __buf, __buf+__sz, __bn);
1323
            if (__r == codecvt_base::error || __nn == __nb)
1324
                __throw_runtime_error("locale not supported");
1325
            for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1326
                *__s = (wchar_t)*__p;
1327
            __nb = __nn;
1328
        }
1329
        return __s;
1330
    }
1331
};
1332

    
1333
template <>
1334
struct __widen_from_utf8<32>
1335
    : public codecvt<char32_t, char, mbstate_t>
1336
{
1337
    _LIBCPP_ALWAYS_INLINE
1338
    __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1339

    
1340
    ~__widen_from_utf8();
1341

    
1342
    template <class _OutputIterator>
1343
    _LIBCPP_ALWAYS_INLINE
1344
    _OutputIterator
1345
    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1346
    {
1347
        result __r = ok;
1348
        mbstate_t __mb;
1349
        while (__nb < __ne && __r != error)
1350
        {
1351
            const int __sz = 32;
1352
            char32_t __buf[__sz];
1353
            char32_t* __bn;
1354
            const char* __nn = __nb;
1355
            __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1356
                        __buf, __buf+__sz, __bn);
1357
            if (__r == codecvt_base::error || __nn == __nb)
1358
                __throw_runtime_error("locale not supported");
1359
            for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1360
                *__s = (wchar_t)*__p;
1361
            __nb = __nn;
1362
        }
1363
        return __s;
1364
    }
1365
};
1366

    
1367
// template <class charT> class numpunct
1368

    
1369
template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct;
1370

    
1371
template <>
1372
class _LIBCPP_TYPE_VIS numpunct<char>
1373
    : public locale::facet
1374
{
1375
public:
1376
    typedef char char_type;
1377
    typedef basic_string<char_type> string_type;
1378

    
1379
    explicit numpunct(size_t __refs = 0);
1380

    
1381
    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1382
    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1383
    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
1384
    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
1385
    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
1386

    
1387
    static locale::id id;
1388

    
1389
protected:
1390
    ~numpunct();
1391
    virtual char_type do_decimal_point() const;
1392
    virtual char_type do_thousands_sep() const;
1393
    virtual string do_grouping() const;
1394
    virtual string_type do_truename() const;
1395
    virtual string_type do_falsename() const;
1396

    
1397
    char_type __decimal_point_;
1398
    char_type __thousands_sep_;
1399
    string __grouping_;
1400
};
1401

    
1402
template <>
1403
class _LIBCPP_TYPE_VIS numpunct<wchar_t>
1404
    : public locale::facet
1405
{
1406
public:
1407
    typedef wchar_t char_type;
1408
    typedef basic_string<char_type> string_type;
1409

    
1410
    explicit numpunct(size_t __refs = 0);
1411

    
1412
    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1413
    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1414
    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
1415
    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
1416
    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
1417

    
1418
    static locale::id id;
1419

    
1420
protected:
1421
    ~numpunct();
1422
    virtual char_type do_decimal_point() const;
1423
    virtual char_type do_thousands_sep() const;
1424
    virtual string do_grouping() const;
1425
    virtual string_type do_truename() const;
1426
    virtual string_type do_falsename() const;
1427

    
1428
    char_type __decimal_point_;
1429
    char_type __thousands_sep_;
1430
    string __grouping_;
1431
};
1432

    
1433
// template <class charT> class numpunct_byname
1434

    
1435
template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct_byname;
1436

    
1437
template <>
1438
class _LIBCPP_TYPE_VIS numpunct_byname<char>
1439
: public numpunct<char>
1440
{
1441
public:
1442
    typedef char char_type;
1443
    typedef basic_string<char_type> string_type;
1444

    
1445
    explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1446
    explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1447

    
1448
protected:
1449
    ~numpunct_byname();
1450

    
1451
private:
1452
    void __init(const char*);
1453
};
1454

    
1455
template <>
1456
class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
1457
: public numpunct<wchar_t>
1458
{
1459
public:
1460
    typedef wchar_t char_type;
1461
    typedef basic_string<char_type> string_type;
1462

    
1463
    explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1464
    explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1465

    
1466
protected:
1467
    ~numpunct_byname();
1468

    
1469
private:
1470
    void __init(const char*);
1471
};
1472

    
1473
_LIBCPP_END_NAMESPACE_STD
1474

    
1475
#endif  // _LIBCPP___LOCALE