~ubuntu-branches/ubuntu/saucy/emscripten/saucy-proposed

« back to all changes in this revision

Viewing changes to system/include/libcxx/locale

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- C++ -*-
 
2
//===-------------------------- locale ------------------------------------===//
 
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
/*
 
15
    locale synopsis
 
16
 
 
17
namespace std
 
18
{
 
19
 
 
20
class locale
 
21
{
 
22
public:
 
23
    // types:
 
24
    class facet;
 
25
    class id;
 
26
 
 
27
    typedef int category;
 
28
    static const category // values assigned here are for exposition only
 
29
        none     = 0x000,
 
30
        collate  = 0x010,
 
31
        ctype    = 0x020,
 
32
        monetary = 0x040,
 
33
        numeric  = 0x080,
 
34
        time     = 0x100,
 
35
        messages = 0x200,
 
36
        all = collate | ctype | monetary | numeric | time | messages;
 
37
 
 
38
    // construct/copy/destroy:
 
39
    locale() noexcept;
 
40
    locale(const locale& other) noexcept;
 
41
    explicit locale(const char* std_name);
 
42
    explicit locale(const string& std_name);
 
43
    locale(const locale& other, const char* std_name, category);
 
44
    locale(const locale& other, const string& std_name, category);
 
45
    template <class Facet> locale(const locale& other, Facet* f);
 
46
    locale(const locale& other, const locale& one, category);
 
47
 
 
48
    ~locale(); // not virtual
 
49
 
 
50
    const locale& operator=(const locale& other) noexcept;
 
51
 
 
52
    template <class Facet> locale combine(const locale& other) const;
 
53
 
 
54
    // locale operations:
 
55
    basic_string<char> name() const;
 
56
    bool operator==(const locale& other) const;
 
57
    bool operator!=(const locale& other) const;
 
58
    template <class charT, class Traits, class Allocator>
 
59
      bool operator()(const basic_string<charT,Traits,Allocator>& s1,
 
60
                      const basic_string<charT,Traits,Allocator>& s2) const;
 
61
 
 
62
    // global locale objects:
 
63
    static locale global(const locale&);
 
64
    static const locale& classic();
 
65
};
 
66
 
 
67
template <class Facet> const Facet& use_facet(const locale&);
 
68
template <class Facet> bool has_facet(const locale&) noexcept;
 
69
 
 
70
// 22.3.3, convenience interfaces:
 
71
template <class charT> bool isspace (charT c, const locale& loc);
 
72
template <class charT> bool isprint (charT c, const locale& loc);
 
73
template <class charT> bool iscntrl (charT c, const locale& loc);
 
74
template <class charT> bool isupper (charT c, const locale& loc);
 
75
template <class charT> bool islower (charT c, const locale& loc);
 
76
template <class charT> bool isalpha (charT c, const locale& loc);
 
77
template <class charT> bool isdigit (charT c, const locale& loc);
 
78
template <class charT> bool ispunct (charT c, const locale& loc);
 
79
template <class charT> bool isxdigit(charT c, const locale& loc);
 
80
template <class charT> bool isalnum (charT c, const locale& loc);
 
81
template <class charT> bool isgraph (charT c, const locale& loc);
 
82
template <class charT> charT toupper(charT c, const locale& loc);
 
83
template <class charT> charT tolower(charT c, const locale& loc);
 
84
 
 
85
template<class Codecvt, class Elem = wchar_t,
 
86
         class Wide_alloc = allocator<Elem>,
 
87
         class Byte_alloc = allocator<char>>
 
88
class wstring_convert
 
89
{
 
90
public:
 
91
    typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string;
 
92
    typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;
 
93
    typedef typename Codecvt::state_type                      state_type;
 
94
    typedef typename wide_string::traits_type::int_type       int_type;
 
95
 
 
96
    wstring_convert(Codecvt* pcvt = new Codecvt);
 
97
    wstring_convert(Codecvt* pcvt, state_type state);
 
98
    wstring_convert(const byte_string& byte_err,
 
99
                    const wide_string& wide_err = wide_string());
 
100
    ~wstring_convert();
 
101
 
 
102
    wide_string from_bytes(char byte);
 
103
    wide_string from_bytes(const char* ptr);
 
104
    wide_string from_bytes(const byte_string& str);
 
105
    wide_string from_bytes(const char* first, const char* last);
 
106
 
 
107
    byte_string to_bytes(Elem wchar);
 
108
    byte_string to_bytes(const Elem* wptr);
 
109
    byte_string to_bytes(const wide_string& wstr);
 
110
    byte_string to_bytes(const Elem* first, const Elem* last);
 
111
 
 
112
    size_t converted() const;
 
113
    state_type state() const;
 
114
};
 
115
 
 
116
template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
 
117
class wbuffer_convert
 
118
    : public basic_streambuf<Elem, Tr>
 
119
{
 
120
public:
 
121
    typedef typename Tr::state_type state_type;
 
122
 
 
123
    wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
 
124
                    state_type state = state_type());
 
125
 
 
126
    streambuf* rdbuf() const;
 
127
    streambuf* rdbuf(streambuf* bytebuf);
 
128
 
 
129
    state_type state() const;
 
130
};
 
131
 
 
132
// 22.4.1 and 22.4.1.3, ctype:
 
133
class ctype_base;
 
134
template <class charT> class ctype;
 
135
template <> class ctype<char>; // specialization
 
136
template <class charT> class ctype_byname;
 
137
template <> class ctype_byname<char>; // specialization
 
138
 
 
139
class codecvt_base;
 
140
template <class internT, class externT, class stateT> class codecvt;
 
141
template <class internT, class externT, class stateT> class codecvt_byname;
 
142
 
 
143
// 22.4.2 and 22.4.3, numeric:
 
144
template <class charT, class InputIterator> class num_get;
 
145
template <class charT, class OutputIterator> class num_put;
 
146
template <class charT> class numpunct;
 
147
template <class charT> class numpunct_byname;
 
148
 
 
149
// 22.4.4, col lation:
 
150
template <class charT> class collate;
 
151
template <class charT> class collate_byname;
 
152
 
 
153
// 22.4.5, date and time:
 
154
class time_base;
 
155
template <class charT, class InputIterator> class time_get;
 
156
template <class charT, class InputIterator> class time_get_byname;
 
157
template <class charT, class OutputIterator> class time_put;
 
158
template <class charT, class OutputIterator> class time_put_byname;
 
159
 
 
160
// 22.4.6, money:
 
161
class money_base;
 
162
template <class charT, class InputIterator> class money_get;
 
163
template <class charT, class OutputIterator> class money_put;
 
164
template <class charT, bool Intl> class moneypunct;
 
165
template <class charT, bool Intl> class moneypunct_byname;
 
166
 
 
167
// 22.4.7, message retrieval:
 
168
class messages_base;
 
169
template <class charT> class messages;
 
170
template <class charT> class messages_byname;
 
171
 
 
172
}  // std
 
173
 
 
174
*/
 
175
 
 
176
#include <__config>
 
177
#include <__locale>
 
178
#include <algorithm>
 
179
#include <memory>
 
180
#include <ios>
 
181
#include <streambuf>
 
182
#include <iterator>
 
183
#include <limits>
 
184
#ifndef __APPLE__
 
185
#include <cstdarg>
 
186
#endif
 
187
#include <cstdlib>
 
188
#include <ctime>
 
189
#ifdef _WIN32
 
190
#include <support/win32/locale_win32.h>
 
191
#else // _WIN32
 
192
#include <nl_types.h>
 
193
#endif  // !_WIN32
 
194
 
 
195
#ifdef __APPLE__
 
196
#include <Availability.h>
 
197
#endif
 
198
 
 
199
#include <__undef_min_max>
 
200
 
 
201
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 
202
#pragma GCC system_header
 
203
#endif
 
204
 
 
205
_LIBCPP_BEGIN_NAMESPACE_STD
 
206
 
 
207
#if defined(__APPLE__) || defined(__FreeBSD__)
 
208
#  define _LIBCPP_GET_C_LOCALE 0
 
209
#else
 
210
#  define _LIBCPP_GET_C_LOCALE __cloc()
 
211
   // Get the C locale object
 
212
   locale_t __cloc();
 
213
#define __cloc_defined
 
214
#endif
 
215
 
 
216
typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
 
217
typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
 
218
#ifndef _LIBCPP_LOCALE__L_EXTENSIONS
 
219
typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
 
220
#endif
 
221
 
 
222
// OSX has nice foo_l() functions that let you turn off use of the global
 
223
// locale.  Linux, not so much.  The following functions avoid the locale when
 
224
// that's possible and otherwise do the wrong thing.  FIXME.
 
225
#if defined(__linux__) || defined(EMSCRIPTEN)
 
226
 
 
227
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
228
decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
 
229
inline _LIBCPP_INLINE_VISIBILITY
 
230
__mb_cur_max_l(locale_t __l)
 
231
{
 
232
  return MB_CUR_MAX_L(__l);
 
233
}
 
234
#else  // _LIBCPP_LOCALE__L_EXTENSIONS
 
235
_LIBCPP_ALWAYS_INLINE inline
 
236
decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
 
237
{
 
238
  __locale_raii __current(uselocale(__l), uselocale);
 
239
  return MB_CUR_MAX;
 
240
}
 
241
#endif // _LIBCPP_LOCALE__L_EXTENSIONS
 
242
 
 
243
_LIBCPP_ALWAYS_INLINE inline
 
244
wint_t __btowc_l(int __c, locale_t __l)
 
245
{
 
246
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
247
  return btowc_l(__c, __l);
 
248
#else
 
249
  __locale_raii __current(uselocale(__l), uselocale);
 
250
  return btowc(__c);
 
251
#endif
 
252
}
 
253
 
 
254
_LIBCPP_ALWAYS_INLINE inline
 
255
int __wctob_l(wint_t __c, locale_t __l)
 
256
{
 
257
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
258
  return wctob_l(__c, __l);
 
259
#else
 
260
  __locale_raii __current(uselocale(__l), uselocale);
 
261
  return wctob(__c);
 
262
#endif
 
263
}
 
264
 
 
265
_LIBCPP_ALWAYS_INLINE inline
 
266
size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
 
267
                      size_t __len, mbstate_t *__ps, locale_t __l)
 
268
{
 
269
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
270
  return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);
 
271
#else
 
272
  __locale_raii __current(uselocale(__l), uselocale);
 
273
  return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
 
274
#endif
 
275
}
 
276
 
 
277
_LIBCPP_ALWAYS_INLINE inline
 
278
size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
 
279
{
 
280
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
281
  return wcrtomb_l(__s, __wc, __ps, __l);
 
282
#else
 
283
  __locale_raii __current(uselocale(__l), uselocale);
 
284
  return wcrtomb(__s, __wc, __ps);
 
285
#endif
 
286
}
 
287
 
 
288
_LIBCPP_ALWAYS_INLINE inline
 
289
size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
 
290
                      size_t __len, mbstate_t *__ps, locale_t __l)
 
291
{
 
292
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
293
  return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);
 
294
#else
 
295
  __locale_raii __current(uselocale(__l), uselocale);
 
296
  return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
 
297
#endif
 
298
}
 
299
 
 
300
_LIBCPP_ALWAYS_INLINE inline
 
301
size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
 
302
                   mbstate_t *__ps, locale_t __l)
 
303
{
 
304
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
305
  return mbrtowc_l(__pwc, __s, __n, __ps, __l);
 
306
#else
 
307
  __locale_raii __current(uselocale(__l), uselocale);
 
308
  return mbrtowc(__pwc, __s, __n, __ps);
 
309
#endif
 
310
}
 
311
 
 
312
_LIBCPP_ALWAYS_INLINE inline
 
313
int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
 
314
{
 
315
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
316
  return mbtowc_l(__pwc, __pmb, __max, __l);
 
317
#else
 
318
  __locale_raii __current(uselocale(__l), uselocale);
 
319
  return mbtowc(__pwc, __pmb, __max);
 
320
#endif
 
321
}
 
322
 
 
323
_LIBCPP_ALWAYS_INLINE inline
 
324
size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
 
325
{
 
326
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
327
  return mbrlen_l(__s, __n, __ps, __l);
 
328
#else
 
329
  __locale_raii __current(uselocale(__l), uselocale);
 
330
  return mbrlen(__s, __n, __ps);
 
331
#endif
 
332
}
 
333
 
 
334
_LIBCPP_ALWAYS_INLINE inline
 
335
lconv *__localeconv_l(locale_t __l)
 
336
{
 
337
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
338
  return localeconv_l(__l);
 
339
#else
 
340
  __locale_raii __current(uselocale(__l), uselocale);
 
341
  return localeconv();
 
342
#endif
 
343
}
 
344
 
 
345
_LIBCPP_ALWAYS_INLINE inline
 
346
size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
 
347
                     mbstate_t *__ps, locale_t __l)
 
348
{
 
349
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
350
  return mbsrtowcs_l(__dest, __src, __len, __ps, __l);
 
351
#else
 
352
  __locale_raii __current(uselocale(__l), uselocale);
 
353
  return mbsrtowcs(__dest, __src, __len, __ps);
 
354
#endif
 
355
}
 
356
 
 
357
inline
 
358
int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) {
 
359
  va_list __va;
 
360
  va_start(__va, __format);
 
361
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
362
  int __res = vsprintf_l(__s, __l, __format, __va);
 
363
#else
 
364
  __locale_raii __current(uselocale(__l), uselocale);
 
365
  int __res = vsprintf(__s, __format, __va);
 
366
#endif
 
367
  va_end(__va);
 
368
  return __res;
 
369
}
 
370
 
 
371
inline
 
372
int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
 
373
  va_list __va;
 
374
  va_start(__va, __format);
 
375
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
376
  int __res = vsnprintf_l(__s, __n, __l, __format, __va);
 
377
#else
 
378
  __locale_raii __current(uselocale(__l), uselocale);
 
379
  int __res = vsnprintf(__s, __n, __format, __va);
 
380
#endif
 
381
  va_end(__va);
 
382
  return __res;
 
383
}
 
384
 
 
385
inline
 
386
int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
 
387
  va_list __va;
 
388
  va_start(__va, __format);
 
389
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
390
  int __res = vasprintf_l(__s, __l, __format, __va);
 
391
#else
 
392
  __locale_raii __current(uselocale(__l), uselocale);
 
393
  int __res = vasprintf(__s, __format, __va);
 
394
#endif
 
395
  va_end(__va);
 
396
  return __res;
 
397
}
 
398
 
 
399
inline
 
400
int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
 
401
  va_list __va;
 
402
  va_start(__va, __format);
 
403
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
404
  int __res = vsscanf_l(__s, __l, __format, __va);
 
405
#else
 
406
  __locale_raii __current(uselocale(__l), uselocale);
 
407
  int __res = vsscanf(__s, __format, __va);
 
408
#endif
 
409
  va_end(__va);
 
410
  return __res;
 
411
}
 
412
 
 
413
#endif  // __linux__
 
414
 
 
415
// __scan_keyword
 
416
// Scans [__b, __e) until a match is found in the basic_strings range
 
417
//  [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
 
418
//  __b will be incremented (visibly), consuming CharT until a match is found
 
419
//  or proved to not exist.  A keyword may be "", in which will match anything.
 
420
//  If one keyword is a prefix of another, and the next CharT in the input
 
421
//  might match another keyword, the algorithm will attempt to find the longest
 
422
//  matching keyword.  If the longer matching keyword ends up not matching, then
 
423
//  no keyword match is found.  If no keyword match is found, __ke is returned
 
424
//  and failbit is set in __err.
 
425
//  Else an iterator pointing to the matching keyword is found.  If more than
 
426
//  one keyword matches, an iterator to the first matching keyword is returned.
 
427
//  If on exit __b == __e, eofbit is set in __err.  If __case_senstive is false,
 
428
//  __ct is used to force to lower case before comparing characters.
 
429
//  Examples:
 
430
//  Keywords:  "a", "abb"
 
431
//  If the input is "a", the first keyword matches and eofbit is set.
 
432
//  If the input is "abc", no match is found and "ab" are consumed.
 
433
template <class _InputIterator, class _ForwardIterator, class _Ctype>
 
434
_LIBCPP_HIDDEN
 
435
_ForwardIterator
 
436
__scan_keyword(_InputIterator& __b, _InputIterator __e,
 
437
               _ForwardIterator __kb, _ForwardIterator __ke,
 
438
               const _Ctype& __ct, ios_base::iostate& __err,
 
439
               bool __case_sensitive = true)
 
440
{
 
441
    typedef typename iterator_traits<_InputIterator>::value_type _CharT;
 
442
    size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
 
443
    const unsigned char __doesnt_match = '\0';
 
444
    const unsigned char __might_match = '\1';
 
445
    const unsigned char __does_match = '\2';
 
446
    unsigned char __statbuf[100];
 
447
    unsigned char* __status = __statbuf;
 
448
    unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
 
449
    if (__nkw > sizeof(__statbuf))
 
450
    {
 
451
        __status = (unsigned char*)malloc(__nkw);
 
452
        if (__status == 0)
 
453
            __throw_bad_alloc();
 
454
        __stat_hold.reset(__status);
 
455
    }
 
456
    size_t __n_might_match = __nkw;  // At this point, any keyword might match
 
457
    size_t __n_does_match = 0;       // but none of them definitely do
 
458
    // Initialize all statuses to __might_match, except for "" keywords are __does_match
 
459
    unsigned char* __st = __status;
 
460
    for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
 
461
    {
 
462
        if (!__ky->empty())
 
463
            *__st = __might_match;
 
464
        else
 
465
        {
 
466
            *__st = __does_match;
 
467
            --__n_might_match;
 
468
            ++__n_does_match;
 
469
        }
 
470
    }
 
471
    // While there might be a match, test keywords against the next CharT
 
472
    for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
 
473
    {
 
474
        // Peek at the next CharT but don't consume it
 
475
        _CharT __c = *__b;
 
476
        if (!__case_sensitive)
 
477
            __c = __ct.toupper(__c);
 
478
        bool __consume = false;
 
479
        // For each keyword which might match, see if the __indx character is __c
 
480
        // If a match if found, consume __c
 
481
        // If a match is found, and that is the last character in the keyword,
 
482
        //    then that keyword matches.
 
483
        // If the keyword doesn't match this character, then change the keyword
 
484
        //    to doesn't match
 
485
        __st = __status;
 
486
        for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
 
487
        {
 
488
            if (*__st == __might_match)
 
489
            {
 
490
                _CharT __kc = (*__ky)[__indx];
 
491
                if (!__case_sensitive)
 
492
                    __kc = __ct.toupper(__kc);
 
493
                if (__c == __kc)
 
494
                {
 
495
                    __consume = true;
 
496
                    if (__ky->size() == __indx+1)
 
497
                    {
 
498
                        *__st = __does_match;
 
499
                        --__n_might_match;
 
500
                        ++__n_does_match;
 
501
                    }
 
502
                }
 
503
                else
 
504
                {
 
505
                    *__st = __doesnt_match;
 
506
                    --__n_might_match;
 
507
                }
 
508
            }
 
509
        }
 
510
        // consume if we matched a character
 
511
        if (__consume)
 
512
        {
 
513
            ++__b;
 
514
            // If we consumed a character and there might be a matched keyword that
 
515
            //   was marked matched on a previous iteration, then such keywords
 
516
            //   which are now marked as not matching.
 
517
            if (__n_might_match + __n_does_match > 1)
 
518
            {
 
519
                __st = __status;
 
520
                for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
 
521
                {
 
522
                    if (*__st == __does_match && __ky->size() != __indx+1)
 
523
                    {
 
524
                        *__st = __doesnt_match;
 
525
                        --__n_does_match;
 
526
                    }
 
527
                }
 
528
            }
 
529
        }
 
530
    }
 
531
    // We've exited the loop because we hit eof and/or we have no more "might matches".
 
532
    if (__b == __e)
 
533
        __err |= ios_base::eofbit;
 
534
    // Return the first matching result
 
535
    for (__st = __status; __kb != __ke; ++__kb, ++__st)
 
536
        if (*__st == __does_match)
 
537
            break;
 
538
    if (__kb == __ke)
 
539
        __err |= ios_base::failbit;
 
540
    return __kb;
 
541
}
 
542
 
 
543
struct __num_get_base
 
544
{
 
545
    static const int __num_get_buf_sz = 40;
 
546
 
 
547
    static int __get_base(ios_base&);
 
548
    static const char __src[33];
 
549
};
 
550
 
 
551
void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
 
552
                      ios_base::iostate& __err);
 
553
 
 
554
template <class _CharT>
 
555
struct __num_get
 
556
    : protected __num_get_base
 
557
{
 
558
    static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
 
559
    static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
 
560
                                      _CharT& __thousands_sep);
 
561
    static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
 
562
                  unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
 
563
                  unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
 
564
    static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
 
565
                                   char* __a, char*& __a_end,
 
566
                                   _CharT __decimal_point, _CharT __thousands_sep,
 
567
                                   const string& __grouping, unsigned* __g,
 
568
                                   unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
 
569
};
 
570
 
 
571
template <class _CharT>
 
572
string
 
573
__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
 
574
{
 
575
    locale __loc = __iob.getloc();
 
576
    use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
 
577
    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
 
578
    __thousands_sep = __np.thousands_sep();
 
579
    return __np.grouping();
 
580
}
 
581
 
 
582
template <class _CharT>
 
583
string
 
584
__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
 
585
                    _CharT& __thousands_sep)
 
586
{
 
587
    locale __loc = __iob.getloc();
 
588
    use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
 
589
    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
 
590
    __decimal_point = __np.decimal_point();
 
591
    __thousands_sep = __np.thousands_sep();
 
592
    return __np.grouping();
 
593
}
 
594
 
 
595
template <class _CharT>
 
596
int
 
597
__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
 
598
                  unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
 
599
                  unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
 
