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