600
{
 
601
    if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
 
602
    {
 
603
        *__a_end++ = __ct == __atoms[24] ? '+' : '-';
 
604
        __dc = 0;
 
605
        return 0;
 
606
    }
 
607
    if (__grouping.size() != 0 && __ct == __thousands_sep)
 
608
    {
 
609
        if (__g_end-__g < __num_get_buf_sz)
 
610
        {
 
611
            *__g_end++ = __dc;
 
612
            __dc = 0;
 
613
        }
 
614
        return 0;
 
615
    }
 
616
    ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
 
617
    if (__f >= 24)
 
618
        return -1;
 
619
    switch (__base)
 
620
    {
 
621
    case 8:
 
622
    case 10:
 
623
        if (__f >= __base)
 
624
            return -1;
 
625
        break;
 
626
    case 16:
 
627
        if (__f < 22)
 
628
            break;
 
629
        if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
 
630
        {
 
631
            __dc = 0;
 
632
            *__a_end++ = __src[__f];
 
633
            return 0;
 
634
        }
 
635
        return -1;
 
636
    }
 
637
    if (__a_end-__a < __num_get_buf_sz - 1)
 
638
        *__a_end++ = __src[__f];
 
639
    ++__dc;
 
640
    return 0;
 
641
}
 
642
 
 
643
template <class _CharT>
 
644
int
 
645
__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
 
646
                    _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
 
647
                    unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
 
648
{
 
649
    if (__a_end-__a >= __num_get_buf_sz - 1)
 
650
        return -1;
 
651
    if (__ct == __decimal_point)
 
652
    {
 
653
        if (!__in_units)
 
654
            return -1;
 
655
        __in_units = false;
 
656
        *__a_end++ = '.';
 
657
        if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
 
658
            *__g_end++ = __dc;
 
659
        return 0;
 
660
    }
 
661
    if (__ct == __thousands_sep && __grouping.size() != 0)
 
662
    {
 
663
        if (!__in_units)
 
664
            return -1;
 
665
        if (__g_end-__g < __num_get_buf_sz)
 
666
        {
 
667
            *__g_end++ = __dc;
 
668
            __dc = 0;
 
669
        }
 
670
        return 0;
 
671
    }
 
672
    ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
 
673
    if (__f >= 32)
 
674
        return -1;
 
675
    char __x = __src[__f];
 
676
    if (__x == '-' || __x == '+')
 
677
    {
 
678
        if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
 
679
        {
 
680
            *__a_end++ = __x;
 
681
            return 0;
 
682
        }
 
683
        return -1;
 
684
    }
 
685
    if (__x == 'x' || __x == 'X')
 
686
        __exp = 'P';
 
687
    else if ((__x & 0x5F) == __exp)
 
688
    {
 
689
        __exp |= 0x80;
 
690
        if (__in_units)
 
691
        {
 
692
            __in_units = false;
 
693
            if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
 
694
                *__g_end++ = __dc;
 
695
        }
 
696
    }
 
697
    if (__a_end-__a < __num_get_buf_sz - ((__exp & 0x80) ? 1 : 11))
 
698
        *__a_end++ = __x;
 
699
    if (__f >= 22)
 
700
        return 0;
 
701
    ++__dc;
 
702
    return 0;
 
703
}
 
704
 
 
705
_LIBCPP_EXTERN_TEMPLATE(struct __num_get<char>)
 
706
_LIBCPP_EXTERN_TEMPLATE(struct __num_get<wchar_t>)
 
707
 
 
708
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
 
709
class _LIBCPP_TYPE_VIS num_get
 
710
    : public locale::facet,
 
711
      private __num_get<_CharT>
 
712
{
 
713
public:
 
714
    typedef _CharT char_type;
 
715
    typedef _InputIterator iter_type;
 
716
 
 
717
    _LIBCPP_ALWAYS_INLINE
 
718
    explicit num_get(size_t __refs = 0)
 
719
        : locale::facet(__refs) {}
 
720
 
 
721
    _LIBCPP_ALWAYS_INLINE
 
722
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
723
                  ios_base::iostate& __err, bool& __v) const
 
724
    {
 
725
        return do_get(__b, __e, __iob, __err, __v);
 
726
    }
 
727
 
 
728
    _LIBCPP_ALWAYS_INLINE
 
729
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
730
                  ios_base::iostate& __err, long& __v) const
 
731
    {
 
732
        return do_get(__b, __e, __iob, __err, __v);
 
733
    }
 
734
 
 
735
    _LIBCPP_ALWAYS_INLINE
 
736
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
737
                  ios_base::iostate& __err, long long& __v) const
 
738
    {
 
739
        return do_get(__b, __e, __iob, __err, __v);
 
740
    }
 
741
 
 
742
    _LIBCPP_ALWAYS_INLINE
 
743
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
744
                  ios_base::iostate& __err, unsigned short& __v) const
 
745
    {
 
746
        return do_get(__b, __e, __iob, __err, __v);
 
747
    }
 
748
 
 
749
    _LIBCPP_ALWAYS_INLINE
 
750
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
751
                  ios_base::iostate& __err, unsigned int& __v) const
 
752
    {
 
753
        return do_get(__b, __e, __iob, __err, __v);
 
754
    }
 
755
 
 
756
    _LIBCPP_ALWAYS_INLINE
 
757
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
758
                  ios_base::iostate& __err, unsigned long& __v) const
 
759
    {
 
760
        return do_get(__b, __e, __iob, __err, __v);
 
761
    }
 
762
 
 
763
    _LIBCPP_ALWAYS_INLINE
 
764
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
765
                  ios_base::iostate& __err, unsigned long long& __v) const
 
766
    {
 
767
        return do_get(__b, __e, __iob, __err, __v);
 
768
    }
 
769
 
 
770
    _LIBCPP_ALWAYS_INLINE
 
771
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
772
                  ios_base::iostate& __err, float& __v) const
 
773
    {
 
774
        return do_get(__b, __e, __iob, __err, __v);
 
775
    }
 
776
 
 
777
    _LIBCPP_ALWAYS_INLINE
 
778
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
779
                  ios_base::iostate& __err, double& __v) const
 
780
    {
 
781
        return do_get(__b, __e, __iob, __err, __v);
 
782
    }
 
783
 
 
784
    _LIBCPP_ALWAYS_INLINE
 
785
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
786
                  ios_base::iostate& __err, long double& __v) const
 
787
    {
 
788
        return do_get(__b, __e, __iob, __err, __v);
 
789
    }
 
790
 
 
791
    _LIBCPP_ALWAYS_INLINE
 
792
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
793
                  ios_base::iostate& __err, void*& __v) const
 
794
    {
 
795
        return do_get(__b, __e, __iob, __err, __v);
 
796
    }
 
797
 
 
798
    static locale::id id;
 
799
 
 
800
protected:
 
801
    _LIBCPP_ALWAYS_INLINE
 
802
    ~num_get() {}
 
803
 
 
804
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
805
                             ios_base::iostate& __err, bool& __v) const;
 
806
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
807
                             ios_base::iostate& __err, long& __v) const;
 
808
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
809
                             ios_base::iostate& __err, long long& __v) const;
 
810
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
811
                             ios_base::iostate& __err, unsigned short& __v) const;
 
812
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
813
                             ios_base::iostate& __err, unsigned int& __v) const;
 
814
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
815
                             ios_base::iostate& __err, unsigned long& __v) const;
 
816
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
817
                             ios_base::iostate& __err, unsigned long long& __v) const;
 
818
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
819
                             ios_base::iostate& __err, float& __v) const;
 
820
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
821
                             ios_base::iostate& __err, double& __v) const;
 
822
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
823
                             ios_base::iostate& __err, long double& __v) const;
 
824
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
825
                             ios_base::iostate& __err, void*& __v) const;
 
826
};
 
827
 
 
828
template <class _CharT, class _InputIterator>
 
829
locale::id
 
830
num_get<_CharT, _InputIterator>::id;
 
831
 
 
832
template <class _Tp>
 
833
_Tp
 
834
__num_get_signed_integral(const char* __a, const char* __a_end,
 
835
                          ios_base::iostate& __err, int __base)
 
836
{
 
837
    if (__a != __a_end)
 
838
    {
 
839
        typename remove_reference<decltype(errno)>::type __save_errno = errno;
 
840
        errno = 0;
 
841
        char *__p2;
 
842
        long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
 
843
        typename remove_reference<decltype(errno)>::type __current_errno = errno;
 
844
        if (__current_errno == 0)
 
845
            errno = __save_errno;
 
846
        if (__p2 != __a_end)
 
847
        {
 
848
            __err = ios_base::failbit;
 
849
            return 0;
 
850
        }
 
851
        else if (__current_errno == ERANGE         ||
 
852
                 __ll < numeric_limits<_Tp>::min() ||
 
853
                 numeric_limits<_Tp>::max() < __ll)
 
854
        {
 
855
            __err = ios_base::failbit;
 
856
            if (__ll > 0)
 
857
                return numeric_limits<_Tp>::max();
 
858
            else
 
859
                return numeric_limits<_Tp>::min();
 
860
        }
 
861
        return static_cast<_Tp>(__ll);
 
862
    }
 
863
    __err = ios_base::failbit;
 
864
    return 0;
 
865
}
 
866
 
 
867
template <class _Tp>
 
868
_Tp
 
869
__num_get_unsigned_integral(const char* __a, const char* __a_end,
 
870
                            ios_base::iostate& __err, int __base)
 
871
{
 
872
    if (__a != __a_end)
 
873
    {
 
874
        if (*__a == '-')
 
875
        {
 
876
            __err = ios_base::failbit;
 
877
            return 0;
 
878
        }
 
879
        typename remove_reference<decltype(errno)>::type __save_errno = errno;
 
880
        errno = 0;
 
881
        char *__p2;
 
882
        unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
 
883
        typename remove_reference<decltype(errno)>::type __current_errno = errno;
 
884
        if (__current_errno == 0)
 
885
            errno = __save_errno;
 
886
        if (__p2 != __a_end)
 
887
        {
 
888
            __err = ios_base::failbit;
 
889
            return 0;
 
890
        }
 
891
        else if (__current_errno == ERANGE ||
 
892
                 numeric_limits<_Tp>::max() < __ll)
 
893
        {
 
894
            __err = ios_base::failbit;
 
895
            return numeric_limits<_Tp>::max();
 
896
        }
 
897
        return static_cast<_Tp>(__ll);
 
898
    }
 
899
    __err = ios_base::failbit;
 
900
    return 0;
 
901
}
 
902
 
 
903
template <class _Tp>
 
904
_Tp
 
905
__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
 
906
{
 
907
    if (__a != __a_end)
 
908
    {
 
909
        char *__p2;
 
910
        long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
 
911
        if (__p2 != __a_end)
 
912
        {
 
913
            __err = ios_base::failbit;
 
914
            return 0;
 
915
        }
 
916
        return static_cast<_Tp>(__ld);
 
917
    }
 
918
    __err = ios_base::failbit;
 
919
    return 0;
 
920
}
 
921
 
 
922
template <class _CharT, class _InputIterator>
 
923
_InputIterator
 
924
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
925
                                        ios_base& __iob,
 
926
                                        ios_base::iostate& __err,
 
927
                                        bool& __v) const
 
928
{
 
929
    if ((__iob.flags() & ios_base::boolalpha) == 0)
 
930
    {
 
931
        long __lv = -1;
 
932
        __b = do_get(__b, __e, __iob, __err, __lv);
 
933
        switch (__lv)
 
934
        {
 
935
        case 0:
 
936
            __v = false;
 
937
            break;
 
938
        case 1:
 
939
            __v = true;
 
940
            break;
 
941
        default:
 
942
            __v = true;
 
943
            __err = ios_base::failbit;
 
944
            break;
 
945
        }
 
946
        return __b;
 
947
    }
 
948
    const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
 
949
    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
 
950
    typedef typename numpunct<_CharT>::string_type string_type;
 
951
    const string_type __names[2] = {__np.truename(), __np.falsename()};
 
952
    const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
 
953
                                            __ct, __err);
 
954
    __v = __i == __names;
 
955
    return __b;
 
956
}
 
957
 
 
958
template <class _CharT, class _InputIterator>
 
959
_InputIterator
 
960
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
961
                                        ios_base& __iob,
 
962
                                        ios_base::iostate& __err,
 
963
                                        long& __v) const
 
964
{
 
965
    // Stage 1
 
966
    int __base = this->__get_base(__iob);
 
967
    // Stage 2
 
968
    char_type __atoms[26];
 
969
    char_type __thousands_sep;
 
970
    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
 
971
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
972
    char* __a_end = __a;
 
973
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
974
    unsigned* __g_end = __g;
 
975
    unsigned __dc = 0;
 
976
    for (; __b != __e; ++__b)
 
977
        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
 
978
                                    __thousands_sep, __grouping, __g, __g_end,
 
979
                                    __atoms))
 
980
            break;
 
981
    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
982
        *__g_end++ = __dc;
 
983
    // Stage 3
 
984
    __v = __num_get_signed_integral<long>(__a, __a_end, __err, __base);
 
985
    // Digit grouping checked
 
986
    __check_grouping(__grouping, __g, __g_end, __err);
 
987
    // EOF checked
 
988
    if (__b == __e)
 
989
        __err |= ios_base::eofbit;
 
990
    return __b;
 
991
}
 
992
 
 
993
template <class _CharT, class _InputIterator>
 
994
_InputIterator
 
995
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
996
                                        ios_base& __iob,
 
997
                                        ios_base::iostate& __err,
 
998
                                        long long& __v) const
 
999
{
 
1000
    // Stage 1
 
1001
    int __base = this->__get_base(__iob);
 
1002
    // Stage 2
 
1003
    char_type __atoms[26];
 
1004
    char_type __thousands_sep;
 
1005
    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
 
1006
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1007
    char* __a_end = __a;
 
1008
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1009
    unsigned* __g_end = __g;
 
1010
    unsigned __dc = 0;
 
1011
    for (; __b != __e; ++__b)
 
1012
        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
 
1013
                                    __thousands_sep, __grouping, __g, __g_end,
 
1014
                                    __atoms))
 
1015
            break;
 
1016
    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
1017
        *__g_end++ = __dc;
 
1018
    // Stage 3
 
1019
    __v = __num_get_signed_integral<long long>(__a, __a_end, __err, __base);
 
1020
    // Digit grouping checked
 
1021
    __check_grouping(__grouping, __g, __g_end, __err);
 
1022
    // EOF checked
 
1023
    if (__b == __e)
 
1024
        __err |= ios_base::eofbit;
 
1025
    return __b;
 
1026
}
 
1027
 
 
1028
template <class _CharT, class _InputIterator>
 
1029
_InputIterator
 
1030
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
1031
                                        ios_base& __iob,
 
1032
                                        ios_base::iostate& __err,
 
1033
                                        unsigned short& __v) const
 
1034
{
 
1035
    // Stage 1
 
1036
    int __base = this->__get_base(__iob);
 
1037
    // Stage 2
 
1038
    char_type __atoms[26];
 
1039
    char_type __thousands_sep;
 
1040
    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
 
1041
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1042
    char* __a_end = __a;
 
1043
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1044
    unsigned* __g_end = __g;
 
1045
    unsigned __dc = 0;
 
1046
    for (; __b != __e; ++__b)
 
1047
        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
 
1048
                                    __thousands_sep, __grouping, __g, __g_end,
 
1049
                                    __atoms))
 
1050
            break;
 
1051
    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
1052
        *__g_end++ = __dc;
 
1053
    // Stage 3
 
1054
    __v = __num_get_unsigned_integral<unsigned short>(__a, __a_end, __err, __base);
 
1055
    // Digit grouping checked
 
1056
    __check_grouping(__grouping, __g, __g_end, __err);
 
1057
    // EOF checked
 
1058
    if (__b == __e)
 
1059
        __err |= ios_base::eofbit;
 
1060
    return __b;
 
1061
}
 
1062
 
 
1063
template <class _CharT, class _InputIterator>
 
1064
_InputIterator
 
1065
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
1066
                                        ios_base& __iob,
 
1067
                                        ios_base::iostate& __err,
 
1068
                                        unsigned int& __v) const
 
1069
{
 
1070
    // Stage 1
 
1071
    int __base = this->__get_base(__iob);
 
1072
    // Stage 2
 
1073
    char_type __atoms[26];
 
1074
    char_type __thousands_sep;
 
1075
    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
 
1076
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1077
    char* __a_end = __a;
 
1078
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1079
    unsigned* __g_end = __g;
 
1080
    unsigned __dc = 0;
 
1081
    for (; __b != __e; ++__b)
 
1082
        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
 
1083
                                    __thousands_sep, __grouping, __g, __g_end,
 
1084
                                    __atoms))
 
1085
            break;
 
1086
    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
1087
        *__g_end++ = __dc;
 
1088
    // Stage 3
 
1089
    __v = __num_get_unsigned_integral<unsigned int>(__a, __a_end, __err, __base);
 
1090
    // Digit grouping checked
 
1091
    __check_grouping(__grouping, __g, __g_end, __err);
 
1092
    // EOF checked
 
1093
    if (__b == __e)
 
1094
        __err |= ios_base::eofbit;
 
1095
    return __b;
 
1096
}
 
1097
 
 
1098
template <class _CharT, class _InputIterator>
 
1099
_InputIterator
 
1100
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
1101
                                        ios_base& __iob,
 
1102
                                        ios_base::iostate& __err,
 
1103
                                        unsigned long& __v) const
 
1104
{
 
1105
    // Stage 1
 
1106
    int __base = this->__get_base(__iob);
 
1107
    // Stage 2
 
1108
    char_type __atoms[26];
 
1109
    char_type __thousands_sep;
 
1110
    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
 
1111
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1112
    char* __a_end = __a;
 
1113
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1114
    unsigned* __g_end = __g;
 
1115
    unsigned __dc = 0;
 
1116
    for (; __b != __e; ++__b)
 
1117
        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
 
1118
                                    __thousands_sep, __grouping, __g, __g_end,
 
1119
                                    __atoms))
 
1120
            break;
 
1121
    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
1122
        *__g_end++ = __dc;
 
1123
    // Stage 3
 
1124
    __v = __num_get_unsigned_integral<unsigned long>(__a, __a_end, __err, __base);
 
1125
    // Digit grouping checked
 
1126
    __check_grouping(__grouping, __g, __g_end, __err);
 
1127
    // EOF checked
 
1128
    if (__b == __e)
 
1129
        __err |= ios_base::eofbit;
 
1130
    return __b;
 
1131
}
 
1132
 
 
1133
template <class _CharT, class _InputIterator>
 
1134
_InputIterator
 
1135
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
1136
                                        ios_base& __iob,
 
1137
                                        ios_base::iostate& __err,
 
1138
                                        unsigned long long& __v) const
 
1139
{
 
1140
    // Stage 1
 
1141
    int __base = this->__get_base(__iob);
 
1142
    // Stage 2
 
1143
    char_type __atoms[26];
 
1144
    char_type __thousands_sep;
 
1145
    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
 
1146
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1147
    char* __a_end = __a;
 
1148
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1149
    unsigned* __g_end = __g;
 
1150
    unsigned __dc = 0;
 
1151
    for (; __b != __e; ++__b)
 
1152
        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
 
1153
                                    __thousands_sep, __grouping, __g, __g_end,
 
1154
                                    __atoms))
 
1155
            break;
 
1156
    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
1157
        *__g_end++ = __dc;
 
1158
    // Stage 3
 
1159
    __v = __num_get_unsigned_integral<unsigned long long>(__a, __a_end, __err, __base);
 
1160
    // Digit grouping checked
 
1161
    __check_grouping(__grouping, __g, __g_end, __err);
 
1162
    // EOF checked
 
1163
    if (__b == __e)
 
1164
        __err |= ios_base::eofbit;
 
1165
    return __b;
 
1166
}
 
1167
 
 
1168
template <class _CharT, class _InputIterator>
 
1169
_InputIterator
 
1170
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
1171
                                        ios_base& __iob,
 
1172
                                        ios_base::iostate& __err,
 
1173
                                        float& __v) const
 
1174
{
 
1175
    // Stage 1, nothing to do
 
1176
    // Stage 2
 
1177
    char_type __atoms[32];
 
1178
    char_type __decimal_point;
 
1179
    char_type __thousands_sep;
 
1180
    string __grouping = this->__stage2_float_prep(__iob, __atoms,
 
1181
                                                  __decimal_point,
 
1182
                                                  __thousands_sep);
 
1183
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1184
    char* __a_end = __a;
 
1185
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1186
    unsigned* __g_end = __g;
 
1187
    unsigned __dc = 0;
 
1188
    bool __in_units = true;
 
1189
    char __exp = 'E';
 
1190
    for (; __b != __e; ++__b)
 
1191
        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
 
1192
                                      __decimal_point, __thousands_sep,
 
1193
                                      __grouping, __g, __g_end,
 
1194
                                      __dc, __atoms))
 
1195
            break;
 
1196
    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
1197
        *__g_end++ = __dc;
 
1198
    // Stage 3
 
1199
    __v = __num_get_float<float>(__a, __a_end, __err);
 
1200
    // Digit grouping checked
 
1201
    __check_grouping(__grouping, __g, __g_end, __err);
 
1202
    // EOF checked
 
1203
    if (__b == __e)
 
1204
        __err |= ios_base::eofbit;
 
1205
    return __b;
 
1206
}
 
1207
 
 
1208
template <class _CharT, class _InputIterator>
 
1209
_InputIterator
 
1210
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
1211
                                        ios_base& __iob,
 
1212
                                        ios_base::iostate& __err,
 
1213
                                        double& __v) const
 
1214
{
 
1215
    // Stage 1, nothing to do
 
1216
    // Stage 2
 
1217
    char_type __atoms[32];
 
1218
    char_type __decimal_point;
 
1219
    char_type __thousands_sep;
 
1220
    string __grouping = this->__stage2_float_prep(__iob, __atoms,
 
1221
                                                  __decimal_point,
 
1222
                                                  __thousands_sep);
 
1223
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1224
    char* __a_end = __a;
 
1225
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1226
    unsigned* __g_end = __g;
 
1227
    unsigned __dc = 0;
 
1228
    bool __in_units = true;
 
1229
    char __exp = 'E';
 
1230
    for (; __b != __e; ++__b)
 
1231
        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
 
1232
                                      __decimal_point, __thousands_sep,
 
1233
                                      __grouping, __g, __g_end,
 
1234
                                      __dc, __atoms))
 
1235
            break;
 
1236
    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
1237
        *__g_end++ = __dc;
 
1238
    // Stage 3
 
1239
    __v = __num_get_float<double>(__a, __a_end, __err);
 
1240
    // Digit grouping checked
 
1241
    __check_grouping(__grouping, __g, __g_end, __err);
 
1242
    // EOF checked
 
1243
    if (__b == __e)
 
1244
        __err |= ios_base::eofbit;
 
1245
    return __b;
 
1246
}
 
1247
 
 
1248
template <class _CharT, class _InputIterator>
 
1249
_InputIterator
 
1250
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
1251
                                        ios_base& __iob,
 
1252
                                        ios_base::iostate& __err,
 
1253
                                        long double& __v) const
 
1254
{
 
1255
    // Stage 1, nothing to do
 
1256
    // Stage 2
 
1257
    char_type __atoms[32];
 
1258
    char_type __decimal_point;
 
1259
    char_type __thousands_sep;
 
1260
    string __grouping = this->__stage2_float_prep(__iob, __atoms,
 
1261
                                                  __decimal_point,
 
1262
                                                  __thousands_sep);
 
1263
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1264
    char* __a_end = __a;
 
1265
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1266
    unsigned* __g_end = __g;
 
1267
    unsigned __dc = 0;
 
1268
    bool __in_units = true;
 
1269
    char __exp = 'E';
 
1270
    for (; __b != __e; ++__b)
 
1271
        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
 
1272
                                      __decimal_point, __thousands_sep,
 
1273
                                      __grouping, __g, __g_end,
 
1274
                                      __dc, __atoms))
 
1275
            break;
 
1276
    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
 
1277
        *__g_end++ = __dc;
 
1278
    // Stage 3
 
1279
    __v = __num_get_float<long double>(__a, __a_end, __err);
 
1280
    // Digit grouping checked
 
1281
    __check_grouping(__grouping, __g, __g_end, __err);
 
1282
    // EOF checked
 
1283
    if (__b == __e)
 
1284
        __err |= ios_base::eofbit;
 
1285
    return __b;
 
1286
}
 
1287
 
 
1288
template <class _CharT, class _InputIterator>
 
1289
_InputIterator
 
1290
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
1291
                                        ios_base& __iob,
 
1292
                                        ios_base::iostate& __err,
 
1293
                                        void*& __v) const
 
1294
{
 
1295
    // Stage 1
 
1296
    int __base = 16;
 
1297
    // Stage 2
 
1298
    char_type __atoms[26];
 
1299
    char_type __thousands_sep = 0;
 
1300
    string __grouping;
 
1301
    use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
 
1302
                                                    __num_get_base::__src + 26, __atoms);
 
1303
    char __a[__num_get_base::__num_get_buf_sz] = {0};
 
1304
    char* __a_end = __a;
 
1305
    unsigned __g[__num_get_base::__num_get_buf_sz];
 
1306
    unsigned* __g_end = __g;
 
1307
    unsigned __dc = 0;
 
1308
    for (; __b != __e; ++__b)
 
1309
        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
 
1310
                                    __thousands_sep, __grouping,
 
1311
                                    __g, __g_end, __atoms))
 
1312
            break;
 
1313
    // Stage 3
 
1314
    __a[sizeof(__a)-1] = 0;
 
1315
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1316
    if (sscanf_l(__a, _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
 
1317
#else
 
1318
    if (__sscanf_l(__a, __cloc(), "%p", &__v) != 1)
 
1319
#endif
 
1320
        __err = ios_base::failbit;
 
1321
    // EOF checked
 
1322
    if (__b == __e)
 
1323
        __err |= ios_base::eofbit;
 
1324
    return __b;
 
1325
}
 
1326
 
 
1327
_LIBCPP_EXTERN_TEMPLATE(class num_get<char>)
 
1328
_LIBCPP_EXTERN_TEMPLATE(class num_get<wchar_t>)
 
1329
 
 
1330
struct __num_put_base
 
1331
{
 
1332
protected:
 
1333
    static void __format_int(char* __fmt, const char* __len, bool __signd,
 
1334
                             ios_base::fmtflags __flags);
 
1335
    static bool __format_float(char* __fmt, const char* __len,
 
1336
                               ios_base::fmtflags __flags);
 
1337
    static char* __identify_padding(char* __nb, char* __ne,
 
1338
                                    const ios_base& __iob);
 
1339
};
 
1340
 
 
1341
template <class _CharT>
 
1342
struct __num_put
 
1343
    : protected __num_put_base
 
1344
{
 
1345
    static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
 
1346
                                      _CharT* __ob, _CharT*& __op, _CharT*& __oe,
 
1347
                                      const locale& __loc);
 
1348
    static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
 
1349
                                        _CharT* __ob, _CharT*& __op, _CharT*& __oe,
 
1350
                                        const locale& __loc);
 
1351
};
 
1352
 
 
1353
template <class _CharT>
 
1354
void
 
1355
__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
 
1356
                                         _CharT* __ob, _CharT*& __op, _CharT*& __oe,
 
1357
                                         const locale& __loc)
 
1358
{
 
1359
    const ctype<_CharT>&    __ct = use_facet<ctype<_CharT> >   (__loc);
 
1360
    const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
 
1361
    string __grouping = __npt.grouping();
 
1362
    if (__grouping.empty())
 
1363
    {
 
1364
        __ct.widen(__nb, __ne, __ob);
 
1365
        __oe = __ob + (__ne - __nb);
 
1366
    }
 
1367
    else
 
1368
    {
 
1369
        __oe = __ob;
 
1370
        char* __nf = __nb;
 
1371
        if (*__nf == '-' || *__nf == '+')
 
1372
            *__oe++ = __ct.widen(*__nf++);
 
1373
        if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
 
1374
                                                   __nf[1] == 'X'))
 
1375
        {
 
1376
            *__oe++ = __ct.widen(*__nf++);
 
1377
            *__oe++ = __ct.widen(*__nf++);
 
1378
        }
 
1379
        reverse(__nf, __ne);
 
1380
        _CharT __thousands_sep = __npt.thousands_sep();
 
1381
        unsigned __dc = 0;
 
1382
        unsigned __dg = 0;
 
1383
        for (char* __p = __nf; __p < __ne; ++__p)
 
1384
        {
 
1385
            if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
 
1386
                __dc == static_cast<unsigned>(__grouping[__dg]))
 
1387
            {
 
1388
                *__oe++ = __thousands_sep;
 
1389
                __dc = 0;
 
1390
                if (__dg < __grouping.size()-1)
 
1391
                    ++__dg;
 
1392
            }
 
1393
            *__oe++ = __ct.widen(*__p);
 
1394
            ++__dc;
 
1395
        }
 
1396
        reverse(__ob + (__nf - __nb), __oe);
 
1397
    }
 
1398
    if (__np == __ne)
 
1399
        __op = __oe;
 
1400
    else
 
1401
        __op = __ob + (__np - __nb);
 
1402
}
 
1403
 
 
1404
template <class _CharT>
 
1405
void
 
1406
__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
 
1407
                                           _CharT* __ob, _CharT*& __op, _CharT*& __oe,
 
1408
                                           const locale& __loc)
 
1409
{
 
1410
    const ctype<_CharT>&    __ct = use_facet<ctype<_CharT> >   (__loc);
 
1411
    const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
 
1412
    string __grouping = __npt.grouping();
 
1413
    __oe = __ob;
 
1414
    char* __nf = __nb;
 
1415
    if (*__nf == '-' || *__nf == '+')
 
1416
        *__oe++ = __ct.widen(*__nf++);
 
1417
    char* __ns;
 
1418
    if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
 
1419
                                               __nf[1] == 'X'))
 
1420
    {
 
1421
        *__oe++ = __ct.widen(*__nf++);
 
1422
        *__oe++ = __ct.widen(*__nf++);
 
1423
        for (__ns = __nf; __ns < __ne; ++__ns)
 
1424
            if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
 
1425
                break;
 
1426
    }
 
1427
    else
 
1428
    {
 
1429
        for (__ns = __nf; __ns < __ne; ++__ns)
 
1430
            if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
 
1431
                break;
 
1432
    }
 
1433
    if (__grouping.empty())
 
1434
    {
 
1435
        __ct.widen(__nf, __ns, __oe);
 
1436
        __oe += __ns - __nf;
 
1437
    }
 
1438
    else
 
1439
    {
 
1440
        reverse(__nf, __ns);
 
1441
        _CharT __thousands_sep = __npt.thousands_sep();
 
1442
        unsigned __dc = 0;
 
1443
        unsigned __dg = 0;
 
1444
        for (char* __p = __nf; __p < __ns; ++__p)
 
1445
        {
 
1446
            if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
 
1447
            {
 
1448
                *__oe++ = __thousands_sep;
 
1449
                __dc = 0;
 
1450
                if (__dg < __grouping.size()-1)
 
1451
                    ++__dg;
 
1452
            }
 
1453
            *__oe++ = __ct.widen(*__p);
 
1454
            ++__dc;
 
1455
        }
 
1456
        reverse(__ob + (__nf - __nb), __oe);
 
1457
    }
 
1458
    for (__nf = __ns; __nf < __ne; ++__nf)
 
1459
    {
 
1460
        if (*__nf == '.')
 
1461
        {
 
1462
            *__oe++ = __npt.decimal_point();
 
1463
            ++__nf;
 
1464
            break;
 
1465
        }
 
1466
        else
 
1467
            *__oe++ = __ct.widen(*__nf);
 
1468
    }
 
1469
    __ct.widen(__nf, __ne, __oe);
 
1470
    __oe += __ne - __nf;
 
1471
    if (__np == __ne)
 
1472
        __op = __oe;
 
1473
    else
 
1474
        __op = __ob + (__np - __nb);
 
1475
}
 
1476
 
 
1477
_LIBCPP_EXTERN_TEMPLATE(struct __num_put<char>)
 
1478
_LIBCPP_EXTERN_TEMPLATE(struct __num_put<wchar_t>)
 
1479
 
 
1480
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
 
1481
class _LIBCPP_TYPE_VIS num_put
 
1482
    : public locale::facet,
 
1483
      private __num_put<_CharT>
 
1484
{
 
1485
public:
 
1486
    typedef _CharT char_type;
 
1487
    typedef _OutputIterator iter_type;
 
1488
 
 
1489
    _LIBCPP_ALWAYS_INLINE
 
1490
    explicit num_put(size_t __refs = 0)
 
1491
        : locale::facet(__refs) {}
 
1492
 
 
1493
    _LIBCPP_ALWAYS_INLINE
 
1494
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
1495
                  bool __v) const
 
1496
    {
 
1497
        return do_put(__s, __iob, __fl, __v);
 
1498
    }
 
1499
 
 
1500
    _LIBCPP_ALWAYS_INLINE
 
1501
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
1502
                  long __v) const
 
1503
    {
 
1504
        return do_put(__s, __iob, __fl, __v);
 
1505
    }
 
1506
 
 
1507
    _LIBCPP_ALWAYS_INLINE
 
1508
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
1509
                  long long __v) const
 
1510
    {
 
1511
        return do_put(__s, __iob, __fl, __v);
 
1512
    }
 
1513
 
 
1514
    _LIBCPP_ALWAYS_INLINE
 
1515
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
1516
                  unsigned long __v) const
 
1517
    {
 
1518
        return do_put(__s, __iob, __fl, __v);
 
1519
    }
 
1520
 
 
1521
    _LIBCPP_ALWAYS_INLINE
 
1522
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
1523
                  unsigned long long __v) const
 
1524
    {
 
1525
        return do_put(__s, __iob, __fl, __v);
 
1526
    }
 
1527
 
 
1528
    _LIBCPP_ALWAYS_INLINE
 
1529
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
1530
                  double __v) const
 
1531
    {
 
1532
        return do_put(__s, __iob, __fl, __v);
 
1533
    }
 
1534
 
 
1535
    _LIBCPP_ALWAYS_INLINE
 
1536
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
1537
                  long double __v) const
 
1538
    {
 
1539
        return do_put(__s, __iob, __fl, __v);
 
1540
    }
 
1541
 
 
1542
    _LIBCPP_ALWAYS_INLINE
 
1543
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
1544
                  const void* __v) const
 
1545
    {
 
1546
        return do_put(__s, __iob, __fl, __v);
 
1547
    }
 
1548
 
 
1549
    static locale::id id;
 
1550
 
 
1551
protected:
 
1552
    _LIBCPP_ALWAYS_INLINE
 
1553
    ~num_put() {}
 
1554
 
 
1555
    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
 
1556
                             bool __v) const;
 
1557
    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
 
1558
                             long __v) const;
 
1559
    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
 
1560
                             long long __v) const;
 
1561
    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
 
1562
                             unsigned long) const;
 
1563
    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
 
1564
                             unsigned long long) const;
 
1565
    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
 
1566
                             double __v) const;
 
1567
    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
 
1568
                             long double __v) const;
 
1569
    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
 
1570
                             const void* __v) const;
 
1571
};
 
1572
 
 
1573
template <class _CharT, class _OutputIterator>
 
1574
locale::id
 
1575
num_put<_CharT, _OutputIterator>::id;
 
1576
 
 
1577
template <class _CharT, class _OutputIterator>
 
1578
_LIBCPP_HIDDEN
 
1579
_OutputIterator
 
1580
__pad_and_output(_OutputIterator __s,
 
1581
                 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
 
1582
                 ios_base& __iob, _CharT __fl)
 
1583
{
 
1584
    streamsize __sz = __oe - __ob;
 
1585
    streamsize __ns = __iob.width();
 
1586
    if (__ns > __sz)
 
1587
        __ns -= __sz;
 
1588
    else
 
1589
        __ns = 0;
 
1590
    for (;__ob < __op; ++__ob, ++__s)
 
1591
        *__s = *__ob;
 
1592
    for (; __ns; --__ns, ++__s)
 
1593
        *__s = __fl;
 
1594
    for (; __ob < __oe; ++__ob, ++__s)
 
1595
        *__s = *__ob;
 
1596
    __iob.width(0);
 
1597
    return __s;
 
1598
}
 
1599
 
 
1600
#if !defined(__APPLE__) || \
 
1601
    (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
 
1602
    (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
 
1603
 
 
1604
template <class _CharT, class _Traits>
 
1605
_LIBCPP_HIDDEN
 
1606
ostreambuf_iterator<_CharT, _Traits>
 
1607
__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
 
1608
                 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
 
1609
                 ios_base& __iob, _CharT __fl)
 
1610
{
 
1611
    if (__s.__sbuf_ == nullptr)
 
1612
        return __s;
 
1613
    streamsize __sz = __oe - __ob;
 
1614
    streamsize __ns = __iob.width();
 
1615
    if (__ns > __sz)
 
1616
        __ns -= __sz;
 
1617
    else
 
1618
        __ns = 0;
 
1619
    streamsize __np = __op - __ob;
 
1620
    if (__np > 0)
 
1621
    {
 
1622
        if (__s.__sbuf_->sputn(__ob, __np) != __np)
 
1623
        {
 
1624
            __s.__sbuf_ = nullptr;
 
1625
            return __s;
 
1626
        }
 
1627
    }
 
1628
    if (__ns > 0)
 
1629
    {
 
1630
        basic_string<_CharT, _Traits> __sp(__ns, __fl);
 
1631
        if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
 
1632
        {
 
1633
            __s.__sbuf_ = nullptr;
 
1634
            return __s;
 
1635
        }
 
1636
    }
 
1637
    __np = __oe - __op;
 
1638
    if (__np > 0)
 
1639
    {
 
1640
        if (__s.__sbuf_->sputn(__op, __np) != __np)
 
1641
        {
 
1642
            __s.__sbuf_ = nullptr;
 
1643
            return __s;
 
1644
        }
 
1645
    }
 
1646
    __iob.width(0);
 
1647
    return __s;
 
1648
}
 
1649
 
 
1650
#endif
 
1651
 
 
1652
template <class _CharT, class _OutputIterator>
 
1653
_OutputIterator
 
1654
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
 
1655
                                         char_type __fl, bool __v) const
 
1656
{
 
1657
    if ((__iob.flags() & ios_base::boolalpha) == 0)
 
1658
        return do_put(__s, __iob, __fl, (unsigned long)__v);
 
1659
    const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
 
1660
    typedef typename numpunct<char_type>::string_type string_type;
 
1661
    string_type __nm = __v ? __np.truename() : __np.falsename();
 
1662
    for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
 
1663
        *__s = *__i;
 
1664
    return __s;
 
1665
}
 
1666
 
 
1667
template <class _CharT, class _OutputIterator>
 
1668
_OutputIterator
 
1669
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
 
1670
                                         char_type __fl, long __v) const
 
1671
{
 
1672
    // Stage 1 - Get number in narrow char
 
1673
    char __fmt[6] = {'%', 0};
 
1674
    const char* __len = "l";
 
1675
    this->__format_int(__fmt+1, __len, true, __iob.flags());
 
1676
    const unsigned __nbuf = (numeric_limits<long>::digits / 3)
 
1677
                          + ((numeric_limits<long>::digits % 3) != 0)
 
1678
                          + 1;
 
1679
    char __nar[__nbuf];
 
1680
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1681
    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1682
#else
 
1683
    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
 
1684
#endif
 
1685
    char* __ne = __nar + __nc;
 
1686
    char* __np = this->__identify_padding(__nar, __ne, __iob);
 
1687
    // Stage 2 - Widen __nar while adding thousands separators
 
1688
    char_type __o[2*(__nbuf-1) - 1];
 
1689
    char_type* __op;  // pad here
 
1690
    char_type* __oe;  // end of output
 
1691
    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
 
1692
    // [__o, __oe) contains thousands_sep'd wide number
 
1693
    // Stage 3 & 4
 
1694
    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
 
1695
}
 
1696
 
 
1697
template <class _CharT, class _OutputIterator>
 
1698
_OutputIterator
 
1699
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
 
1700
                                         char_type __fl, long long __v) const
 
1701
{
 
1702
    // Stage 1 - Get number in narrow char
 
1703
    char __fmt[8] = {'%', 0};
 
1704
    const char* __len = "ll";
 
1705
    this->__format_int(__fmt+1, __len, true, __iob.flags());
 
1706
    const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
 
1707
                          + ((numeric_limits<long long>::digits % 3) != 0)
 
1708
                          + 1;
 
1709
    char __nar[__nbuf];
 
1710
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1711
    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1712
#else
 
1713
    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
 
1714
#endif
 
1715
    char* __ne = __nar + __nc;
 
1716
    char* __np = this->__identify_padding(__nar, __ne, __iob);
 
1717
    // Stage 2 - Widen __nar while adding thousands separators
 
1718
    char_type __o[2*(__nbuf-1) - 1];
 
1719
    char_type* __op;  // pad here
 
1720
    char_type* __oe;  // end of output
 
1721
    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
 
1722
    // [__o, __oe) contains thousands_sep'd wide number
 
1723
    // Stage 3 & 4
 
1724
    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
 
1725
}
 
1726
 
 
1727
template <class _CharT, class _OutputIterator>
 
1728
_OutputIterator
 
1729
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
 
1730
                                         char_type __fl, unsigned long __v) const
 
1731
{
 
1732
    // Stage 1 - Get number in narrow char
 
1733
    char __fmt[6] = {'%', 0};
 
1734
    const char* __len = "l";
 
1735
    this->__format_int(__fmt+1, __len, false, __iob.flags());
 
1736
    const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
 
1737
                          + ((numeric_limits<unsigned long>::digits % 3) != 0)
 
1738
                          + 1;
 
1739
    char __nar[__nbuf];
 
1740
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1741
    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1742
#else
 
1743
    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
 
1744
#endif
 
1745
    char* __ne = __nar + __nc;
 
1746
    char* __np = this->__identify_padding(__nar, __ne, __iob);
 
1747
    // Stage 2 - Widen __nar while adding thousands separators
 
1748
    char_type __o[2*(__nbuf-1) - 1];
 
1749
    char_type* __op;  // pad here
 
1750
    char_type* __oe;  // end of output
 
1751
    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
 
1752
    // [__o, __oe) contains thousands_sep'd wide number
 
1753
    // Stage 3 & 4
 
1754
    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
 
1755
}
 
1756
 
 
1757
template <class _CharT, class _OutputIterator>
 
1758
_OutputIterator
 
1759
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
 
1760
                                         char_type __fl, unsigned long long __v) const
 
1761
{
 
1762
    // Stage 1 - Get number in narrow char
 
1763
    char __fmt[8] = {'%', 0};
 
1764
    const char* __len = "ll";
 
1765
    this->__format_int(__fmt+1, __len, false, __iob.flags());
 
1766
    const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
 
1767
                          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
 
1768
                          + 1;
 
1769
    char __nar[__nbuf];
 
1770
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1771
    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1772
#else
 
1773
    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
 
1774
#endif
 
1775
    char* __ne = __nar + __nc;
 
1776
    char* __np = this->__identify_padding(__nar, __ne, __iob);
 
1777
    // Stage 2 - Widen __nar while adding thousands separators
 
1778
    char_type __o[2*(__nbuf-1) - 1];
 
1779
    char_type* __op;  // pad here
 
1780
    char_type* __oe;  // end of output
 
1781
    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
 
1782
    // [__o, __oe) contains thousands_sep'd wide number
 
1783
    // Stage 3 & 4
 
1784
    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
 
1785
}
 
1786
 
 
1787
template <class _CharT, class _OutputIterator>
 
1788
_OutputIterator
 
1789
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
 
1790
                                         char_type __fl, double __v) const
 
1791
{
 
1792
    // Stage 1 - Get number in narrow char
 
1793
    char __fmt[8] = {'%', 0};
 
1794
    const char* __len = "";
 
1795
    bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
 
1796
    const unsigned __nbuf = 30;
 
1797
    char __nar[__nbuf];
 
1798
    char* __nb = __nar;
 
1799
    int __nc;
 
1800
    if (__specify_precision)
 
1801
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1802
        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
 
1803
                                   (int)__iob.precision(), __v);
 
1804
#else
 
1805
        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
 
1806
                            (int)__iob.precision(), __v);
 
1807
#endif
 
1808
    else
 
1809
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1810
        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1811
#else
 
1812
        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
 
1813
#endif
 
1814
    unique_ptr<char, void(*)(void*)> __nbh(0, free);
 
1815
    if (__nc > static_cast<int>(__nbuf-1))
 
1816
    {
 
1817
        if (__specify_precision)
 
1818
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1819
            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
 
1820
#else
 
1821
            __nc = __asprintf_l(&__nb, __cloc(), __fmt,
 
1822
                              (int)__iob.precision(), __v);
 
1823
#endif
 
1824
        else
 
1825
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1826
            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1827
#else
 
1828
            __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
 
1829
#endif
 
1830
        if (__nb == 0)
 
1831
            __throw_bad_alloc();
 
1832
        __nbh.reset(__nb);
 
1833
    }
 
1834
    char* __ne = __nb + __nc;
 
1835
    char* __np = this->__identify_padding(__nb, __ne, __iob);
 
1836
    // Stage 2 - Widen __nar while adding thousands separators
 
1837
    char_type __o[2*(__nbuf-1) - 1];
 
1838
    char_type* __ob = __o;
 
1839
    unique_ptr<char_type, void(*)(void*)> __obh(0, free);
 
1840
    if (__nb != __nar)
 
1841
    {
 
1842
        __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
 
1843
        if (__ob == 0)
 
1844
            __throw_bad_alloc();
 
1845
        __obh.reset(__ob);
 
1846
    }
 
1847
    char_type* __op;  // pad here
 
1848
    char_type* __oe;  // end of output
 
1849
    this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
 
1850
    // [__o, __oe) contains thousands_sep'd wide number
 
1851
    // Stage 3 & 4
 
1852
    __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
 
1853
    return __s;
 
1854
}
 
1855
 
 
1856
template <class _CharT, class _OutputIterator>
 
1857
_OutputIterator
 
1858
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
 
1859
                                         char_type __fl, long double __v) const
 
1860
{
 
1861
    // Stage 1 - Get number in narrow char
 
1862
    char __fmt[8] = {'%', 0};
 
1863
    const char* __len = "L";
 
1864
    bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
 
1865
    const unsigned __nbuf = 30;
 
1866
    char __nar[__nbuf];
 
1867
    char* __nb = __nar;
 
1868
    int __nc;
 
1869
    if (__specify_precision)
 
1870
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1871
        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
 
1872
                                   (int)__iob.precision(), __v);
 
1873
#else
 
1874
        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
 
1875
                            (int)__iob.precision(), __v);
 
1876
#endif
 
1877
    else
 
1878
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1879
        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1880
#else
 
1881
        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
 
1882
#endif
 
1883
    unique_ptr<char, void(*)(void*)> __nbh(0, free);
 
1884
    if (__nc > static_cast<int>(__nbuf-1))
 
1885
    {
 
1886
        if (__specify_precision)
 
1887
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1888
            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
 
1889
#else
 
1890
            __nc = __asprintf_l(&__nb, __cloc(), __fmt,
 
1891
                              (int)__iob.precision(), __v);
 
1892
#endif
 
1893
        else
 
1894
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1895
            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1896
#else
 
1897
            __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
 
1898
#endif
 
1899
        if (__nb == 0)
 
1900
            __throw_bad_alloc();
 
1901
        __nbh.reset(__nb);
 
1902
    }
 
1903
    char* __ne = __nb + __nc;
 
1904
    char* __np = this->__identify_padding(__nb, __ne, __iob);
 
1905
    // Stage 2 - Widen __nar while adding thousands separators
 
1906
    char_type __o[2*(__nbuf-1) - 1];
 
1907
    char_type* __ob = __o;
 
1908
    unique_ptr<char_type, void(*)(void*)> __obh(0, free);
 
1909
    if (__nb != __nar)
 
1910
    {
 
1911
        __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
 
1912
        if (__ob == 0)
 
1913
            __throw_bad_alloc();
 
1914
        __obh.reset(__ob);
 
1915
    }
 
1916
    char_type* __op;  // pad here
 
1917
    char_type* __oe;  // end of output
 
1918
    this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
 
1919
    // [__o, __oe) contains thousands_sep'd wide number
 
1920
    // Stage 3 & 4
 
1921
    __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
 
1922
    return __s;
 
1923
}
 
1924
 
 
1925
template <class _CharT, class _OutputIterator>
 
1926
_OutputIterator
 
1927
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
 
1928
                                         char_type __fl, const void* __v) const
 
1929
{
 
1930
    // Stage 1 - Get pointer in narrow char
 
1931
    char __fmt[6] = "%p";
 
1932
    const unsigned __nbuf = 20;
 
1933
    char __nar[__nbuf];
 
1934
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
1935
    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
 
1936
#else
 
1937
    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
 
1938
#endif
 
1939
    char* __ne = __nar + __nc;
 
1940
    char* __np = this->__identify_padding(__nar, __ne, __iob);
 
1941
    // Stage 2 - Widen __nar
 
1942
    char_type __o[2*(__nbuf-1) - 1];
 
1943
    char_type* __op;  // pad here
 
1944
    char_type* __oe;  // end of output
 
1945
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
 
1946
    __ct.widen(__nar, __ne, __o);
 
1947
    __oe = __o + (__ne - __nar);
 
1948
    if (__np == __ne)
 
1949
        __op = __oe;
 
1950
    else
 
1951
        __op = __o + (__np - __nar);
 
1952
    // [__o, __oe) contains wide number
 
1953
    // Stage 3 & 4
 
1954
    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
 
1955
}
 
1956
 
 
1957
_LIBCPP_EXTERN_TEMPLATE(class num_put<char>)
 
1958
_LIBCPP_EXTERN_TEMPLATE(class num_put<wchar_t>)
 
1959
 
 
1960
template <class _CharT, class _InputIterator>
 
1961
_LIBCPP_HIDDEN
 
1962
int
 
1963
__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
 
1964
                     ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
 
1965
{
 
1966
    // Precondition:  __n >= 1
 
1967
    if (__b == __e)
 
1968
    {
 
1969
        __err |= ios_base::eofbit | ios_base::failbit;
 
1970
        return 0;
 
1971
    }
 
1972
    // get first digit
 
1973
    _CharT __c = *__b;
 
1974
    if (!__ct.is(ctype_base::digit, __c))
 
1975
    {
 
1976
        __err |= ios_base::failbit;
 
1977
        return 0;
 
1978
    }
 
1979
    int __r = __ct.narrow(__c, 0) - '0';
 
1980
    for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n)
 
1981
    {
 
1982
        // get next digit
 
1983
        __c = *__b;
 
1984
        if (!__ct.is(ctype_base::digit, __c))
 
1985
            return __r;
 
1986
        __r = __r * 10 + __ct.narrow(__c, 0) - '0';
 
1987
    }
 
1988
    if (__b == __e)
 
1989
        __err |= ios_base::eofbit;
 
1990
    return __r;
 
1991
}
 
1992
 
 
1993
class _LIBCPP_TYPE_VIS time_base
 
1994
{
 
1995
public:
 
1996
    enum dateorder {no_order, dmy, mdy, ymd, ydm};
 
1997
};
 
1998
 
 
1999
template <class _CharT>
 
2000
class __time_get_c_storage  // purposefully not decorated
 
2001
{
 
2002
protected:
 
2003
    typedef basic_string<_CharT> string_type;
 
2004
 
 
2005
    virtual const string_type* __weeks() const;
 
2006
    virtual const string_type* __months() const;
 
2007
    virtual const string_type* __am_pm() const;
 
2008
    virtual const string_type& __c() const;
 
2009
    virtual const string_type& __r() const;
 
2010
    virtual const string_type& __x() const;
 
2011
    virtual const string_type& __X() const;
 
2012
};
 
2013
 
 
2014
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
 
2015
class _LIBCPP_TYPE_VIS time_get
 
2016
    : public locale::facet,
 
2017
      public time_base,
 
2018
      private __time_get_c_storage<_CharT>
 
2019
{
 
2020
public:
 
2021
    typedef _CharT                  char_type;
 
2022
    typedef _InputIterator          iter_type;
 
2023
    typedef time_base::dateorder    dateorder;
 
2024
    typedef basic_string<char_type> string_type;
 
2025
 
 
2026
    _LIBCPP_ALWAYS_INLINE
 
2027
    explicit time_get(size_t __refs = 0)
 
2028
        : locale::facet(__refs) {}
 
2029
 
 
2030
    _LIBCPP_ALWAYS_INLINE
 
2031
    dateorder date_order() const
 
2032
    {
 
2033
        return this->do_date_order();
 
2034
    }
 
2035
 
 
2036
    _LIBCPP_ALWAYS_INLINE
 
2037
    iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
 
2038
                       ios_base::iostate& __err, tm* __tm) const
 
2039
    {
 
2040
        return do_get_time(__b, __e, __iob, __err, __tm);
 
2041
    }
 
2042
 
 
2043
    _LIBCPP_ALWAYS_INLINE
 
2044
    iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
 
2045
                       ios_base::iostate& __err, tm* __tm) const
 
2046
    {
 
2047
        return do_get_date(__b, __e, __iob, __err, __tm);
 
2048
    }
 
2049
 
 
2050
    _LIBCPP_ALWAYS_INLINE
 
2051
    iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
 
2052
                          ios_base::iostate& __err, tm* __tm) const
 
2053
    {
 
2054
        return do_get_weekday(__b, __e, __iob, __err, __tm);
 
2055
    }
 
2056
 
 
2057
    _LIBCPP_ALWAYS_INLINE
 
2058
    iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
 
2059
                            ios_base::iostate& __err, tm* __tm) const
 
2060
    {
 
2061
        return do_get_monthname(__b, __e, __iob, __err, __tm);
 
2062
    }
 
2063
 
 
2064
    _LIBCPP_ALWAYS_INLINE
 
2065
    iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
 
2066
                       ios_base::iostate& __err, tm* __tm) const
 
2067
    {
 
2068
        return do_get_year(__b, __e, __iob, __err, __tm);
 
2069
    }
 
2070
 
 
2071
    _LIBCPP_ALWAYS_INLINE
 
2072
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
2073
                  ios_base::iostate& __err, tm *__tm,
 
2074
                  char __fmt, char __mod = 0) const
 
2075
    {
 
2076
        return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
 
2077
    }
 
2078
 
 
2079
    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
 
2080
                  ios_base::iostate& __err, tm* __tm,
 
2081
                  const char_type* __fmtb, const char_type* __fmte) const;
 
2082
 
 
2083
    static locale::id id;
 
2084
 
 
2085
protected:
 
2086
    _LIBCPP_ALWAYS_INLINE
 
2087
    ~time_get() {}
 
2088
 
 
2089
    virtual dateorder do_date_order() const;
 
2090
    virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
 
2091
                                  ios_base::iostate& __err, tm* __tm) const;
 
2092
    virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
 
2093
                                  ios_base::iostate& __err, tm* __tm) const;
 
2094
    virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
 
2095
                                     ios_base::iostate& __err, tm* __tm) const;
 
2096
    virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
 
2097
                                       ios_base::iostate& __err, tm* __tm) const;
 
2098
    virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
 
2099
                                  ios_base::iostate& __err, tm* __tm) const;
 
2100
    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
 
2101
                             ios_base::iostate& __err, tm* __tm,
 
2102
                             char __fmt, char __mod) const;
 
2103
private:
 
2104
    void __get_white_space(iter_type& __b, iter_type __e,
 
2105
                           ios_base::iostate& __err, const ctype<char_type>& __ct) const;
 
2106
    void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
 
2107
                       const ctype<char_type>& __ct) const;
 
2108
 
 
2109
    void __get_weekdayname(int& __m,
 
2110
                           iter_type& __b, iter_type __e,
 
2111
                           ios_base::iostate& __err,
 
2112
                           const ctype<char_type>& __ct) const;
 
2113
    void __get_monthname(int& __m,
 
2114
                         iter_type& __b, iter_type __e,
 
2115
                         ios_base::iostate& __err,
 
2116
                         const ctype<char_type>& __ct) const;
 
2117
    void __get_day(int& __d,
 
2118
                   iter_type& __b, iter_type __e,
 
2119
                   ios_base::iostate& __err,
 
2120
                   const ctype<char_type>& __ct) const;
 
2121
    void __get_month(int& __m,
 
2122
                     iter_type& __b, iter_type __e,
 
2123
                     ios_base::iostate& __err,
 
2124
                     const ctype<char_type>& __ct) const;
 
2125
    void __get_year(int& __y,
 
2126
                   iter_type& __b, iter_type __e,
 
2127
                   ios_base::iostate& __err,
 
2128
                   const ctype<char_type>& __ct) const;
 
2129
    void __get_year4(int& __y,
 
2130
                    iter_type& __b, iter_type __e,
 
2131
                    ios_base::iostate& __err,
 
2132
                    const ctype<char_type>& __ct) const;
 
2133
    void __get_hour(int& __d,
 
2134
                    iter_type& __b, iter_type __e,
 
2135
                    ios_base::iostate& __err,
 
2136
                    const ctype<char_type>& __ct) const;
 
2137
    void __get_12_hour(int& __h,
 
2138
                       iter_type& __b, iter_type __e,
 
2139
                       ios_base::iostate& __err,
 
2140
                       const ctype<char_type>& __ct) const;
 
2141
    void __get_am_pm(int& __h,
 
2142
                     iter_type& __b, iter_type __e,
 
2143
                     ios_base::iostate& __err,
 
2144
                     const ctype<char_type>& __ct) const;
 
2145
    void __get_minute(int& __m,
 
2146
                      iter_type& __b, iter_type __e,
 
2147
                      ios_base::iostate& __err,
 
2148
                      const ctype<char_type>& __ct) const;
 
2149
    void __get_second(int& __s,
 
2150
                      iter_type& __b, iter_type __e,
 
2151
                      ios_base::iostate& __err,
 
2152
                      const ctype<char_type>& __ct) const;
 
2153
    void __get_weekday(int& __w,
 
2154
                       iter_type& __b, iter_type __e,
 
2155
                       ios_base::iostate& __err,
 
2156
                       const ctype<char_type>& __ct) const;
 
2157
    void __get_day_year_num(int& __w,
 
2158
                            iter_type& __b, iter_type __e,
 
2159
                            ios_base::iostate& __err,
 
2160
                            const ctype<char_type>& __ct) const;
 
2161
};
 
2162
 
 
2163
template <class _CharT, class _InputIterator>
 
2164
locale::id
 
2165
time_get<_CharT, _InputIterator>::id;
 
2166
 
 
2167
// time_get primatives
 
2168
 
 
2169
template <class _CharT, class _InputIterator>
 
2170
void
 
2171
time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
 
2172
                                                    iter_type& __b, iter_type __e,
 
2173
                                                    ios_base::iostate& __err,
 
2174
                                                    const ctype<char_type>& __ct) const
 
2175
{
 
2176
    // Note:  ignoring case comes from the POSIX strptime spec
 
2177
    const string_type* __wk = this->__weeks();
 
2178
    ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
 
2179
    if (__i < 14)
 
2180
        __w = __i % 7;
 
2181
}
 
2182
 
 
2183
template <class _CharT, class _InputIterator>
 
2184
void
 
2185
time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
 
2186
                                                  iter_type& __b, iter_type __e,
 
2187
                                                  ios_base::iostate& __err,
 
2188
                                                  const ctype<char_type>& __ct) const
 
2189
{
 
2190
    // Note:  ignoring case comes from the POSIX strptime spec
 
2191
    const string_type* __month = this->__months();
 
2192
    ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
 
2193
    if (__i < 24)
 
2194
        __m = __i % 12;
 
2195
}
 
2196
 
 
2197
template <class _CharT, class _InputIterator>
 
2198
void
 
2199
time_get<_CharT, _InputIterator>::__get_day(int& __d,
 
2200
                                            iter_type& __b, iter_type __e,
 
2201
                                            ios_base::iostate& __err,
 
2202
                                            const ctype<char_type>& __ct) const
 
2203
{
 
2204
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
 
2205
    if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
 
2206
        __d = __t;
 
2207
    else
 
2208
        __err |= ios_base::failbit;
 
2209
}
 
2210
 
 
2211
template <class _CharT, class _InputIterator>
 
2212
void
 
2213
time_get<_CharT, _InputIterator>::__get_month(int& __m,
 
2214
                                              iter_type& __b, iter_type __e,
 
2215
                                              ios_base::iostate& __err,
 
2216
                                              const ctype<char_type>& __ct) const
 
2217
{
 
2218
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
 
2219
    if (!(__err & ios_base::failbit) && __t <= 11)
 
2220
        __m = __t;
 
2221
    else
 
2222
        __err |= ios_base::failbit;
 
2223
}
 
2224
 
 
2225
template <class _CharT, class _InputIterator>
 
2226
void
 
2227
time_get<_CharT, _InputIterator>::__get_year(int& __y,
 
2228
                                             iter_type& __b, iter_type __e,
 
2229
                                             ios_base::iostate& __err,
 
2230
                                             const ctype<char_type>& __ct) const
 
2231
{
 
2232
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
 
2233
    if (!(__err & ios_base::failbit))
 
2234
    {
 
2235
        if (__t < 69)
 
2236
            __t += 2000;
 
2237
        else if (69 <= __t && __t <= 99)
 
2238
            __t += 1900;
 
2239
        __y = __t - 1900;
 
2240
    }
 
2241
}
 
2242
 
 
2243
template <class _CharT, class _InputIterator>
 
2244
void
 
2245
time_get<_CharT, _InputIterator>::__get_year4(int& __y,
 
2246
                                              iter_type& __b, iter_type __e,
 
2247
                                              ios_base::iostate& __err,
 
2248
                                              const ctype<char_type>& __ct) const
 
2249
{
 
2250
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
 
2251
    if (!(__err & ios_base::failbit))
 
2252
        __y = __t - 1900;
 
2253
}
 
2254
 
 
2255
template <class _CharT, class _InputIterator>
 
2256
void
 
2257
time_get<_CharT, _InputIterator>::__get_hour(int& __h,
 
2258
                                             iter_type& __b, iter_type __e,
 
2259
                                             ios_base::iostate& __err,
 
2260
                                             const ctype<char_type>& __ct) const
 
2261
{
 
2262
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
 
2263
    if (!(__err & ios_base::failbit) && __t <= 23)
 
2264
        __h = __t;
 
2265
    else
 
2266
        __err |= ios_base::failbit;
 
2267
}
 
2268
 
 
2269
template <class _CharT, class _InputIterator>
 
2270
void
 
2271
time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
 
2272
                                                iter_type& __b, iter_type __e,
 
2273
                                                ios_base::iostate& __err,
 
2274
                                                const ctype<char_type>& __ct) const
 
2275
{
 
2276
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
 
2277
    if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
 
2278
        __h = __t;
 
2279
    else
 
2280
        __err |= ios_base::failbit;
 
2281
}
 
2282
 
 
2283
template <class _CharT, class _InputIterator>
 
2284
void
 
2285
time_get<_CharT, _InputIterator>::__get_minute(int& __m,
 
2286
                                               iter_type& __b, iter_type __e,
 
2287
                                               ios_base::iostate& __err,
 
2288
                                               const ctype<char_type>& __ct) const
 
2289
{
 
2290
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
 
2291
    if (!(__err & ios_base::failbit) && __t <= 59)
 
2292
        __m = __t;
 
2293
    else
 
2294
        __err |= ios_base::failbit;
 
2295
}
 
2296
 
 
2297
template <class _CharT, class _InputIterator>
 
2298
void
 
2299
time_get<_CharT, _InputIterator>::__get_second(int& __s,
 
2300
                                               iter_type& __b, iter_type __e,
 
2301
                                               ios_base::iostate& __err,
 
2302
                                               const ctype<char_type>& __ct) const
 
2303
{
 
2304
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
 
2305
    if (!(__err & ios_base::failbit) && __t <= 60)
 
2306
        __s = __t;
 
2307
    else
 
2308
        __err |= ios_base::failbit;
 
2309
}
 
2310
 
 
2311
template <class _CharT, class _InputIterator>
 
2312
void
 
2313
time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
 
2314
                                                iter_type& __b, iter_type __e,
 
2315
                                                ios_base::iostate& __err,
 
2316
                                                const ctype<char_type>& __ct) const
 
2317
{
 
2318
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
 
2319
    if (!(__err & ios_base::failbit) && __t <= 6)
 
2320
        __w = __t;
 
2321
    else
 
2322
        __err |= ios_base::failbit;
 
2323
}
 
2324
 
 
2325
template <class _CharT, class _InputIterator>
 
2326
void
 
2327
time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
 
2328
                                                     iter_type& __b, iter_type __e,
 
2329
                                                     ios_base::iostate& __err,
 
2330
                                                     const ctype<char_type>& __ct) const
 
2331
{
 
2332
    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
 
2333
    if (!(__err & ios_base::failbit) && __t <= 365)
 
2334
        __d = __t;
 
2335
    else
 
2336
        __err |= ios_base::failbit;
 
2337
}
 
2338
 
 
2339
template <class _CharT, class _InputIterator>
 
2340
void
 
2341
time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
 
2342
                                                    ios_base::iostate& __err,
 
2343
                                                    const ctype<char_type>& __ct) const
 
2344
{
 
2345
    for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
 
2346
        ;
 
2347
    if (__b == __e)
 
2348
        __err |= ios_base::eofbit;
 
2349
}
 
2350
 
 
2351
template <class _CharT, class _InputIterator>
 
2352
void
 
2353
time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
 
2354
                                              iter_type& __b, iter_type __e,
 
2355
                                              ios_base::iostate& __err,
 
2356
                                              const ctype<char_type>& __ct) const
 
2357
{
 
2358
    const string_type* __ap = this->__am_pm();
 
2359
    if (__ap[0].size() + __ap[1].size() == 0)
 
2360
    {
 
2361
        __err |= ios_base::failbit;
 
2362
        return;
 
2363
    }
 
2364
    ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
 
2365
    if (__i == 0 && __h == 12)
 
2366
        __h = 0;
 
2367
    else if (__i == 1 && __h < 12)
 
2368
        __h += 12;
 
2369
}
 
2370
 
 
2371
template <class _CharT, class _InputIterator>
 
2372
void
 
2373
time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
 
2374
                                                ios_base::iostate& __err,
 
2375
                                                const ctype<char_type>& __ct) const
 
2376
{
 
2377
    if (__b == __e)
 
2378
    {
 
2379
        __err |= ios_base::eofbit | ios_base::failbit;
 
2380
        return;
 
2381
    }
 
2382
    if (__ct.narrow(*__b, 0) != '%')
 
2383
        __err |= ios_base::failbit;
 
2384
    else if(++__b == __e)
 
2385
        __err |= ios_base::eofbit;
 
2386
}
 
2387
 
 
2388
// time_get end primatives
 
2389
 
 
2390
template <class _CharT, class _InputIterator>
 
2391
_InputIterator
 
2392
time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
 
2393
                                      ios_base& __iob,
 
2394
                                      ios_base::iostate& __err, tm* __tm,
 
2395
                                      const char_type* __fmtb, const char_type* __fmte) const
 
2396
{
 
2397
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
 
2398
    __err = ios_base::goodbit;
 
2399
    while (__fmtb != __fmte && __err == ios_base::goodbit)
 
2400
    {
 
2401
        if (__b == __e)
 
2402
        {
 
2403
            __err = ios_base::failbit;
 
2404
            break;
 
2405
        }
 
2406
        if (__ct.narrow(*__fmtb, 0) == '%')
 
2407
        {
 
2408
            if (++__fmtb == __fmte)
 
2409
            {
 
2410
                __err = ios_base::failbit;
 
2411
                break;
 
2412
            }
 
2413
            char __cmd = __ct.narrow(*__fmtb, 0);
 
2414
            char __opt = '\0';
 
2415
            if (__cmd == 'E' || __cmd == '0')
 
2416
            {
 
2417
                if (++__fmtb == __fmte)
 
2418
                {
 
2419
                    __err = ios_base::failbit;
 
2420
                    break;
 
2421
                }
 
2422
                __opt = __cmd;
 
2423
                __cmd = __ct.narrow(*__fmtb, 0);
 
2424
            }
 
2425
            __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
 
2426
            ++__fmtb;
 
2427
        }
 
2428
        else if (__ct.is(ctype_base::space, *__fmtb))
 
2429
        {
 
2430
            for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
 
2431
                ;
 
2432
            for (        ;    __b != __e    && __ct.is(ctype_base::space, *__b);    ++__b)
 
2433
                ;
 
2434
        }
 
2435
        else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
 
2436
        {
 
2437
            ++__b;
 
2438
            ++__fmtb;
 
2439
        }
 
2440
        else
 
2441
            __err = ios_base::failbit;
 
2442
    }
 
2443
    if (__b == __e)
 
2444
        __err |= ios_base::eofbit;
 
2445
    return __b;
 
2446
}
 
2447
 
 
2448
template <class _CharT, class _InputIterator>
 
2449
typename time_get<_CharT, _InputIterator>::dateorder
 
2450
time_get<_CharT, _InputIterator>::do_date_order() const
 
2451
{
 
2452
    return mdy;
 
2453
}
 
2454
 
 
2455
template <class _CharT, class _InputIterator>
 
2456
_InputIterator
 
2457
time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
 
2458
                                              ios_base& __iob,
 
2459
                                              ios_base::iostate& __err,
 
2460
                                              tm* __tm) const
 
2461
{
 
2462
    const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
 
2463
    return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
 
2464
}
 
2465
 
 
2466
template <class _CharT, class _InputIterator>
 
2467
_InputIterator
 
2468
time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
 
2469
                                              ios_base& __iob,
 
2470
                                              ios_base::iostate& __err,
 
2471
                                              tm* __tm) const
 
2472
{
 
2473
    const string_type& __fmt = this->__x();
 
2474
    return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
 
2475
}
 
2476
 
 
2477
template <class _CharT, class _InputIterator>
 
2478
_InputIterator
 
2479
time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
 
2480
                                                 ios_base& __iob,
 
2481
                                                 ios_base::iostate& __err,
 
2482
                                                 tm* __tm) const
 
2483
{
 
2484
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
 
2485
    __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
 
2486
    return __b;
 
2487
}
 
2488
 
 
2489
template <class _CharT, class _InputIterator>
 
2490
_InputIterator
 
2491
time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
 
2492
                                                   ios_base& __iob,
 
2493
                                                   ios_base::iostate& __err,
 
2494
                                                   tm* __tm) const
 
2495
{
 
2496
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
 
2497
    __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
 
2498
    return __b;
 
2499
}
 
2500
 
 
2501
template <class _CharT, class _InputIterator>
 
2502
_InputIterator
 
2503
time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
 
2504
                                              ios_base& __iob,
 
2505
                                              ios_base::iostate& __err,
 
2506
                                              tm* __tm) const
 
2507
{
 
2508
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
 
2509
    __get_year(__tm->tm_year, __b, __e, __err, __ct);
 
2510
    return __b;
 
2511
}
 
2512
 
 
2513
template <class _CharT, class _InputIterator>
 
2514
_InputIterator
 
2515
time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
2516
                                         ios_base& __iob,
 
2517
                                         ios_base::iostate& __err, tm* __tm,
 
2518
                                         char __fmt, char) const
 
2519
{
 
2520
    __err = ios_base::goodbit;
 
2521
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
 
2522
    switch (__fmt)
 
2523
    {
 
2524
    case 'a':
 
2525
    case 'A':
 
2526
        __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
 
2527
        break;
 
2528
    case 'b':
 
2529
    case 'B':
 
2530
    case 'h':
 
2531
        __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
 
2532
        break;
 
2533
    case 'c':
 
2534
        {
 
2535
        const string_type& __fm = this->__c();
 
2536
        __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
 
2537
        }
 
2538
        break;
 
2539
    case 'd':
 
2540
    case 'e':
 
2541
        __get_day(__tm->tm_mday, __b, __e, __err, __ct);
 
2542
        break;
 
2543
    case 'D':
 
2544
        {
 
2545
        const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
 
2546
        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
 
2547
        }
 
2548
        break;
 
2549
    case 'F':
 
2550
        {
 
2551
        const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
 
2552
        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
 
2553
        }
 
2554
        break;
 
2555
    case 'H':
 
2556
        __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
 
2557
        break;
 
2558
    case 'I':
 
2559
        __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
 
2560
        break;
 
2561
    case 'j':
 
2562
        __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
 
2563
        break;
 
2564
    case 'm':
 
2565
        __get_month(__tm->tm_mon, __b, __e, __err, __ct);
 
2566
        break;
 
2567
    case 'M':
 
2568
        __get_minute(__tm->tm_min, __b, __e, __err, __ct);
 
2569
        break;
 
2570
    case 'n':
 
2571
    case 't':
 
2572
        __get_white_space(__b, __e, __err, __ct);
 
2573
        break;
 
2574
    case 'p':
 
2575
        __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
 
2576
        break;
 
2577
    case 'r':
 
2578
        {
 
2579
        const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
 
2580
        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
 
2581
        }
 
2582
        break;
 
2583
    case 'R':
 
2584
        {
 
2585
        const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
 
2586
        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
 
2587
        }
 
2588
        break;
 
2589
    case 'S':
 
2590
        __get_second(__tm->tm_sec, __b, __e, __err, __ct);
 
2591
        break;
 
2592
    case 'T':
 
2593
        {
 
2594
        const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
 
2595
        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
 
2596
        }
 
2597
        break;
 
2598
    case 'w':
 
2599
        __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
 
2600
        break;
 
2601
    case 'x':
 
2602
        return do_get_date(__b, __e, __iob, __err, __tm);
 
2603
    case 'X':
 
2604
        {
 
2605
        const string_type& __fm = this->__X();
 
2606
        __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
 
2607
        }
 
2608
        break;
 
2609
    case 'y':
 
2610
        __get_year(__tm->tm_year, __b, __e, __err, __ct);
 
2611
        break;
 
2612
    case 'Y':
 
2613
        __get_year4(__tm->tm_year, __b, __e, __err, __ct);
 
2614
        break;
 
2615
    case '%':
 
2616
        __get_percent(__b, __e, __err, __ct);
 
2617
        break;
 
2618
    default:
 
2619
        __err |= ios_base::failbit;
 
2620
    }
 
2621
    return __b;
 
2622
}
 
2623
 
 
2624
_LIBCPP_EXTERN_TEMPLATE(class time_get<char>)
 
2625
_LIBCPP_EXTERN_TEMPLATE(class time_get<wchar_t>)
 
2626
 
 
2627
class __time_get
 
2628
{
 
2629
protected:
 
2630
    locale_t __loc_;
 
2631
 
 
2632
    __time_get(const char* __nm);
 
2633
    __time_get(const string& __nm);
 
2634
    ~__time_get();
 
2635
};
 
2636
 
 
2637
template <class _CharT>
 
2638
class __time_get_storage
 
2639
    : public __time_get
 
2640
{
 
2641
protected:
 
2642
    typedef basic_string<_CharT> string_type;
 
2643
 
 
2644
    string_type __weeks_[14];
 
2645
    string_type __months_[24];
 
2646
    string_type __am_pm_[2];
 
2647
    string_type __c_;
 
2648
    string_type __r_;
 
2649
    string_type __x_;
 
2650
    string_type __X_;
 
2651
 
 
2652
    explicit __time_get_storage(const char* __nm);
 
2653
    explicit __time_get_storage(const string& __nm);
 
2654
 
 
2655
    _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
 
2656
 
 
2657
    time_base::dateorder __do_date_order() const;
 
2658
 
 
2659
private:
 
2660
    void init(const ctype<_CharT>&);
 
2661
    string_type __analyze(char __fmt, const ctype<_CharT>&);
 
2662
};
 
2663
 
 
2664
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
 
2665
class _LIBCPP_TYPE_VIS time_get_byname
 
2666
    : public time_get<_CharT, _InputIterator>,
 
2667
      private __time_get_storage<_CharT>
 
2668
{
 
2669
public:
 
2670
    typedef time_base::dateorder    dateorder;
 
2671
    typedef _InputIterator          iter_type;
 
2672
    typedef _CharT                  char_type;
 
2673
    typedef basic_string<char_type> string_type;
 
2674
 
 
2675
    _LIBCPP_INLINE_VISIBILITY
 
2676
    explicit time_get_byname(const char* __nm, size_t __refs = 0)
 
2677
        : time_get<_CharT, _InputIterator>(__refs),
 
2678
          __time_get_storage<_CharT>(__nm) {}
 
2679
    _LIBCPP_INLINE_VISIBILITY
 
2680
    explicit time_get_byname(const string& __nm, size_t __refs = 0)
 
2681
        : time_get<_CharT, _InputIterator>(__refs),
 
2682
          __time_get_storage<_CharT>(__nm) {}
 
2683
 
 
2684
protected:
 
2685
    _LIBCPP_INLINE_VISIBILITY
 
2686
    ~time_get_byname() {}
 
2687
 
 
2688
    _LIBCPP_INLINE_VISIBILITY
 
2689
    virtual dateorder do_date_order() const {return this->__do_date_order();}
 
2690
private:
 
2691
    _LIBCPP_INLINE_VISIBILITY
 
2692
    virtual const string_type* __weeks() const  {return this->__weeks_;}
 
2693
    _LIBCPP_INLINE_VISIBILITY
 
2694
    virtual const string_type* __months() const {return this->__months_;}
 
2695
    _LIBCPP_INLINE_VISIBILITY
 
2696
    virtual const string_type* __am_pm() const  {return this->__am_pm_;}
 
2697
    _LIBCPP_INLINE_VISIBILITY
 
2698
    virtual const string_type& __c() const      {return this->__c_;}
 
2699
    _LIBCPP_INLINE_VISIBILITY
 
2700
    virtual const string_type& __r() const      {return this->__r_;}
 
2701
    _LIBCPP_INLINE_VISIBILITY
 
2702
    virtual const string_type& __x() const      {return this->__x_;}
 
2703
    _LIBCPP_INLINE_VISIBILITY
 
2704
    virtual const string_type& __X() const      {return this->__X_;}
 
2705
};
 
2706
 
 
2707
_LIBCPP_EXTERN_TEMPLATE(class time_get_byname<char>)
 
2708
_LIBCPP_EXTERN_TEMPLATE(class time_get_byname<wchar_t>)
 
2709
 
 
2710
class __time_put
 
2711
{
 
2712
    locale_t __loc_;
 
2713
protected:
 
2714
    _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
 
2715
    __time_put(const char* __nm);
 
2716
    __time_put(const string& __nm);
 
2717
    ~__time_put();
 
2718
    void __do_put(char* __nb, char*& __ne, const tm* __tm,
 
2719
                  char __fmt, char __mod) const;
 
2720
    void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
 
2721
                  char __fmt, char __mod) const;
 
2722
};
 
2723
 
 
2724
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
 
2725
class _LIBCPP_TYPE_VIS time_put
 
2726
    : public locale::facet,
 
2727
      private __time_put
 
2728
{
 
2729
public:
 
2730
    typedef _CharT char_type;
 
2731
    typedef _OutputIterator iter_type;
 
2732
 
 
2733
    _LIBCPP_ALWAYS_INLINE
 
2734
    explicit time_put(size_t __refs = 0)
 
2735
        : locale::facet(__refs) {}
 
2736
 
 
2737
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
 
2738
                  const char_type* __pb, const char_type* __pe) const;
 
2739
 
 
2740
    _LIBCPP_ALWAYS_INLINE
 
2741
    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
 
2742
                  const tm* __tm, char __fmt, char __mod = 0) const
 
2743
    {
 
2744
        return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
 
2745
    }
 
2746
 
 
2747
    static locale::id id;
 
2748
 
 
2749
protected:
 
2750
    _LIBCPP_ALWAYS_INLINE
 
2751
    ~time_put() {}
 
2752
    virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
 
2753
                             char __fmt, char __mod) const;
 
2754
 
 
2755
    _LIBCPP_ALWAYS_INLINE
 
2756
    explicit time_put(const char* __nm, size_t __refs)
 
2757
        : locale::facet(__refs),
 
2758
          __time_put(__nm) {}
 
2759
    _LIBCPP_ALWAYS_INLINE
 
2760
    explicit time_put(const string& __nm, size_t __refs)
 
2761
        : locale::facet(__refs),
 
2762
          __time_put(__nm) {}
 
2763
};
 
2764
 
 
2765
template <class _CharT, class _OutputIterator>
 
2766
locale::id
 
2767
time_put<_CharT, _OutputIterator>::id;
 
2768
 
 
2769
template <class _CharT, class _OutputIterator>
 
2770
_OutputIterator
 
2771
time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
 
2772
                                       char_type __fl, const tm* __tm,
 
2773
                                       const char_type* __pb,
 
2774
                                       const char_type* __pe) const
 
2775
{
 
2776
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
 
2777
    for (; __pb != __pe; ++__pb)
 
2778
    {
 
2779
        if (__ct.narrow(*__pb, 0) == '%')
 
2780
        {
 
2781
            if (++__pb == __pe)
 
2782
            {
 
2783
                *__s++ = __pb[-1];
 
2784
                break;
 
2785
            }
 
2786
            char __mod = 0;
 
2787
            char __fmt = __ct.narrow(*__pb, 0);
 
2788
            if (__fmt == 'E' || __fmt == 'O')
 
2789
            {
 
2790
                if (++__pb == __pe)
 
2791
                {
 
2792
                    *__s++ = __pb[-2];
 
2793
                    *__s++ = __pb[-1];
 
2794
                    break;
 
2795
                }
 
2796
                __mod = __fmt;
 
2797
                __fmt = __ct.narrow(*__pb, 0);
 
2798
            }
 
2799
            __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
 
2800
        }
 
2801
        else
 
2802
            *__s++ = *__pb;
 
2803
    }
 
2804
    return __s;
 
2805
}
 
2806
 
 
2807
template <class _CharT, class _OutputIterator>
 
2808
_OutputIterator
 
2809
time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
 
2810
                                          char_type, const tm* __tm,
 
2811
                                          char __fmt, char __mod) const
 
2812
{
 
2813
    char_type __nar[100];
 
2814
    char_type* __nb = __nar;
 
2815
    char_type* __ne = __nb + 100;
 
2816
    __do_put(__nb, __ne, __tm, __fmt, __mod);
 
2817
    return _VSTD::copy(__nb, __ne, __s);
 
2818
}
 
2819
 
 
2820
_LIBCPP_EXTERN_TEMPLATE(class time_put<char>)
 
2821
_LIBCPP_EXTERN_TEMPLATE(class time_put<wchar_t>)
 
2822
 
 
2823
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
 
2824
class _LIBCPP_TYPE_VIS time_put_byname
 
2825
    : public time_put<_CharT, _OutputIterator>
 
2826
{
 
2827
public:
 
2828
    _LIBCPP_ALWAYS_INLINE
 
2829
    explicit time_put_byname(const char* __nm, size_t __refs = 0)
 
2830
        : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
 
2831
 
 
2832
    _LIBCPP_ALWAYS_INLINE
 
2833
    explicit time_put_byname(const string& __nm, size_t __refs = 0)
 
2834
        : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
 
2835
 
 
2836
protected:
 
2837
    _LIBCPP_ALWAYS_INLINE
 
2838
    ~time_put_byname() {}
 
2839
};
 
2840
 
 
2841
_LIBCPP_EXTERN_TEMPLATE(class time_put_byname<char>)
 
2842
_LIBCPP_EXTERN_TEMPLATE(class time_put_byname<wchar_t>)
 
2843
 
 
2844
// money_base
 
2845
 
 
2846
class _LIBCPP_TYPE_VIS money_base
 
2847
{
 
2848
public:
 
2849
    enum part {none, space, symbol, sign, value};
 
2850
    struct pattern {char field[4];};
 
2851
 
 
2852
    _LIBCPP_ALWAYS_INLINE money_base() {}
 
2853
};
 
2854
 
 
2855
// moneypunct
 
2856
 
 
2857
template <class _CharT, bool _International = false>
 
2858
class _LIBCPP_TYPE_VIS moneypunct
 
2859
    : public locale::facet,
 
2860
      public money_base
 
2861
{
 
2862
public:
 
2863
    typedef _CharT                  char_type;
 
2864
    typedef basic_string<char_type> string_type;
 
2865
 
 
2866
    _LIBCPP_ALWAYS_INLINE
 
2867
    explicit moneypunct(size_t __refs = 0)
 
2868
        : locale::facet(__refs) {}
 
2869
 
 
2870
    _LIBCPP_ALWAYS_INLINE char_type   decimal_point() const {return do_decimal_point();}
 
2871
    _LIBCPP_ALWAYS_INLINE char_type   thousands_sep() const {return do_thousands_sep();}
 
2872
    _LIBCPP_ALWAYS_INLINE string      grouping()      const {return do_grouping();}
 
2873
    _LIBCPP_ALWAYS_INLINE string_type curr_symbol()   const {return do_curr_symbol();}
 
2874
    _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
 
2875
    _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
 
2876
    _LIBCPP_ALWAYS_INLINE int         frac_digits()   const {return do_frac_digits();}
 
2877
    _LIBCPP_ALWAYS_INLINE pattern     pos_format()    const {return do_pos_format();}
 
2878
    _LIBCPP_ALWAYS_INLINE pattern     neg_format()    const {return do_neg_format();}
 
2879
 
 
2880
    static locale::id id;
 
2881
    static const bool intl = _International;
 
2882
 
 
2883
protected:
 
2884
    _LIBCPP_ALWAYS_INLINE
 
2885
    ~moneypunct() {}
 
2886
 
 
2887
    virtual char_type   do_decimal_point() const {return numeric_limits<char_type>::max();}
 
2888
    virtual char_type   do_thousands_sep() const {return numeric_limits<char_type>::max();}
 
2889
    virtual string      do_grouping()      const {return string();}
 
2890
    virtual string_type do_curr_symbol()   const {return string_type();}
 
2891
    virtual string_type do_positive_sign() const {return string_type();}
 
2892
    virtual string_type do_negative_sign() const {return string_type(1, '-');}
 
2893
    virtual int         do_frac_digits()   const {return 0;}
 
2894
    virtual pattern     do_pos_format()    const
 
2895
        {pattern __p = {{symbol, sign, none, value}}; return __p;}
 
2896
    virtual pattern     do_neg_format()    const
 
2897
        {pattern __p = {{symbol, sign, none, value}}; return __p;}
 
2898
};
 
2899
 
 
2900
template <class _CharT, bool _International>
 
2901
locale::id
 
2902
moneypunct<_CharT, _International>::id;
 
2903
 
 
2904
template <class _CharT, bool _International>
 
2905
const bool
 
2906
moneypunct<_CharT, _International>::intl;
 
2907
 
 
2908
_LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, false>)
 
2909
_LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, true>)
 
2910
_LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, false>)
 
2911
_LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, true>)
 
2912
 
 
2913
// moneypunct_byname
 
2914
 
 
2915
template <class _CharT, bool _International = false>
 
2916
class _LIBCPP_TYPE_VIS moneypunct_byname
 
2917
    : public moneypunct<_CharT, _International>
 
2918
{
 
2919
public:
 
2920
    typedef money_base::pattern  pattern;
 
2921
    typedef _CharT                  char_type;
 
2922
    typedef basic_string<char_type> string_type;
 
2923
 
 
2924
    _LIBCPP_ALWAYS_INLINE
 
2925
    explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
 
2926
        : moneypunct<_CharT, _International>(__refs) {init(__nm);}
 
2927
 
 
2928
    _LIBCPP_ALWAYS_INLINE
 
2929
    explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
 
2930
        : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
 
2931
 
 
2932
protected:
 
2933
    _LIBCPP_ALWAYS_INLINE
 
2934
    ~moneypunct_byname() {}
 
2935
 
 
2936
    virtual char_type   do_decimal_point() const {return __decimal_point_;}
 
2937
    virtual char_type   do_thousands_sep() const {return __thousands_sep_;}
 
2938
    virtual string      do_grouping()      const {return __grouping_;}
 
2939
    virtual string_type do_curr_symbol()   const {return __curr_symbol_;}
 
2940
    virtual string_type do_positive_sign() const {return __positive_sign_;}
 
2941
    virtual string_type do_negative_sign() const {return __negative_sign_;}
 
2942
    virtual int         do_frac_digits()   const {return __frac_digits_;}
 
2943
    virtual pattern     do_pos_format()    const {return __pos_format_;}
 
2944
    virtual pattern     do_neg_format()    const {return __neg_format_;}
 
2945
 
 
2946
private:
 
2947
    char_type   __decimal_point_;
 
2948
    char_type   __thousands_sep_;
 
2949
    string      __grouping_;
 
2950
    string_type __curr_symbol_;
 
2951
    string_type __positive_sign_;
 
2952
    string_type __negative_sign_;
 
2953
    int         __frac_digits_;
 
2954
    pattern     __pos_format_;
 
2955
    pattern     __neg_format_;
 
2956
 
 
2957
    void init(const char*);
 
2958
};
 
2959
 
 
2960
template<> void moneypunct_byname<char, false>::init(const char*);
 
2961
template<> void moneypunct_byname<char, true>::init(const char*);
 
2962
template<> void moneypunct_byname<wchar_t, false>::init(const char*);
 
2963
template<> void moneypunct_byname<wchar_t, true>::init(const char*);
 
2964
 
 
2965
_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, false>)
 
2966
_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, true>)
 
2967
_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, false>)
 
2968
_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, true>)
 
2969
 
 
2970
// money_get
 
2971
 
 
2972
template <class _CharT>
 
2973
class __money_get
 
2974
{
 
2975
protected:
 
2976
    typedef _CharT                  char_type;
 
2977
    typedef basic_string<char_type> string_type;
 
2978
 
 
2979
    _LIBCPP_ALWAYS_INLINE __money_get() {}
 
2980
 
 
2981
    static void __gather_info(bool __intl, const locale& __loc,
 
2982
                              money_base::pattern& __pat, char_type& __dp,
 
2983
                              char_type& __ts, string& __grp,
 
2984
                              string_type& __sym, string_type& __psn,
 
2985
                              string_type& __nsn, int& __fd);
 
2986
};
 
2987
 
 
2988
template <class _CharT>
 
2989
void
 
2990
__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
 
2991
                                   money_base::pattern& __pat, char_type& __dp,
 
2992
                                   char_type& __ts, string& __grp,
 
2993
                                   string_type& __sym, string_type& __psn,
 
2994
                                   string_type& __nsn, int& __fd)
 
2995
{
 
2996
    if (__intl)
 
2997
    {
 
2998
        const moneypunct<char_type, true>& __mp =
 
2999
            use_facet<moneypunct<char_type, true> >(__loc);
 
3000
        __pat = __mp.neg_format();
 
3001
        __nsn = __mp.negative_sign();
 
3002
        __psn = __mp.positive_sign();
 
3003
        __dp = __mp.decimal_point();
 
3004
        __ts = __mp.thousands_sep();
 
3005
        __grp = __mp.grouping();
 
3006
        __sym = __mp.curr_symbol();
 
3007
        __fd = __mp.frac_digits();
 
3008
    }
 
3009
    else
 
3010
    {
 
3011
        const moneypunct<char_type, false>& __mp =
 
3012
            use_facet<moneypunct<char_type, false> >(__loc);
 
3013
        __pat = __mp.neg_format();
 
3014
        __nsn = __mp.negative_sign();
 
3015
        __psn = __mp.positive_sign();
 
3016
        __dp = __mp.decimal_point();
 
3017
        __ts = __mp.thousands_sep();
 
3018
        __grp = __mp.grouping();
 
3019
        __sym = __mp.curr_symbol();
 
3020
        __fd = __mp.frac_digits();
 
3021
    }
 
3022
}
 
3023
 
 
3024
_LIBCPP_EXTERN_TEMPLATE(class __money_get<char>)
 
3025
_LIBCPP_EXTERN_TEMPLATE(class __money_get<wchar_t>)
 
3026
 
 
3027
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
 
3028
class _LIBCPP_TYPE_VIS money_get
 
3029
    : public locale::facet,
 
3030
      private __money_get<_CharT>
 
3031
{
 
3032
public:
 
3033
    typedef _CharT                  char_type;
 
3034
    typedef _InputIterator          iter_type;
 
3035
    typedef basic_string<char_type> string_type;
 
3036
 
 
3037
    _LIBCPP_ALWAYS_INLINE
 
3038
    explicit money_get(size_t __refs = 0)
 
3039
        : locale::facet(__refs) {}
 
3040
 
 
3041
    _LIBCPP_ALWAYS_INLINE
 
3042
    iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
 
3043
                  ios_base::iostate& __err, long double& __v) const
 
3044
    {
 
3045
        return do_get(__b, __e, __intl, __iob, __err, __v);
 
3046
    }
 
3047
 
 
3048
    _LIBCPP_ALWAYS_INLINE
 
3049
    iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
 
3050
                  ios_base::iostate& __err, string_type& __v) const
 
3051
    {
 
3052
        return do_get(__b, __e, __intl, __iob, __err, __v);
 
3053
    }
 
3054
 
 
3055
    static locale::id id;
 
3056
 
 
3057
protected:
 
3058
 
 
3059
    _LIBCPP_ALWAYS_INLINE
 
3060
    ~money_get() {}
 
3061
 
 
3062
    virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
 
3063
                             ios_base& __iob, ios_base::iostate& __err,
 
3064
                             long double& __v) const;
 
3065
    virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
 
3066
                             ios_base& __iob, ios_base::iostate& __err,
 
3067
                             string_type& __v) const;
 
3068
 
 
3069
private:
 
3070
    static bool __do_get(iter_type& __b, iter_type __e,
 
3071
                         bool __intl, const locale& __loc,
 
3072
                         ios_base::fmtflags __flags, ios_base::iostate& __err,
 
3073
                         bool& __neg, const ctype<char_type>& __ct,
 
3074
                         unique_ptr<char_type, void(*)(void*)>& __wb,
 
3075
                         char_type*& __wn, char_type* __we);
 
3076
};
 
3077
 
 
3078
template <class _CharT, class _InputIterator>
 
3079
locale::id
 
3080
money_get<_CharT, _InputIterator>::id;
 
3081
 
 
3082
void __do_nothing(void*);
 
3083
 
 
3084
template <class _Tp>
 
3085
_LIBCPP_HIDDEN
 
3086
void
 
3087
__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
 
3088
{
 
3089
    bool __owns = __b.get_deleter() != __do_nothing;
 
3090
    size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
 
3091
    size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
 
3092
                       2 * __cur_cap : numeric_limits<size_t>::max();
 
3093
    size_t __n_off = static_cast<size_t>(__n - __b.get());
 
3094
    _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
 
3095
    if (__t == 0)
 
3096
        __throw_bad_alloc();
 
3097
    if (__owns)
 
3098
        __b.release();
 
3099
    __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
 
3100
    __new_cap /= sizeof(_Tp);
 
3101
    __n = __b.get() + __n_off;
 
3102
    __e = __b.get() + __new_cap;
 
3103
}
 
3104
 
 
3105
// true == success
 
3106
template <class _CharT, class _InputIterator>
 
3107
bool
 
3108
money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
 
3109
                                            bool __intl, const locale& __loc,
 
3110
                                            ios_base::fmtflags __flags,
 
3111
                                            ios_base::iostate& __err,
 
3112
                                            bool& __neg,
 
3113
                                            const ctype<char_type>& __ct,
 
3114
                                            unique_ptr<char_type, void(*)(void*)>& __wb,
 
3115
                                            char_type*& __wn, char_type* __we)
 
3116
{
 
3117
    const unsigned __bz = 100;
 
3118
    unsigned __gbuf[__bz];
 
3119
    unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
 
3120
    unsigned* __gn = __gb.get();
 
3121
    unsigned* __ge = __gn + __bz;
 
3122
    money_base::pattern __pat;
 
3123
    char_type __dp;
 
3124
    char_type __ts;
 
3125
    string __grp;
 
3126
    string_type __sym;
 
3127
    string_type __psn;
 
3128
    string_type __nsn;
 
3129
    // Capture the spaces read into money_base::{space,none} so they
 
3130
    // can be compared to initial spaces in __sym.
 
3131
    string_type __spaces;
 
3132
    int __fd;
 
3133
    __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
 
3134
                                       __sym, __psn, __nsn, __fd);
 
3135
    const string_type* __trailing_sign = 0;
 
3136
    __wn = __wb.get();
 
3137
    for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
 
3138
    {
 
3139
        switch (__pat.field[__p])
 
3140
        {
 
3141
        case money_base::space:
 
3142
            if (__p != 3)
 
3143
            {
 
3144
                if (__ct.is(ctype_base::space, *__b))
 
3145
                    __spaces.push_back(*__b++);
 
3146
                else
 
3147
                {
 
3148
                    __err |= ios_base::failbit;
 
3149
                    return false;
 
3150
                }
 
3151
            }
 
3152
            // drop through
 
3153
        case money_base::none:
 
3154
            if (__p != 3)
 
3155
            {
 
3156
                while (__b != __e && __ct.is(ctype_base::space, *__b))
 
3157
                    __spaces.push_back(*__b++);
 
3158
            }
 
3159
            break;
 
3160
        case money_base::sign:
 
3161
            if (__psn.size() + __nsn.size() > 0)
 
3162
            {
 
3163
                if (__psn.size() == 0 || __nsn.size() == 0)
 
3164
                {   // sign is optional
 
3165
                    if (__psn.size() > 0)
 
3166
                    {   // __nsn.size() == 0
 
3167
                        if (*__b == __psn[0])
 
3168
                        {
 
3169
                            ++__b;
 
3170
                            if (__psn.size() > 1)
 
3171
                                __trailing_sign = &__psn;
 
3172
                        }
 
3173
                        else
 
3174
                            __neg = true;
 
3175
                    }
 
3176
                    else if (*__b == __nsn[0])  // __nsn.size() > 0 &&  __psn.size() == 0
 
3177
                    {
 
3178
                        ++__b;
 
3179
                        __neg = true;
 
3180
                        if (__nsn.size() > 1)
 
3181
                            __trailing_sign = &__nsn;
 
3182
                    }
 
3183
                }
 
3184
                else  // sign is required
 
3185
                {
 
3186
                    if (*__b == __psn[0])
 
3187
                    {
 
3188
                        ++__b;
 
3189
                        if (__psn.size() > 1)
 
3190
                            __trailing_sign = &__psn;
 
3191
                    }
 
3192
                    else if (*__b == __nsn[0])
 
3193
                    {
 
3194
                        ++__b;
 
3195
                        __neg = true;
 
3196
                        if (__nsn.size() > 1)
 
3197
                            __trailing_sign = &__nsn;
 
3198
                    }
 
3199
                    else
 
3200
                    {
 
3201
                        __err |= ios_base::failbit;
 
3202
                        return false;
 
3203
                    }
 
3204
                }
 
3205
            }
 
3206
            break;
 
3207
        case money_base::symbol:
 
3208
            {
 
3209
            bool __more_needed = __trailing_sign ||
 
3210
                                 (__p < 2)       ||
 
3211
                                 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
 
3212
            bool __sb = __flags & ios_base::showbase;
 
3213
            if (__sb || __more_needed)
 
3214
            {
 
3215
                typename string_type::const_iterator __sym_space_end = __sym.begin();
 
3216
                if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
 
3217
                                __pat.field[__p - 1] == money_base::space)) {
 
3218
                    // Match spaces we've already read against spaces at
 
3219
                    // the beginning of __sym.
 
3220
                    while (__sym_space_end != __sym.end() &&
 
3221
                           __ct.is(ctype_base::space, *__sym_space_end))
 
3222
                        ++__sym_space_end;
 
3223
                    const size_t __num_spaces = __sym_space_end - __sym.begin();
 
3224
                    if (__num_spaces > __spaces.size() ||
 
3225
                        !equal(__spaces.end() - __num_spaces, __spaces.end(),
 
3226
                               __sym.begin())) {
 
3227
                        // No match. Put __sym_space_end back at the
 
3228
                        // beginning of __sym, which will prevent a
 
3229
                        // match in the next loop.
 
3230
                        __sym_space_end = __sym.begin();
 
3231
                    }
 
3232
                }
 
3233
                typename string_type::const_iterator __sym_curr_char = __sym_space_end;
 
3234
                while (__sym_curr_char != __sym.end() && __b != __e &&
 
3235
                       *__b == *__sym_curr_char) {
 
3236
                    ++__b;
 
3237
                    ++__sym_curr_char;
 
3238
                }
 
3239
                if (__sb && __sym_curr_char != __sym.end())
 
3240
                {
 
3241
                    __err |= ios_base::failbit;
 
3242
                    return false;
 
3243
                }
 
3244
            }
 
3245
            }
 
3246
            break;
 
3247
        case money_base::value:
 
3248
            {
 
3249
            unsigned __ng = 0;
 
3250
            for (; __b != __e; ++__b)
 
3251
            {
 
3252
                char_type __c = *__b;
 
3253
                if (__ct.is(ctype_base::digit, __c))
 
3254
                {
 
3255
                    if (__wn == __we)
 
3256
                        __double_or_nothing(__wb, __wn, __we);
 
3257
                    *__wn++ = __c;
 
3258
                    ++__ng;
 
3259
                }
 
3260
                else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
 
3261
                {
 
3262
                    if (__gn == __ge)
 
3263
                        __double_or_nothing(__gb, __gn, __ge);
 
3264
                    *__gn++ = __ng;
 
3265
                    __ng = 0;
 
3266
                }
 
3267
                else
 
3268
                    break;
 
3269
            }
 
3270
            if (__gb.get() != __gn && __ng > 0)
 
3271
            {
 
3272
                if (__gn == __ge)
 
3273
                    __double_or_nothing(__gb, __gn, __ge);
 
3274
                *__gn++ = __ng;
 
3275
            }
 
3276
            if (__fd > 0)
 
3277
            {
 
3278
                if (__b == __e || *__b != __dp)
 
3279
                {
 
3280
                    __err |= ios_base::failbit;
 
3281
                    return false;
 
3282
                }
 
3283
                for (++__b; __fd > 0; --__fd, ++__b)
 
3284
                {
 
3285
                    if (__b == __e || !__ct.is(ctype_base::digit, *__b))
 
3286
                    {
 
3287
                        __err |= ios_base::failbit;
 
3288
                        return false;
 
3289
                    }
 
3290
                    if (__wn == __we)
 
3291
                        __double_or_nothing(__wb, __wn, __we);
 
3292
                    *__wn++ = *__b;
 
3293
                }
 
3294
            }
 
3295
            if (__wn == __wb.get())
 
3296
            {
 
3297
                __err |= ios_base::failbit;
 
3298
                return false;
 
3299
            }
 
3300
            }
 
3301
            break;
 
3302
        }
 
3303
    }
 
3304
    if (__trailing_sign)
 
3305
    {
 
3306
        for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
 
3307
        {
 
3308
            if (__b == __e || *__b != (*__trailing_sign)[__i])
 
3309
            {
 
3310
                __err |= ios_base::failbit;
 
3311
                return false;
 
3312
            }
 
3313
        }
 
3314
    }
 
3315
    if (__gb.get() != __gn)
 
3316
    {
 
3317
        ios_base::iostate __et = ios_base::goodbit;
 
3318
        __check_grouping(__grp, __gb.get(), __gn, __et);
 
3319
        if (__et)
 
3320
        {
 
3321
            __err |= ios_base::failbit;
 
3322
            return false;
 
3323
        }
 
3324
    }
 
3325
    return true;
 
3326
}
 
3327
 
 
3328
template <class _CharT, class _InputIterator>
 
3329
_InputIterator
 
3330
money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
3331
                                          bool __intl, ios_base& __iob,
 
3332
                                          ios_base::iostate& __err,
 
3333
                                          long double& __v) const
 
3334
{
 
3335
    const int __bz = 100;
 
3336
    char_type __wbuf[__bz];
 
3337
    unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
 
3338
    char_type* __wn;
 
3339
    char_type* __we = __wbuf + __bz;
 
3340
    locale __loc = __iob.getloc();
 
3341
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
 
3342
    bool __neg = false;
 
3343
    if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
 
3344
                 __wb, __wn, __we))
 
3345
    {
 
3346
        const char __src[] = "0123456789";
 
3347
        char_type __atoms[sizeof(__src)-1];
 
3348
        __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
 
3349
        char __nbuf[__bz];
 
3350
        char* __nc = __nbuf;
 
3351
        unique_ptr<char, void(*)(void*)> __h(0, free);
 
3352
        if (__wn - __wb.get() > __bz-2)
 
3353
        {
 
3354
            __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
 
3355
            if (__h.get() == 0)
 
3356
                __throw_bad_alloc();
 
3357
            __nc = __h.get();
 
3358
        }
 
3359
        if (__neg)
 
3360
            *__nc++ = '-';
 
3361
        for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
 
3362
            *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
 
3363
        *__nc = char();
 
3364
        if (sscanf(__nbuf, "%Lf", &__v) != 1)
 
3365
            __throw_runtime_error("money_get error");
 
3366
    }
 
3367
    if (__b == __e)
 
3368
        __err |= ios_base::eofbit;
 
3369
    return __b;
 
3370
}
 
3371
 
 
3372
template <class _CharT, class _InputIterator>
 
3373
_InputIterator
 
3374
money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
 
3375
                                          bool __intl, ios_base& __iob,
 
3376
                                          ios_base::iostate& __err,
 
3377
                                          string_type& __v) const
 
3378
{
 
3379
    const int __bz = 100;
 
3380
    char_type __wbuf[__bz];
 
3381
    unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
 
3382
    char_type* __wn;
 
3383
    char_type* __we = __wbuf + __bz;
 
3384
    locale __loc = __iob.getloc();
 
3385
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
 
3386
    bool __neg = false;
 
3387
    if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
 
3388
                 __wb, __wn, __we))
 
3389
    {
 
3390
        __v.clear();
 
3391
        if (__neg)
 
3392
            __v.push_back(__ct.widen('-'));
 
3393
        char_type __z = __ct.widen('0');
 
3394
        char_type* __w;
 
3395
        for (__w = __wb.get(); __w < __wn-1; ++__w)
 
3396
            if (*__w != __z)
 
3397
                break;
 
3398
        __v.append(__w, __wn);
 
3399
    }
 
3400
    if (__b == __e)
 
3401
        __err |= ios_base::eofbit;
 
3402
    return __b;
 
3403
}
 
3404
 
 
3405
_LIBCPP_EXTERN_TEMPLATE(class money_get<char>)
 
3406
_LIBCPP_EXTERN_TEMPLATE(class money_get<wchar_t>)
 
3407
 
 
3408
// money_put
 
3409
 
 
3410
template <class _CharT>
 
3411
class __money_put
 
3412
{
 
3413
protected:
 
3414
    typedef _CharT                  char_type;
 
3415
    typedef basic_string<char_type> string_type;
 
3416
 
 
3417
    _LIBCPP_ALWAYS_INLINE __money_put() {}
 
3418
 
 
3419
    static void __gather_info(bool __intl, bool __neg, const locale& __loc,
 
3420
                              money_base::pattern& __pat, char_type& __dp,
 
3421
                              char_type& __ts, string& __grp,
 
3422
                              string_type& __sym, string_type& __sn,
 
3423
                              int& __fd);
 
3424
    static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
 
3425
                         ios_base::fmtflags __flags,
 
3426
                         const char_type* __db, const char_type* __de,
 
3427
                         const ctype<char_type>& __ct, bool __neg,
 
3428
                         const money_base::pattern& __pat, char_type __dp,
 
3429
                         char_type __ts, const string& __grp,
 
3430
                         const string_type& __sym, const string_type& __sn,
 
3431
                         int __fd);
 
3432
};
 
3433
 
 
3434
template <class _CharT>
 
3435
void
 
3436
__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
 
3437
                                   money_base::pattern& __pat, char_type& __dp,
 
3438
                                   char_type& __ts, string& __grp,
 
3439
                                   string_type& __sym, string_type& __sn,
 
3440
                                   int& __fd)
 
3441
{
 
3442
    if (__intl)
 
3443
    {
 
3444
        const moneypunct<char_type, true>& __mp =
 
3445
            use_facet<moneypunct<char_type, true> >(__loc);
 
3446
        if (__neg)
 
3447
        {
 
3448
            __pat = __mp.neg_format();
 
3449
            __sn = __mp.negative_sign();
 
3450
        }
 
3451
        else
 
3452
        {
 
3453
            __pat = __mp.pos_format();
 
3454
            __sn = __mp.positive_sign();
 
3455
        }
 
3456
        __dp = __mp.decimal_point();
 
3457
        __ts = __mp.thousands_sep();
 
3458
        __grp = __mp.grouping();
 
3459
        __sym = __mp.curr_symbol();
 
3460
        __fd = __mp.frac_digits();
 
3461
    }
 
3462
    else
 
3463
    {
 
3464
        const moneypunct<char_type, false>& __mp =
 
3465
            use_facet<moneypunct<char_type, false> >(__loc);
 
3466
        if (__neg)
 
3467
        {
 
3468
            __pat = __mp.neg_format();
 
3469
            __sn = __mp.negative_sign();
 
3470
        }
 
3471
        else
 
3472
        {
 
3473
            __pat = __mp.pos_format();
 
3474
            __sn = __mp.positive_sign();
 
3475
        }
 
3476
        __dp = __mp.decimal_point();
 
3477
        __ts = __mp.thousands_sep();
 
3478
        __grp = __mp.grouping();
 
3479
        __sym = __mp.curr_symbol();
 
3480
        __fd = __mp.frac_digits();
 
3481
    }
 
3482
}
 
3483
 
 
3484
template <class _CharT>
 
3485
void
 
3486
__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
 
3487
                              ios_base::fmtflags __flags,
 
3488
                              const char_type* __db, const char_type* __de,
 
3489
                              const ctype<char_type>& __ct, bool __neg,
 
3490
                              const money_base::pattern& __pat, char_type __dp,
 
3491
                              char_type __ts, const string& __grp,
 
3492
                              const string_type& __sym, const string_type& __sn,
 
3493
                              int __fd)
 
3494
{
 
3495
    __me = __mb;
 
3496
    for (unsigned __p = 0; __p < 4; ++__p)
 
3497
    {
 
3498
        switch (__pat.field[__p])
 
3499
        {
 
3500
        case money_base::none:
 
3501
            __mi = __me;
 
3502
            break;
 
3503
        case money_base::space:
 
3504
            __mi = __me;
 
3505
            *__me++ = __ct.widen(' ');
 
3506
            break;
 
3507
        case money_base::sign:
 
3508
            if (!__sn.empty())
 
3509
                *__me++ = __sn[0];
 
3510
            break;
 
3511
        case money_base::symbol:
 
3512
            if (!__sym.empty() && (__flags & ios_base::showbase))
 
3513
                __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
 
3514
            break;
 
3515
        case money_base::value:
 
3516
            {
 
3517
            // remember start of value so we can reverse it
 
3518
            char_type* __t = __me;
 
3519
            // find beginning of digits
 
3520
            if (__neg)
 
3521
                ++__db;
 
3522
            // find end of digits
 
3523
            const char_type* __d;
 
3524
            for (__d = __db; __d < __de; ++__d)
 
3525
                if (!__ct.is(ctype_base::digit, *__d))
 
3526
                    break;
 
3527
            // print fractional part
 
3528
            if (__fd > 0)
 
3529
            {
 
3530
                int __f;
 
3531
                for (__f = __fd; __d > __db && __f > 0; --__f)
 
3532
                    *__me++ = *--__d;
 
3533
                char_type __z = __f > 0 ? __ct.widen('0') : char_type();
 
3534
                for (; __f > 0; --__f)
 
3535
                    *__me++ = __z;
 
3536
                *__me++ = __dp;
 
3537
            }
 
3538
            // print units part
 
3539
            if (__d == __db)
 
3540
            {
 
3541
                *__me++ = __ct.widen('0');
 
3542
            }
 
3543
            else
 
3544
            {
 
3545
                unsigned __ng = 0;
 
3546
                unsigned __ig = 0;
 
3547
                unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
 
3548
                                              : static_cast<unsigned>(__grp[__ig]);
 
3549
                while (__d != __db)
 
3550
                {
 
3551
                    if (__ng == __gl)
 
3552
                    {
 
3553
                        *__me++ = __ts;
 
3554
                        __ng = 0;
 
3555
                        if (++__ig < __grp.size())
 
3556
                            __gl = __grp[__ig] == numeric_limits<char>::max() ?
 
3557
                                        numeric_limits<unsigned>::max() :
 
3558
                                        static_cast<unsigned>(__grp[__ig]);
 
3559
                    }
 
3560
                    *__me++ = *--__d;
 
3561
                    ++__ng;
 
3562
                }
 
3563
            }
 
3564
            // reverse it
 
3565
            reverse(__t, __me);
 
3566
            }
 
3567
            break;
 
3568
        }
 
3569
    }
 
3570
    // print rest of sign, if any
 
3571
    if (__sn.size() > 1)
 
3572
        __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
 
3573
    // set alignment
 
3574
    if ((__flags & ios_base::adjustfield) == ios_base::left)
 
3575
        __mi = __me;
 
3576
    else if ((__flags & ios_base::adjustfield) != ios_base::internal)
 
3577
        __mi = __mb;
 
3578
}
 
3579
 
 
3580
_LIBCPP_EXTERN_TEMPLATE(class __money_put<char>)
 
3581
_LIBCPP_EXTERN_TEMPLATE(class __money_put<wchar_t>)
 
3582
 
 
3583
template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
 
3584
class _LIBCPP_TYPE_VIS money_put
 
3585
    : public locale::facet,
 
3586
      private __money_put<_CharT>
 
3587
{
 
3588
public:
 
3589
    typedef _CharT                  char_type;
 
3590
    typedef _OutputIterator         iter_type;
 
3591
    typedef basic_string<char_type> string_type;
 
3592
 
 
3593
    _LIBCPP_ALWAYS_INLINE
 
3594
    explicit money_put(size_t __refs = 0)
 
3595
        : locale::facet(__refs) {}
 
3596
 
 
3597
    _LIBCPP_ALWAYS_INLINE
 
3598
    iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
 
3599
                  long double __units) const
 
3600
    {
 
3601
        return do_put(__s, __intl, __iob, __fl, __units);
 
3602
    }
 
3603
 
 
3604
    _LIBCPP_ALWAYS_INLINE
 
3605
    iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
 
3606
                  const string_type& __digits) const
 
3607
    {
 
3608
        return do_put(__s, __intl, __iob, __fl, __digits);
 
3609
    }
 
3610
 
 
3611
    static locale::id id;
 
3612
 
 
3613
protected:
 
3614
    _LIBCPP_ALWAYS_INLINE
 
3615
    ~money_put() {}
 
3616
 
 
3617
    virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
 
3618
                             char_type __fl, long double __units) const;
 
3619
    virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
 
3620
                             char_type __fl, const string_type& __digits) const;
 
3621
};
 
3622
 
 
3623
template <class _CharT, class _OutputIterator>
 
3624
locale::id
 
3625
money_put<_CharT, _OutputIterator>::id;
 
3626
 
 
3627
template <class _CharT, class _OutputIterator>
 
3628
_OutputIterator
 
3629
money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
 
3630
                                           ios_base& __iob, char_type __fl,
 
3631
                                           long double __units) const
 
3632
{
 
3633
    // convert to char
 
3634
    const size_t __bs = 100;
 
3635
    char __buf[__bs];
 
3636
    char* __bb = __buf;
 
3637
    char_type __digits[__bs];
 
3638
    char_type* __db = __digits;
 
3639
    size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
 
3640
    unique_ptr<char, void(*)(void*)> __hn(0, free);
 
3641
    unique_ptr<char_type, void(*)(void*)> __hd(0, free);
 
3642
    // secure memory for digit storage
 
3643
    if (__n > __bs-1)
 
3644
    {
 
3645
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 
3646
        __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
 
3647
#else
 
3648
        __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
 
3649
#endif
 
3650
        if (__bb == 0)
 
3651
            __throw_bad_alloc();
 
3652
        __hn.reset(__bb);
 
3653
        __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
 
3654
        if (__hd == nullptr)
 
3655
            __throw_bad_alloc();
 
3656
        __db = __hd.get();
 
3657
    }
 
3658
    // gather info
 
3659
    locale __loc = __iob.getloc();
 
3660
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
 
3661
    __ct.widen(__bb, __bb + __n, __db);
 
3662
    bool __neg = __n > 0 && __bb[0] == '-';
 
3663
    money_base::pattern __pat;
 
3664
    char_type __dp;
 
3665
    char_type __ts;
 
3666
    string __grp;
 
3667
    string_type __sym;
 
3668
    string_type __sn;
 
3669
    int __fd;
 
3670
    this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
 
3671
    // secure memory for formatting
 
3672
    char_type __mbuf[__bs];
 
3673
    char_type* __mb = __mbuf;
 
3674
    unique_ptr<char_type, void(*)(void*)> __hw(0, free);
 
3675
    size_t __exn = static_cast<int>(__n) > __fd ?
 
3676
                   (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
 
3677
                    __sym.size() + static_cast<size_t>(__fd) + 1
 
3678
                 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
 
3679
    if (__exn > __bs)
 
3680
    {
 
3681
        __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
 
3682
        __mb = __hw.get();
 
3683
        if (__mb == 0)
 
3684
            __throw_bad_alloc();
 
3685
    }
 
3686
    // format
 
3687
    char_type* __mi;
 
3688
    char_type* __me;
 
3689
    this->__format(__mb, __mi, __me, __iob.flags(),
 
3690
                   __db, __db + __n, __ct,
 
3691
                   __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
 
3692
    return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
 
3693
}
 
3694
 
 
3695
template <class _CharT, class _OutputIterator>
 
3696
_OutputIterator
 
3697
money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
 
3698
                                           ios_base& __iob, char_type __fl,
 
3699
                                           const string_type& __digits) const
 
3700
{
 
3701
    // gather info
 
3702
    locale __loc = __iob.getloc();
 
3703
    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
 
3704
    bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
 
3705
    money_base::pattern __pat;
 
3706
    char_type __dp;
 
3707
    char_type __ts;
 
3708
    string __grp;
 
3709
    string_type __sym;
 
3710
    string_type __sn;
 
3711
    int __fd;
 
3712
    this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
 
3713
    // secure memory for formatting
 
3714
    char_type __mbuf[100];
 
3715
    char_type* __mb = __mbuf;
 
3716
    unique_ptr<char_type, void(*)(void*)> __h(0, free);
 
3717
    size_t __exn = static_cast<int>(__digits.size()) > __fd ?
 
3718
                   (__digits.size() - static_cast<size_t>(__fd)) * 2 +
 
3719
                    __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
 
3720
                 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
 
3721
    if (__exn > 100)
 
3722
    {
 
3723
        __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
 
3724
        __mb = __h.get();
 
3725
        if (__mb == 0)
 
3726
            __throw_bad_alloc();
 
3727
    }
 
3728
    // format
 
3729
    char_type* __mi;
 
3730
    char_type* __me;
 
3731
    this->__format(__mb, __mi, __me, __iob.flags(),
 
3732
                   __digits.data(), __digits.data() + __digits.size(), __ct,
 
3733
                   __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
 
3734
    return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
 
3735
}
 
3736
 
 
3737
_LIBCPP_EXTERN_TEMPLATE(class money_put<char>)
 
3738
_LIBCPP_EXTERN_TEMPLATE(class money_put<wchar_t>)
 
3739
 
 
3740
// messages
 
3741
 
 
3742
class _LIBCPP_TYPE_VIS messages_base
 
3743
{
 
3744
public:
 
3745
    typedef ptrdiff_t catalog;
 
3746
 
 
3747
    _LIBCPP_ALWAYS_INLINE messages_base() {}
 
3748
};
 
3749
 
 
3750
template <class _CharT>
 
3751
class _LIBCPP_TYPE_VIS messages
 
3752
    : public locale::facet,
 
3753
      public messages_base
 
3754
{
 
3755
public:
 
3756
    typedef _CharT               char_type;
 
3757
    typedef basic_string<_CharT> string_type;
 
3758
 
 
3759
    _LIBCPP_ALWAYS_INLINE
 
3760
    explicit messages(size_t __refs = 0)
 
3761
        : locale::facet(__refs) {}
 
3762
 
 
3763
    _LIBCPP_ALWAYS_INLINE
 
3764
    catalog open(const basic_string<char>& __nm, const locale& __loc) const
 
3765
    {
 
3766
        return do_open(__nm, __loc);
 
3767
    }
 
3768
 
 
3769
    _LIBCPP_ALWAYS_INLINE
 
3770
    string_type get(catalog __c, int __set, int __msgid,
 
3771
                    const string_type& __dflt) const
 
3772
    {
 
3773
        return do_get(__c, __set, __msgid, __dflt);
 
3774
    }
 
3775
 
 
3776
    _LIBCPP_ALWAYS_INLINE
 
3777
    void close(catalog __c) const
 
3778
    {
 
3779
        do_close(__c);
 
3780
    }
 
3781
 
 
3782
    static locale::id id;
 
3783
 
 
3784
protected:
 
3785
    _LIBCPP_ALWAYS_INLINE
 
3786
    ~messages() {}
 
3787
 
 
3788
    virtual catalog do_open(const basic_string<char>&, const locale&) const;
 
3789
    virtual string_type do_get(catalog, int __set, int __msgid,
 
3790
                               const string_type& __dflt) const;
 
3791
    virtual void do_close(catalog) const;
 
3792
};
 
3793
 
 
3794
template <class _CharT>
 
3795
locale::id
 
3796
messages<_CharT>::id;
 
3797
 
 
3798
template <class _CharT>
 
3799
typename messages<_CharT>::catalog
 
3800
messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
 
3801
{
 
3802
#ifdef _WIN32
 
3803
    return -1;
 
3804
#else // _WIN32
 
3805
    catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
 
3806
    if (__cat != -1)
 
3807
        __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
 
3808
    return __cat;
 
3809
#endif // _WIN32
 
3810
}
 
3811
 
 
3812
template <class _CharT>
 
3813
typename messages<_CharT>::string_type
 
3814
messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
 
3815
                         const string_type& __dflt) const
 
3816
{
 
3817
#ifdef _WIN32
 
3818
    return __dflt;
 
3819
#else // _WIN32
 
3820
    string __ndflt;
 
3821
    __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
 
3822
                                                       __dflt.c_str(),
 
3823
                                                       __dflt.c_str() + __dflt.size());
 
3824
    if (__c != -1)
 
3825
        __c <<= 1;
 
3826
    nl_catd __cat = (nl_catd)__c;
 
3827
    char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
 
3828
    string_type __w;
 
3829
    __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
 
3830
                                                        __n, __n + strlen(__n));
 
3831
    return __w;
 
3832
#endif // _WIN32
 
3833
}
 
3834
 
 
3835
template <class _CharT>
 
3836
void
 
3837
messages<_CharT>::do_close(catalog __c) const
 
3838
{
 
3839
#if !defined(_WIN32)
 
3840
    if (__c != -1)
 
3841
        __c <<= 1;
 
3842
    nl_catd __cat = (nl_catd)__c;
 
3843
    catclose(__cat);
 
3844
#endif // !_WIN32
 
3845
}
 
3846
 
 
3847
_LIBCPP_EXTERN_TEMPLATE(class messages<char>)
 
3848
_LIBCPP_EXTERN_TEMPLATE(class messages<wchar_t>)
 
3849
 
 
3850
template <class _CharT>
 
3851
class _LIBCPP_TYPE_VIS messages_byname
 
3852
    : public messages<_CharT>
 
3853
{
 
3854
public:
 
3855
    typedef messages_base::catalog catalog;
 
3856
    typedef basic_string<_CharT> string_type;
 
3857
 
 
3858
    _LIBCPP_ALWAYS_INLINE
 
3859
    explicit messages_byname(const char*, size_t __refs = 0)
 
3860
        : messages<_CharT>(__refs) {}
 
3861
 
 
3862
    _LIBCPP_ALWAYS_INLINE
 
3863
    explicit messages_byname(const string&, size_t __refs = 0)
 
3864
        : messages<_CharT>(__refs) {}
 
3865
 
 
3866
protected:
 
3867
    _LIBCPP_ALWAYS_INLINE
 
3868
    ~messages_byname() {}
 
3869
};
 
3870
 
 
3871
_LIBCPP_EXTERN_TEMPLATE(class messages_byname<char>)
 
3872
_LIBCPP_EXTERN_TEMPLATE(class messages_byname<wchar_t>)
 
3873
 
 
3874
template<class _Codecvt, class _Elem = wchar_t,
 
3875
         class _Wide_alloc = allocator<_Elem>,
 
3876
         class _Byte_alloc = allocator<char> >
 
3877
class _LIBCPP_TYPE_VIS wstring_convert
 
3878
{
 
3879
public:
 
3880
    typedef basic_string<char, char_traits<char>, _Byte_alloc>   byte_string;
 
3881
    typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
 
3882
    typedef typename _Codecvt::state_type                        state_type;
 
3883
    typedef typename wide_string::traits_type::int_type          int_type;
 
3884
 
 
3885
private:
 
3886
    byte_string __byte_err_string_;
 
3887
    wide_string __wide_err_string_;
 
3888
    _Codecvt* __cvtptr_;
 
3889
    state_type __cvtstate_;
 
3890
    size_t __cvtcount_;
 
3891
 
 
3892
    wstring_convert(const wstring_convert& __wc);
 
3893
    wstring_convert& operator=(const wstring_convert& __wc);
 
3894
public:
 
3895
    wstring_convert(_Codecvt* __pcvt = new _Codecvt);
 
3896
    wstring_convert(_Codecvt* __pcvt, state_type __state);
 
3897
    wstring_convert(const byte_string& __byte_err,
 
3898
                    const wide_string& __wide_err = wide_string());
 
3899
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
3900
    wstring_convert(wstring_convert&& __wc);
 
3901
#endif
 
3902
    ~wstring_convert();
 
3903
 
 
3904
    _LIBCPP_ALWAYS_INLINE
 
3905
    wide_string from_bytes(char __byte)
 
3906
        {return from_bytes(&__byte, &__byte+1);}
 
3907
    _LIBCPP_ALWAYS_INLINE
 
3908
    wide_string from_bytes(const char* __ptr)
 
3909
        {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
 
3910
    _LIBCPP_ALWAYS_INLINE
 
3911
    wide_string from_bytes(const byte_string& __str)
 
3912
        {return from_bytes(__str.data(), __str.data() + __str.size());}
 
3913
    wide_string from_bytes(const char* __first, const char* __last);
 
3914
 
 
3915
    _LIBCPP_ALWAYS_INLINE
 
3916
    byte_string to_bytes(_Elem __wchar)
 
3917
        {return to_bytes(&__wchar, &__wchar+1);}
 
3918
    _LIBCPP_ALWAYS_INLINE
 
3919
    byte_string to_bytes(const _Elem* __wptr)
 
3920
        {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
 
3921
    _LIBCPP_ALWAYS_INLINE
 
3922
    byte_string to_bytes(const wide_string& __wstr)
 
3923
        {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
 
3924
    byte_string to_bytes(const _Elem* __first, const _Elem* __last);
 
3925
 
 
3926
    _LIBCPP_ALWAYS_INLINE
 
3927
    size_t converted() const {return __cvtcount_;}
 
3928
    _LIBCPP_ALWAYS_INLINE
 
3929
    state_type state() const {return __cvtstate_;}
 
3930
};
 
3931
 
 
3932
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
 
3933
inline _LIBCPP_ALWAYS_INLINE
 
3934
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
 
3935
    wstring_convert(_Codecvt* __pcvt)
 
3936
        : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
 
3937
{
 
3938
}
 
3939
 
 
3940
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
 
3941
inline _LIBCPP_ALWAYS_INLINE
 
3942
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
 
3943
    wstring_convert(_Codecvt* __pcvt, state_type __state)
 
3944
        : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
 
3945
{
 
3946
}
 
3947
 
 
3948
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
 
3949
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
 
3950
    wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
 
3951
        : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
 
3952
          __cvtstate_(), __cvtcount_(0)
 
3953
{
 
3954
    __cvtptr_ = new _Codecvt;
 
3955
}
 
3956
 
 
3957
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
3958
 
 
3959
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
 
3960
inline _LIBCPP_ALWAYS_INLINE
 
3961
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
 
3962
    wstring_convert(wstring_convert&& __wc)
 
3963
        : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
 
3964
          __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
 
3965
          __cvtptr_(__wc.__cvtptr_),
 
3966
          __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
 
3967
{
 
3968
    __wc.__cvtptr_ = nullptr;
 
3969
}
 
3970
 
 
3971
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
3972
 
 
3973
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
 
3974
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
 
3975
{
 
3976
    delete __cvtptr_;
 
3977
}
 
3978
 
 
3979
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
 
3980
typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
 
3981
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
 
3982
    from_bytes(const char* __frm, const char* __frm_end)
 
3983
{
 
3984
    __cvtcount_ = 0;
 
3985
    if (__cvtptr_ != nullptr)
 
3986
    {
 
3987
        wide_string __ws(2*(__frm_end - __frm), _Elem());
 
3988
        if (__frm != __frm_end)
 
3989
            __ws.resize(__ws.capacity());
 
3990
        codecvt_base::result __r = codecvt_base::ok;
 
3991
        state_type __st = __cvtstate_;
 
3992
        if (__frm != __frm_end)
 
3993
        {
 
3994
            _Elem* __to = &__ws[0];
 
3995
            _Elem* __to_end = __to + __ws.size();
 
3996
            const char* __frm_nxt;
 
3997
            do
 
3998
            {
 
3999
                _Elem* __to_nxt;
 
4000
                __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
 
4001
                                          __to, __to_end, __to_nxt);
 
4002
                __cvtcount_ += __frm_nxt - __frm;
 
4003
                if (__frm_nxt == __frm)
 
4004
                {
 
4005
                    __r = codecvt_base::error;
 
4006
                }
 
4007
                else if (__r == codecvt_base::noconv)
 
4008
                {
 
4009
                    __ws.resize(__to - &__ws[0]);
 
4010
                    // This only gets executed if _Elem is char
 
4011
                    __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
 
4012
                    __frm = __frm_nxt;
 
4013
                    __r = codecvt_base::ok;
 
4014
                }
 
4015
                else if (__r == codecvt_base::ok)
 
4016
                {
 
4017
                    __ws.resize(__to_nxt - &__ws[0]);
 
4018
                    __frm = __frm_nxt;
 
4019
                }
 
4020
                else if (__r == codecvt_base::partial)
 
4021
                {
 
4022
                    ptrdiff_t __s = __to_nxt - &__ws[0];
 
4023
                    __ws.resize(2 * __s);
 
4024
                    __to = &__ws[0] + __s;
 
4025
                    __to_end = &__ws[0] + __ws.size();
 
4026
                    __frm = __frm_nxt;
 
4027
                }
 
4028
            } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
 
4029
        }
 
4030
        if (__r == codecvt_base::ok)
 
4031
            return __ws;
 
4032
    }
 
4033
#ifndef _LIBCPP_NO_EXCEPTIONS
 
4034
    if (__wide_err_string_.empty())
 
4035
        throw range_error("wstring_convert: from_bytes error");
 
4036
#endif  // _LIBCPP_NO_EXCEPTIONS
 
4037
    return __wide_err_string_;
 
4038
}
 
4039
 
 
4040
template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
 
4041
typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
 
4042
wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
 
4043
    to_bytes(const _Elem* __frm, const _Elem* __frm_end)
 
4044
{
 
4045
    __cvtcount_ = 0;
 
4046
    if (__cvtptr_ != nullptr)
 
4047
    {
 
4048
        byte_string __bs(2*(__frm_end - __frm), char());
 
4049
        if (__frm != __frm_end)
 
4050
            __bs.resize(__bs.capacity());
 
4051
        codecvt_base::result __r = codecvt_base::ok;
 
4052
        state_type __st = __cvtstate_;
 
4053
        if (__frm != __frm_end)
 
4054
        {
 
4055
            char* __to = &__bs[0];
 
4056
            char* __to_end = __to + __bs.size();
 
4057
            const _Elem* __frm_nxt;
 
4058
            do
 
4059
            {
 
4060
                char* __to_nxt;
 
4061
                __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
 
4062
                                           __to, __to_end, __to_nxt);
 
4063
                __cvtcount_ += __frm_nxt - __frm;
 
4064
                if (__frm_nxt == __frm)
 
4065
                {
 
4066
                    __r = codecvt_base::error;
 
4067
                }
 
4068
                else if (__r == codecvt_base::noconv)
 
4069
                {
 
4070
                    __bs.resize(__to - &__bs[0]);
 
4071
                    // This only gets executed if _Elem is char
 
4072
                    __bs.append((const char*)__frm, (const char*)__frm_end);
 
4073
                    __frm = __frm_nxt;
 
4074
                    __r = codecvt_base::ok;
 
4075
                }
 
4076
                else if (__r == codecvt_base::ok)
 
4077
                {
 
4078
                    __bs.resize(__to_nxt - &__bs[0]);
 
4079
                    __frm = __frm_nxt;
 
4080
                }
 
4081
                else if (__r == codecvt_base::partial)
 
4082
                {
 
4083
                    ptrdiff_t __s = __to_nxt - &__bs[0];
 
4084
                    __bs.resize(2 * __s);
 
4085
                    __to = &__bs[0] + __s;
 
4086
                    __to_end = &__bs[0] + __bs.size();
 
4087
                    __frm = __frm_nxt;
 
4088
                }
 
4089
            } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
 
4090
        }
 
4091
        if (__r == codecvt_base::ok)
 
4092
        {
 
4093
            size_t __s = __bs.size();
 
4094
            __bs.resize(__bs.capacity());
 
4095
            char* __to = &__bs[0] + __s;
 
4096
            char* __to_end = __to + __bs.size();
 
4097
            do
 
4098
            {
 
4099
                char* __to_nxt;
 
4100
                __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
 
4101
                if (__r == codecvt_base::noconv)
 
4102
                {
 
4103
                    __bs.resize(__to - &__bs[0]);
 
4104
                    __r = codecvt_base::ok;
 
4105
                }
 
4106
                else if (__r == codecvt_base::ok)
 
4107
                {
 
4108
                    __bs.resize(__to_nxt - &__bs[0]);
 
4109
                }
 
4110
                else if (__r == codecvt_base::partial)
 
4111
                {
 
4112
                    ptrdiff_t __sp = __to_nxt - &__bs[0];
 
4113
                    __bs.resize(2 * __sp);
 
4114
                    __to = &__bs[0] + __sp;
 
4115
                    __to_end = &__bs[0] + __bs.size();
 
4116
                }
 
4117
            } while (__r == codecvt_base::partial);
 
4118
            if (__r == codecvt_base::ok)
 
4119
                return __bs;
 
4120
        }
 
4121
    }
 
4122
#ifndef _LIBCPP_NO_EXCEPTIONS
 
4123
    if (__byte_err_string_.empty())
 
4124
        throw range_error("wstring_convert: to_bytes error");
 
4125
#endif  // _LIBCPP_NO_EXCEPTIONS
 
4126
    return __byte_err_string_;
 
4127
}
 
4128
 
 
4129
template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
 
4130
class _LIBCPP_TYPE_VIS wbuffer_convert
 
4131
    : public basic_streambuf<_Elem, _Tr>
 
4132
{
 
4133
public:
 
4134
    // types:
 
4135
    typedef _Elem                          char_type;
 
4136
    typedef _Tr                            traits_type;
 
4137
    typedef typename traits_type::int_type int_type;
 
4138
    typedef typename traits_type::pos_type pos_type;
 
4139
    typedef typename traits_type::off_type off_type;
 
4140
    typedef typename _Codecvt::state_type  state_type;
 
4141
 
 
4142
private:
 
4143
    char*       __extbuf_;
 
4144
    const char* __extbufnext_;
 
4145
    const char* __extbufend_;
 
4146
    char __extbuf_min_[8];
 
4147
    size_t __ebs_;
 
4148
    char_type* __intbuf_;
 
4149
    size_t __ibs_;
 
4150
    streambuf* __bufptr_;
 
4151
    _Codecvt* __cv_;
 
4152
    state_type __st_;
 
4153
    ios_base::openmode __cm_;
 
4154
    bool __owns_eb_;
 
4155
    bool __owns_ib_;
 
4156
    bool __always_noconv_;
 
4157
 
 
4158
    wbuffer_convert(const wbuffer_convert&);
 
4159
    wbuffer_convert& operator=(const wbuffer_convert&);
 
4160
public:
 
4161
    wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt,
 
4162
                    state_type __state = state_type());
 
4163
    ~wbuffer_convert();
 
4164
 
 
4165
    _LIBCPP_INLINE_VISIBILITY
 
4166
    streambuf* rdbuf() const {return __bufptr_;}
 
4167
    _LIBCPP_INLINE_VISIBILITY
 
4168
    streambuf* rdbuf(streambuf* __bytebuf)
 
4169
    {
 
4170
        streambuf* __r = __bufptr_;
 
4171
        __bufptr_ = __bytebuf;
 
4172
        return __r;
 
4173
    }
 
4174
 
 
4175
    _LIBCPP_INLINE_VISIBILITY
 
4176
    state_type state() const {return __st_;}
 
4177
 
 
4178
protected:
 
4179
    virtual int_type underflow();
 
4180
    virtual int_type pbackfail(int_type __c = traits_type::eof());
 
4181
    virtual int_type overflow (int_type __c = traits_type::eof());
 
4182
    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
 
4183
                                                            streamsize __n);
 
4184
    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
 
4185
                             ios_base::openmode __wch = ios_base::in | ios_base::out);
 
4186
    virtual pos_type seekpos(pos_type __sp,
 
4187
                             ios_base::openmode __wch = ios_base::in | ios_base::out);
 
4188
    virtual int sync();
 
4189
 
 
4190
private:
 
4191
    bool __read_mode();
 
4192
    void __write_mode();
 
4193
    wbuffer_convert* __close();
 
4194
};
 
4195
 
 
4196
template <class _Codecvt, class _Elem, class _Tr>
 
4197
wbuffer_convert<_Codecvt, _Elem, _Tr>::
 
4198
    wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
 
4199
    : __extbuf_(0),
 
4200
      __extbufnext_(0),
 
4201
      __extbufend_(0),
 
4202
      __ebs_(0),
 
4203
      __intbuf_(0),
 
4204
      __ibs_(0),
 
4205
      __bufptr_(__bytebuf),
 
4206
      __cv_(__pcvt),
 
4207
      __st_(__state),
 
4208
      __cm_(0),
 
4209
      __owns_eb_(false),
 
4210
      __owns_ib_(false),
 
4211
      __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
 
4212
{
 
4213
    setbuf(0, 4096);
 
4214
}
 
4215
 
 
4216
template <class _Codecvt, class _Elem, class _Tr>
 
4217
wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
 
4218
{
 
4219
    __close();
 
4220
    delete __cv_;
 
4221
    if (__owns_eb_)
 
4222
        delete [] __extbuf_;
 
4223
    if (__owns_ib_)
 
4224
        delete [] __intbuf_;
 
4225
}
 
4226
 
 
4227
template <class _Codecvt, class _Elem, class _Tr>
 
4228
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
 
4229
wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
 
4230
{
 
4231
    if (__cv_ == 0 || __bufptr_ == 0)
 
4232
        return traits_type::eof();
 
4233
    bool __initial = __read_mode();
 
4234
    char_type __1buf;
 
4235
    if (this->gptr() == 0)
 
4236
        this->setg(&__1buf, &__1buf+1, &__1buf+1);
 
4237
    const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
 
4238
    int_type __c = traits_type::eof();
 
4239
    if (this->gptr() == this->egptr())
 
4240
    {
 
4241
        memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
 
4242
        if (__always_noconv_)
 
4243
        {
 
4244
            streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
 
4245
            __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
 
4246
            if (__nmemb != 0)
 
4247
            {
 
4248
                this->setg(this->eback(),
 
4249
                           this->eback() + __unget_sz,
 
4250
                           this->eback() + __unget_sz + __nmemb);
 
4251
                __c = *this->gptr();
 
4252
            }
 
4253
        }
 
4254
        else
 
4255
        {
 
4256
            memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
 
4257
            __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
 
4258
            __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
 
4259
            streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
 
4260
                                 static_cast<streamsize>(__extbufend_ - __extbufnext_));
 
4261
            codecvt_base::result __r;
 
4262
            state_type __svs = __st_;
 
4263
            streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
 
4264
            if (__nr != 0)
 
4265
            {
 
4266
                __extbufend_ = __extbufnext_ + __nr;
 
4267
                char_type*  __inext;
 
4268
                __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
 
4269
                                       this->eback() + __unget_sz,
 
4270
                                       this->egptr(), __inext);
 
4271
                if (__r == codecvt_base::noconv)
 
4272
                {
 
4273
                    this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
 
4274
                    __c = *this->gptr();
 
4275
                }
 
4276
                else if (__inext != this->eback() + __unget_sz)
 
4277
                {
 
4278
                    this->setg(this->eback(), this->eback() + __unget_sz, __inext);
 
4279
                    __c = *this->gptr();
 
4280
                }
 
4281
            }
 
4282
        }
 
4283
    }
 
4284
    else
 
4285
        __c = *this->gptr();
 
4286
    if (this->eback() == &__1buf)
 
4287
        this->setg(0, 0, 0);
 
4288
    return __c;
 
4289
}
 
4290
 
 
4291
template <class _Codecvt, class _Elem, class _Tr>
 
4292
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
 
4293
wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
 
4294
{
 
4295
    if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
 
4296
    {
 
4297
        if (traits_type::eq_int_type(__c, traits_type::eof()))
 
4298
        {
 
4299
            this->gbump(-1);
 
4300
            return traits_type::not_eof(__c);
 
4301
        }
 
4302
        if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
 
4303
        {
 
4304
            this->gbump(-1);
 
4305
            *this->gptr() = traits_type::to_char_type(__c);
 
4306
            return __c;
 
4307
        }
 
4308
    }
 
4309
    return traits_type::eof();
 
4310
}
 
4311
 
 
4312
template <class _Codecvt, class _Elem, class _Tr>
 
4313
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
 
4314
wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
 
4315
{
 
4316
    if (__cv_ == 0 || __bufptr_ == 0)
 
4317
        return traits_type::eof();
 
4318
    __write_mode();
 
4319
    char_type __1buf;
 
4320
    char_type* __pb_save = this->pbase();
 
4321
    char_type* __epb_save = this->epptr();
 
4322
    if (!traits_type::eq_int_type(__c, traits_type::eof()))
 
4323
    {
 
4324
        if (this->pptr() == 0)
 
4325
            this->setp(&__1buf, &__1buf+1);
 
4326
        *this->pptr() = traits_type::to_char_type(__c);
 
4327
        this->pbump(1);
 
4328
    }
 
4329
    if (this->pptr() != this->pbase())
 
4330
    {
 
4331
        if (__always_noconv_)
 
4332
        {
 
4333
            streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
 
4334
            if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
 
4335
                return traits_type::eof();
 
4336
        }
 
4337
        else
 
4338
        {
 
4339
            char* __extbe = __extbuf_;
 
4340
            codecvt_base::result __r;
 
4341
            do
 
4342
            {
 
4343
                const char_type* __e;
 
4344
                __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
 
4345
                                        __extbuf_, __extbuf_ + __ebs_, __extbe);
 
4346
                if (__e == this->pbase())
 
4347
                    return traits_type::eof();
 
4348
                if (__r == codecvt_base::noconv)
 
4349
                {
 
4350
                    streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
 
4351
                    if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
 
4352
                        return traits_type::eof();
 
4353
                }
 
4354
                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
 
4355
                {
 
4356
                    streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
 
4357
                    if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
 
4358
                        return traits_type::eof();
 
4359
                    if (__r == codecvt_base::partial)
 
4360
                    {
 
4361
                        this->setp((char_type*)__e, this->pptr());
 
4362
                        this->pbump(this->epptr() - this->pbase());
 
4363
                    }
 
4364
                }
 
4365
                else
 
4366
                    return traits_type::eof();
 
4367
            } while (__r == codecvt_base::partial);
 
4368
        }
 
4369
        this->setp(__pb_save, __epb_save);
 
4370
    }
 
4371
    return traits_type::not_eof(__c);
 
4372
}
 
4373
 
 
4374
template <class _Codecvt, class _Elem, class _Tr>
 
4375
basic_streambuf<_Elem, _Tr>*
 
4376
wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
 
4377
{
 
4378
    this->setg(0, 0, 0);
 
4379
    this->setp(0, 0);
 
4380
    if (__owns_eb_)
 
4381
        delete [] __extbuf_;
 
4382
    if (__owns_ib_)
 
4383
        delete [] __intbuf_;
 
4384
    __ebs_ = __n;
 
4385
    if (__ebs_ > sizeof(__extbuf_min_))
 
4386
    {
 
4387
        if (__always_noconv_ && __s)
 
4388
        {
 
4389
            __extbuf_ = (char*)__s;
 
4390
            __owns_eb_ = false;
 
4391
        }
 
4392
        else
 
4393
        {
 
4394
            __extbuf_ = new char[__ebs_];
 
4395
            __owns_eb_ = true;
 
4396
        }
 
4397
    }
 
4398
    else
 
4399
    {
 
4400
        __extbuf_ = __extbuf_min_;
 
4401
        __ebs_ = sizeof(__extbuf_min_);
 
4402
        __owns_eb_ = false;
 
4403
    }
 
4404
    if (!__always_noconv_)
 
4405
    {
 
4406
        __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
 
4407
        if (__s && __ibs_ >= sizeof(__extbuf_min_))
 
4408
        {
 
4409
            __intbuf_ = __s;
 
4410
            __owns_ib_ = false;
 
4411
        }
 
4412
        else
 
4413
        {
 
4414
            __intbuf_ = new char_type[__ibs_];
 
4415
            __owns_ib_ = true;
 
4416
        }
 
4417
    }
 
4418
    else
 
4419
    {
 
4420
        __ibs_ = 0;
 
4421
        __intbuf_ = 0;
 
4422
        __owns_ib_ = false;
 
4423
    }
 
4424
    return this;
 
4425
}
 
4426
 
 
4427
template <class _Codecvt, class _Elem, class _Tr>
 
4428
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
 
4429
wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
 
4430
                                        ios_base::openmode __om)
 
4431
{
 
4432
    int __width = __cv_->encoding();
 
4433
    if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
 
4434
        return pos_type(off_type(-1));
 
4435
    // __width > 0 || __off == 0
 
4436
    switch (__way)
 
4437
    {
 
4438
    case ios_base::beg:
 
4439
        break;
 
4440
    case ios_base::cur:
 
4441
        break;
 
4442
    case ios_base::end:
 
4443
        break;
 
4444
    default:
 
4445
        return pos_type(off_type(-1));
 
4446
    }
 
4447
    pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
 
4448
    __r.state(__st_);
 
4449
    return __r;
 
4450
}
 
4451
 
 
4452
template <class _Codecvt, class _Elem, class _Tr>
 
4453
typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
 
4454
wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
 
4455
{
 
4456
    if (__cv_ == 0 || __bufptr_ == 0 || sync())
 
4457
        return pos_type(off_type(-1));
 
4458
    if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
 
4459
        return pos_type(off_type(-1));
 
4460
    return __sp;
 
4461
}
 
4462
 
 
4463
template <class _Codecvt, class _Elem, class _Tr>
 
4464
int
 
4465
wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
 
4466
{
 
4467
    if (__cv_ == 0 || __bufptr_ == 0)
 
4468
        return 0;
 
4469
    if (__cm_ & ios_base::out)
 
4470
    {
 
4471
        if (this->pptr() != this->pbase())
 
4472
            if (overflow() == traits_type::eof())
 
4473
                return -1;
 
4474
        codecvt_base::result __r;
 
4475
        do
 
4476
        {
 
4477
            char* __extbe;
 
4478
            __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
 
4479
            streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
 
4480
            if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
 
4481
                return -1;
 
4482
        } while (__r == codecvt_base::partial);
 
4483
        if (__r == codecvt_base::error)
 
4484
            return -1;
 
4485
        if (__bufptr_->pubsync())
 
4486
            return -1;
 
4487
    }
 
4488
    else if (__cm_ & ios_base::in)
 
4489
    {
 
4490
        off_type __c;
 
4491
        if (__always_noconv_)
 
4492
            __c = this->egptr() - this->gptr();
 
4493
        else
 
4494
        {
 
4495
            int __width = __cv_->encoding();
 
4496
            __c = __extbufend_ - __extbufnext_;
 
4497
            if (__width > 0)
 
4498
                __c += __width * (this->egptr() - this->gptr());
 
4499
            else
 
4500
            {
 
4501
                if (this->gptr() != this->egptr())
 
4502
                {
 
4503
                    reverse(this->gptr(), this->egptr());
 
4504
                    codecvt_base::result __r;
 
4505
                    const char_type* __e = this->gptr();
 
4506
                    char* __extbe;
 
4507
                    do
 
4508
                    {
 
4509
                        __r = __cv_->out(__st_, __e, this->egptr(), __e,
 
4510
                                         __extbuf_, __extbuf_ + __ebs_, __extbe);
 
4511
                        switch (__r)
 
4512
                        {
 
4513
                        case codecvt_base::noconv:
 
4514
                            __c += this->egptr() - this->gptr();
 
4515
                            break;
 
4516
                        case codecvt_base::ok:
 
4517
                        case codecvt_base::partial:
 
4518
                            __c += __extbe - __extbuf_;
 
4519
                            break;
 
4520
                        default:
 
4521
                            return -1;
 
4522
                        }
 
4523
                    } while (__r == codecvt_base::partial);
 
4524
                }
 
4525
            }
 
4526
        }
 
4527
        if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
 
4528
            return -1;
 
4529
        this->setg(0, 0, 0);
 
4530
        __cm_ = 0;
 
4531
    }
 
4532
    return 0;
 
4533
}
 
4534
 
 
4535
template <class _Codecvt, class _Elem, class _Tr>
 
4536
bool
 
4537
wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
 
4538
{
 
4539
    if (!(__cm_ & ios_base::in))
 
4540
    {
 
4541
        this->setp(0, 0);
 
4542
        if (__always_noconv_)
 
4543
            this->setg((char_type*)__extbuf_,
 
4544
                       (char_type*)__extbuf_ + __ebs_,
 
4545
                       (char_type*)__extbuf_ + __ebs_);
 
4546
        else
 
4547
            this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
 
4548
        __cm_ = ios_base::in;
 
4549
        return true;
 
4550
    }
 
4551
    return false;
 
4552
}
 
4553
 
 
4554
template <class _Codecvt, class _Elem, class _Tr>
 
4555
void
 
4556
wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
 
4557
{
 
4558
    if (!(__cm_ & ios_base::out))
 
4559
    {
 
4560
        this->setg(0, 0, 0);
 
4561
        if (__ebs_ > sizeof(__extbuf_min_))
 
4562
        {
 
4563
            if (__always_noconv_)
 
4564
                this->setp((char_type*)__extbuf_,
 
4565
                           (char_type*)__extbuf_ + (__ebs_ - 1));
 
4566
            else
 
4567
                this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
 
4568
        }
 
4569
        else
 
4570
            this->setp(0, 0);
 
4571
        __cm_ = ios_base::out;
 
4572
    }
 
4573
}
 
4574
 
 
4575
template <class _Codecvt, class _Elem, class _Tr>
 
4576
wbuffer_convert<_Codecvt, _Elem, _Tr>*
 
4577
wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
 
4578
{
 
4579
    wbuffer_convert* __rt = 0;
 
4580
    if (__cv_ != 0 && __bufptr_ != 0)
 
4581
    {
 
4582
        __rt = this;
 
4583
        if ((__cm_ & ios_base::out) && sync())
 
4584
            __rt = 0;
 
4585
    }
 
4586
    return __rt;
 
4587
}
 
4588
 
 
4589
_LIBCPP_END_NAMESPACE_STD
 
4590
 
 
4591
#endif  // _LIBCPP_LOCALE