Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | // Locale support -*- C++ -*- |
2 | |||
3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. |
||
4 | // |
||
5 | // This file is part of the GNU ISO C++ Library. This library is free |
||
6 | // software; you can redistribute it and/or modify it under the |
||
7 | // terms of the GNU General Public License as published by the |
||
8 | // Free Software Foundation; either version 2, or (at your option) |
||
9 | // any later version. |
||
10 | |||
11 | // This library is distributed in the hope that it will be useful, |
||
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | // GNU General Public License for more details. |
||
15 | |||
16 | // You should have received a copy of the GNU General Public License along |
||
17 | // with this library; see the file COPYING. If not, write to the Free |
||
18 | // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
||
19 | // USA. |
||
20 | |||
21 | // As a special exception, you may use this file as part of a free software |
||
22 | // library without restriction. Specifically, if other files instantiate |
||
23 | // templates or use macros or inline functions from this file, or you compile |
||
24 | // this file and link it with other files to produce an executable, this |
||
25 | // file does not by itself cause the resulting executable to be covered by |
||
26 | // the GNU General Public License. This exception does not however |
||
27 | // invalidate any other reasons why the executable file might be covered by |
||
28 | // the GNU General Public License. |
||
29 | |||
30 | // Warning: this file is not meant for user inclusion. Use |
||
31 | |||
32 | #ifndef _CPP_BITS_LOCFACETS_TCC |
||
33 | #define _CPP_BITS_LOCFACETS_TCC 1 |
||
34 | |||
35 | #include |
||
36 | #include |
||
37 | #include |
||
38 | #include |
||
39 | #include |
||
40 | #include |
||
41 | #include |
||
42 | #include |
||
43 | #include |
||
44 | |||
45 | |||
46 | namespace std |
||
47 | { |
||
48 | template |
||
49 | locale |
||
50 | locale::combine(const locale& __other) |
||
51 | { |
||
52 | locale __copy(*this); |
||
53 | __copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id); |
||
54 | return __copy; |
||
55 | } |
||
56 | |||
57 | template |
||
58 | bool |
||
59 | locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, |
||
60 | const basic_string<_CharT, _Traits, _Alloc>& __s2) const |
||
61 | { |
||
62 | typedef std::collate<_CharT> __collate_type; |
||
63 | const __collate_type* __fcoll = &use_facet<__collate_type>(*this); |
||
64 | return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(), |
||
65 | __s2.data(), __s2.data() + __s2.length()) < 0); |
||
66 | } |
||
67 | |||
68 | template |
||
69 | const _Facet& |
||
70 | use_facet(const locale& __loc) |
||
71 | { |
||
72 | typedef locale::_Impl::__vec_facet __vec_facet; |
||
73 | size_t __i = _Facet::id._M_index; |
||
74 | __vec_facet* __facet = __loc._M_impl->_M_facets; |
||
75 | const locale::facet* __fp = (*__facet)[__i]; |
||
76 | if (__fp == 0 || __i >= __facet->size()) |
||
77 | __throw_bad_cast(); |
||
78 | return static_cast |
||
79 | } |
||
80 | |||
81 | template |
||
82 | bool |
||
83 | has_facet(const locale& __loc) throw() |
||
84 | { |
||
85 | typedef locale::_Impl::__vec_facet __vec_facet; |
||
86 | size_t __i = _Facet::id._M_index; |
||
87 | __vec_facet* __facet = __loc._M_impl->_M_facets; |
||
88 | return (__i < __facet->size() && (*__facet)[__i] != 0); |
||
89 | } |
||
90 | |||
91 | // __match_parallel |
||
92 | // matches input __s against a set of __ntargs strings in __targets, |
||
93 | // placing in __matches a vector of indices into __targets which |
||
94 | // match, and in __remain the number of such matches. If it hits |
||
95 | // end of sequence before it minimizes the set, sets __eof. |
||
96 | // Empty strings are never matched. |
||
97 | template |
||
98 | _InIter |
||
99 | __match_parallel(_InIter __s, _InIter __end, int __ntargs, |
||
100 | const basic_string<_CharT>* __targets, |
||
101 | int* __matches, int& __remain, bool& __eof) |
||
102 | { |
||
103 | typedef basic_string<_CharT> __string_type; |
||
104 | __eof = false; |
||
105 | for (int __ti = 0; __ti < __ntargs; ++__ti) |
||
106 | __matches[__ti] = __ti; |
||
107 | __remain = __ntargs; |
||
108 | size_t __pos = 0; |
||
109 | do |
||
110 | { |
||
111 | int __ti = 0; |
||
112 | while (__ti < __remain && __pos == __targets[__matches[__ti]].size()) |
||
113 | ++__ti; |
||
114 | if (__ti == __remain) |
||
115 | { |
||
116 | if (__pos == 0) __remain = 0; |
||
117 | return __s; |
||
118 | } |
||
119 | if (__s == __end) |
||
120 | __eof = true; |
||
121 | bool __matched = false; |
||
122 | for (int __ti2 = 0; __ti2 < __remain; ) |
||
123 | { |
||
124 | const __string_type& __target = __targets[__matches[__ti2]]; |
||
125 | if (__pos < __target.size()) |
||
126 | { |
||
127 | if (__eof || __target[__pos] != *__s) |
||
128 | { |
||
129 | __matches[__ti2] = __matches[--__remain]; |
||
130 | continue; |
||
131 | } |
||
132 | __matched = true; |
||
133 | } |
||
134 | ++__ti2; |
||
135 | } |
||
136 | if (__matched) |
||
137 | { |
||
138 | ++__s; |
||
139 | ++__pos; |
||
140 | } |
||
141 | for (int __ti3 = 0; __ti3 < __remain;) |
||
142 | { |
||
143 | if (__pos > __targets[__matches[__ti3]].size()) |
||
144 | { |
||
145 | __matches[__ti3] = __matches[--__remain]; |
||
146 | continue; |
||
147 | } |
||
148 | ++__ti3; |
||
149 | } |
||
150 | } |
||
151 | while (__remain); |
||
152 | return __s; |
||
153 | } |
||
154 | |||
155 | template |
||
156 | _Format_cache<_CharT>::_Format_cache() |
||
157 | : _M_valid(true), _M_use_grouping(false) |
||
158 | { } |
||
159 | |||
160 | template<> |
||
161 | _Format_cache |
||
162 | |||
163 | template<> |
||
164 | _Format_cache |
||
165 | |||
166 | template |
||
167 | void |
||
168 | _Format_cache<_CharT>::_M_populate(ios_base& __io) |
||
169 | { |
||
170 | locale __loc = __io.getloc (); |
||
171 | numpunct<_CharT> const& __np = use_facet |
||
172 | _M_truename = __np.truename(); |
||
173 | _M_falsename = __np.falsename(); |
||
174 | _M_thousands_sep = __np.thousands_sep(); |
||
175 | _M_decimal_point = __np.decimal_point(); |
||
176 | _M_grouping = __np.grouping(); |
||
177 | _M_use_grouping = _M_grouping.size() != 0 && _M_grouping.data()[0] != 0; |
||
178 | _M_valid = true; |
||
179 | } |
||
180 | |||
181 | // This function is always called via a pointer installed in |
||
182 | // an ios_base by ios_base::register_callback. |
||
183 | template |
||
184 | void |
||
185 | _Format_cache<_CharT>:: |
||
186 | _S_callback(ios_base::event __ev, ios_base& __ios, int __ix) throw() |
||
187 | { |
||
188 | void*& __p = __ios.pword(__ix); |
||
189 | switch (__ev) |
||
190 | { |
||
191 | case ios_base::erase_event: |
||
192 | delete static_cast<_Format_cache<_CharT>*>(__p); |
||
193 | __p = 0; |
||
194 | break; |
||
195 | case ios_base::copyfmt_event: |
||
196 | // If just stored zero, the callback would get registered again. |
||
197 | try |
||
198 | { __p = new _Format_cache<_CharT>; } |
||
199 | catch(...) |
||
200 | { } |
||
201 | break; |
||
202 | case ios_base::imbue_event: |
||
203 | static_cast<_Format_cache<_CharT>*>(__p)->_M_valid = false; |
||
204 | break; |
||
205 | } |
||
206 | } |
||
207 | |||
208 | template |
||
209 | _Format_cache<_CharT>* |
||
210 | _Format_cache<_CharT>::_S_get(ios_base& __ios) |
||
211 | { |
||
212 | if (!_S_pword_ix) |
||
213 | _S_pword_ix = ios_base::xalloc(); // XXX MT |
||
214 | void*& __p = __ios.pword(_S_pword_ix); |
||
215 | |||
216 | // XXX What if pword fails? must check failbit, throw. |
||
217 | if (__p == 0) // XXX MT? maybe sentry takes care of it |
||
218 | { |
||
219 | auto_ptr<_Format_cache<_CharT> > __ap(new _Format_cache<_CharT>); |
||
220 | __ios.register_callback(&_Format_cache<_CharT>::_S_callback, |
||
221 | _S_pword_ix); |
||
222 | __p = __ap.release(); |
||
223 | } |
||
224 | _Format_cache<_CharT>* __ncp = static_cast<_Format_cache<_CharT>*>(__p); |
||
225 | if (!__ncp->_M_valid) |
||
226 | __ncp->_M_populate(__ios); |
||
227 | |||
228 | return __ncp; |
||
229 | } |
||
230 | |||
231 | // This member function takes an (w)istreambuf_iterator object and |
||
232 | // parses it into a generic char array suitable for parsing with |
||
233 | // strto[l,ll,f,d]. The thought was to encapsulate the conversion |
||
234 | // into this one function, and thus the num_get::do_get member |
||
235 | // functions can just adjust for the type of the overloaded |
||
236 | // argument and process the char array returned from _M_extract. |
||
237 | // Other things were also considered, including a fused |
||
238 | // multiply-add loop that would obviate the need for any call to |
||
239 | // strto... at all: however, it would b e a bit of a pain, because |
||
240 | // you'd have to be able to return either floating or integral |
||
241 | // types, etc etc. The current approach seems to be smack dab in |
||
242 | // the middle between an unoptimized approach using sscanf, and |
||
243 | // some kind of hyper-optimized approach alluded to above. |
||
244 | |||
245 | // XXX |
||
246 | // Need to do partial specialization to account for differences |
||
247 | // between character sets. For char, this is pretty |
||
248 | // straightforward, but for wchar_t, the conversion to a plain-jane |
||
249 | // char type is a bit more involved. |
||
250 | template |
||
251 | void |
||
252 | num_get<_CharT, _InIter>:: |
||
253 | _M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/, |
||
254 | ios_base::iostate& /*__err*/, char* /*__xtrc*/, |
||
255 | int& /*__base*/, bool /*__fp*/) const |
||
256 | { |
||
257 | // XXX Not currently done: need to expand upon char version below. |
||
258 | } |
||
259 | |||
260 | template<> |
||
261 | void |
||
262 | num_get |
||
263 | _M_extract(istreambuf_iterator |
||
264 | istreambuf_iterator |
||
265 | ios_base::iostate& __err, char* __xtrc, int& __base, |
||
266 | bool __fp) const; |
||
267 | |||
268 | #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS |
||
269 | // NB: This is an unresolved library defect #17 |
||
270 | template |
||
271 | _InIter |
||
272 | num_get<_CharT, _InIter>:: |
||
273 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
274 | ios_base::iostate& __err, bool& __v) const |
||
275 | { |
||
276 | // Parse bool values as long |
||
277 | if (!(__io.flags() & ios_base::boolalpha)) |
||
278 | { |
||
279 | // NB: We can't just call do_get(long) here, as it might |
||
280 | // refer to a derived class. |
||
281 | |||
282 | // Stage 1: extract and determine the conversion specifier. |
||
283 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
284 | // integral types. |
||
285 | char __xtrc[32] = {'\0'}; |
||
286 | int __base; |
||
287 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
288 | |||
289 | // Stage 2: convert and store results. |
||
290 | char* __sanity; |
||
291 | errno = 0; |
||
292 | long __l = strtol(__xtrc, &__sanity, __base); |
||
293 | if (!(__err & ios_base::failbit) |
||
294 | && __l <= 1 |
||
295 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
296 | __v = __l; |
||
297 | else |
||
298 | __err |= ios_base::failbit; |
||
299 | } |
||
300 | |||
301 | // Parse bool values as alphanumeric |
||
302 | else |
||
303 | { |
||
304 | typedef _Format_cache |
||
305 | __fcache_type* __fmt = __fcache_type::_S_get(__io); |
||
306 | const char_type* __true = __fmt->_M_truename.c_str(); |
||
307 | const char_type* __false = __fmt->_M_falsename.c_str(); |
||
308 | const size_t __truelen = __traits_type::length(__true) - 1; |
||
309 | const size_t __falselen = __traits_type::length(__false) - 1; |
||
310 | |||
311 | for (size_t __pos = 0; __beg != __end; ++__pos) |
||
312 | { |
||
313 | char_type __c = *__beg++; |
||
314 | bool __testf = __c == __false[__pos]; |
||
315 | bool __testt = __c == __true[__pos]; |
||
316 | if (!(__testf || __testt)) |
||
317 | { |
||
318 | __err |= ios_base::failbit; |
||
319 | break; |
||
320 | } |
||
321 | else if (__testf && __pos == __falselen) |
||
322 | { |
||
323 | __v = 0; |
||
324 | break; |
||
325 | } |
||
326 | else if (__testt && __pos == __truelen) |
||
327 | { |
||
328 | __v = 1; |
||
329 | break; |
||
330 | } |
||
331 | } |
||
332 | if (__beg == __end) |
||
333 | __err |= ios_base::eofbit; |
||
334 | } |
||
335 | |||
336 | return __beg; |
||
337 | } |
||
338 | #endif |
||
339 | |||
340 | #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS |
||
341 | template |
||
342 | _InIter |
||
343 | num_get<_CharT, _InIter>:: |
||
344 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
345 | ios_base::iostate& __err, short& __v) const |
||
346 | { |
||
347 | // Stage 1: extract and determine the conversion specifier. |
||
348 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
349 | // integral types. |
||
350 | char __xtrc[32]= {'\0'}; |
||
351 | int __base; |
||
352 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
353 | |||
354 | // Stage 2: convert and store results. |
||
355 | char* __sanity; |
||
356 | errno = 0; |
||
357 | long __l = strtol(__xtrc, &__sanity, __base); |
||
358 | if (!(__err & ios_base::failbit) |
||
359 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0 |
||
360 | && __l >= SHRT_MIN && __l <= SHRT_MAX) |
||
361 | __v = static_cast |
||
362 | else |
||
363 | __err |= ios_base::failbit; |
||
364 | |||
365 | return __beg; |
||
366 | } |
||
367 | |||
368 | template |
||
369 | _InIter |
||
370 | num_get<_CharT, _InIter>:: |
||
371 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
372 | ios_base::iostate& __err, int& __v) const |
||
373 | { |
||
374 | // Stage 1: extract and determine the conversion specifier. |
||
375 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
376 | // integral types. |
||
377 | char __xtrc[32] = {'\0'}; |
||
378 | int __base; |
||
379 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
380 | |||
381 | // Stage 2: convert and store results. |
||
382 | char* __sanity; |
||
383 | errno = 0; |
||
384 | long __l = strtol(__xtrc, &__sanity, __base); |
||
385 | if (!(__err & ios_base::failbit) |
||
386 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0 |
||
387 | && __l >= INT_MIN && __l <= INT_MAX) |
||
388 | __v = static_cast |
||
389 | else |
||
390 | __err |= ios_base::failbit; |
||
391 | |||
392 | return __beg; |
||
393 | } |
||
394 | #endif |
||
395 | |||
396 | template |
||
397 | _InIter |
||
398 | num_get<_CharT, _InIter>:: |
||
399 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
400 | ios_base::iostate& __err, long& __v) const |
||
401 | { |
||
402 | // Stage 1: extract and determine the conversion specifier. |
||
403 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
404 | // integral types. |
||
405 | char __xtrc[32]= {'\0'}; |
||
406 | int __base; |
||
407 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
408 | |||
409 | // Stage 2: convert and store results. |
||
410 | char* __sanity; |
||
411 | errno = 0; |
||
412 | long __l = strtol(__xtrc, &__sanity, __base); |
||
413 | if (!(__err & ios_base::failbit) |
||
414 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
415 | __v = __l; |
||
416 | else |
||
417 | __err |= ios_base::failbit; |
||
418 | |||
419 | return __beg; |
||
420 | } |
||
421 | |||
422 | #ifdef _GLIBCPP_USE_LONG_LONG |
||
423 | template |
||
424 | _InIter |
||
425 | num_get<_CharT, _InIter>:: |
||
426 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
427 | ios_base::iostate& __err, long long& __v) const |
||
428 | { |
||
429 | // Stage 1: extract and determine the conversion specifier. |
||
430 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
431 | // integral types. |
||
432 | char __xtrc[32]= {'\0'}; |
||
433 | int __base; |
||
434 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
435 | |||
436 | // Stage 2: convert and store results. |
||
437 | char* __sanity; |
||
438 | errno = 0; |
||
439 | long long __ll = strtoll(__xtrc, &__sanity, __base); |
||
440 | if (!(__err & ios_base::failbit) |
||
441 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
442 | __v = __ll; |
||
443 | else |
||
444 | __err |= ios_base::failbit; |
||
445 | |||
446 | return __beg; |
||
447 | } |
||
448 | #endif |
||
449 | |||
450 | template |
||
451 | _InIter |
||
452 | num_get<_CharT, _InIter>:: |
||
453 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
454 | ios_base::iostate& __err, unsigned short& __v) const |
||
455 | { |
||
456 | // Stage 1: extract and determine the conversion specifier. |
||
457 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
458 | // integral types. |
||
459 | char __xtrc[32]= {'\0'}; |
||
460 | int __base; |
||
461 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
462 | |||
463 | // Stage 2: convert and store results. |
||
464 | char* __sanity; |
||
465 | errno = 0; |
||
466 | unsigned long __ul = strtoul(__xtrc, &__sanity, __base); |
||
467 | if (!(__err & ios_base::failbit) |
||
468 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0 |
||
469 | && __ul <= USHRT_MAX) |
||
470 | __v = static_cast |
||
471 | else |
||
472 | __err |= ios_base::failbit; |
||
473 | |||
474 | return __beg; |
||
475 | } |
||
476 | |||
477 | template |
||
478 | _InIter |
||
479 | num_get<_CharT, _InIter>:: |
||
480 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
481 | ios_base::iostate& __err, unsigned int& __v) const |
||
482 | { |
||
483 | // Stage 1: extract and determine the conversion specifier. |
||
484 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
485 | // integral types. |
||
486 | char __xtrc[32]= {'\0'}; |
||
487 | int __base; |
||
488 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
489 | |||
490 | // Stage 2: convert and store results. |
||
491 | char* __sanity; |
||
492 | errno = 0; |
||
493 | unsigned long __ul = strtoul(__xtrc, &__sanity, __base); |
||
494 | if (!(__err & ios_base::failbit) |
||
495 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0 |
||
496 | && __ul <= UINT_MAX) |
||
497 | __v = static_cast |
||
498 | else |
||
499 | __err |= ios_base::failbit; |
||
500 | |||
501 | return __beg; |
||
502 | } |
||
503 | |||
504 | template |
||
505 | _InIter |
||
506 | num_get<_CharT, _InIter>:: |
||
507 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
508 | ios_base::iostate& __err, unsigned long& __v) const |
||
509 | { |
||
510 | // Stage 1: extract and determine the conversion specifier. |
||
511 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
512 | // integral types. |
||
513 | char __xtrc[32] = {'\0'}; |
||
514 | int __base; |
||
515 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
516 | |||
517 | // Stage 2: convert and store results. |
||
518 | char* __sanity; |
||
519 | errno = 0; |
||
520 | unsigned long __ul = strtoul(__xtrc, &__sanity, __base); |
||
521 | if (!(__err & ios_base::failbit) |
||
522 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
523 | __v = __ul; |
||
524 | else |
||
525 | __err |= ios_base::failbit; |
||
526 | |||
527 | return __beg; |
||
528 | } |
||
529 | |||
530 | #ifdef _GLIBCPP_USE_LONG_LONG |
||
531 | template |
||
532 | _InIter |
||
533 | num_get<_CharT, _InIter>:: |
||
534 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
535 | ios_base::iostate& __err, unsigned long long& __v) const |
||
536 | { |
||
537 | // Stage 1: extract and determine the conversion specifier. |
||
538 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
539 | // integral types. |
||
540 | char __xtrc[32]= {'\0'}; |
||
541 | int __base; |
||
542 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
543 | |||
544 | // Stage 2: convert and store results. |
||
545 | char* __sanity; |
||
546 | errno = 0; |
||
547 | unsigned long long __ull = strtoull(__xtrc, &__sanity, __base); |
||
548 | if (!(__err & ios_base::failbit) |
||
549 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
550 | __v = __ull; |
||
551 | else |
||
552 | __err |= ios_base::failbit; |
||
553 | |||
554 | return __beg; |
||
555 | } |
||
556 | #endif |
||
557 | |||
558 | template |
||
559 | _InIter |
||
560 | num_get<_CharT, _InIter>:: |
||
561 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
562 | ios_base::iostate& __err, float& __v) const |
||
563 | { |
||
564 | // Stage 1: extract and determine the conversion specifier. |
||
565 | // Assuming leading zeros eliminated, thus the size of 256 for |
||
566 | // floating-point types. |
||
567 | char __xtrc[32]= {'\0'}; |
||
568 | int __base; |
||
569 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, true); |
||
570 | |||
571 | // Stage 2: convert and store results. |
||
572 | char* __sanity; |
||
573 | errno = 0; |
||
574 | #ifdef _GLIBCPP_USE_C99 |
||
575 | float __f = strtof(__xtrc, &__sanity); |
||
576 | #else |
||
577 | float __f = static_cast |
||
578 | #endif |
||
579 | if (!(__err & ios_base::failbit) |
||
580 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
581 | __v = __f; |
||
582 | else |
||
583 | __err |= ios_base::failbit; |
||
584 | |||
585 | return __beg; |
||
586 | } |
||
587 | |||
588 | template |
||
589 | _InIter |
||
590 | num_get<_CharT, _InIter>:: |
||
591 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
592 | ios_base::iostate& __err, double& __v) const |
||
593 | { |
||
594 | // Stage 1: extract and determine the conversion specifier. |
||
595 | // Assuming leading zeros eliminated, thus the size of 256 for |
||
596 | // floating-point types. |
||
597 | char __xtrc[32]= {'\0'}; |
||
598 | int __base; |
||
599 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, true); |
||
600 | |||
601 | // Stage 2: convert and store results. |
||
602 | char* __sanity; |
||
603 | errno = 0; |
||
604 | double __d = strtod(__xtrc, &__sanity); |
||
605 | if (!(__err & ios_base::failbit) |
||
606 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
607 | __v = __d; |
||
608 | else |
||
609 | __err |= ios_base::failbit; |
||
610 | |||
611 | return __beg; |
||
612 | } |
||
613 | |||
614 | #if defined(_GLIBCPP_USE_C99) && !defined(__hpux) |
||
615 | template |
||
616 | _InIter |
||
617 | num_get<_CharT, _InIter>:: |
||
618 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
619 | ios_base::iostate& __err, long double& __v) const |
||
620 | { |
||
621 | // Stage 1: extract and determine the conversion specifier. |
||
622 | // Assuming leading zeros eliminated, thus the size of 256 for |
||
623 | // floating-point types. |
||
624 | char __xtrc[32]= {'\0'}; |
||
625 | int __base; |
||
626 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, true); |
||
627 | |||
628 | // Stage 2: convert and store results. |
||
629 | char* __sanity; |
||
630 | errno = 0; |
||
631 | long double __ld = strtold(__xtrc, &__sanity); |
||
632 | if (!(__err & ios_base::failbit) |
||
633 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
634 | __v = __ld; |
||
635 | else |
||
636 | __err |= ios_base::failbit; |
||
637 | |||
638 | return __beg; |
||
639 | } |
||
640 | #else |
||
641 | template |
||
642 | _InIter |
||
643 | num_get<_CharT, _InIter>:: |
||
644 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
645 | ios_base::iostate& __err, long double& __v) const |
||
646 | { |
||
647 | // Stage 1: extract |
||
648 | char __xtrc[32]= {'\0'}; |
||
649 | int __base; |
||
650 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, true); |
||
651 | |||
652 | // Stage 2: determine a conversion specifier. |
||
653 | ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; |
||
654 | const char* __conv; |
||
655 | if (__basefield == ios_base::oct) |
||
656 | __conv = "%Lo"; |
||
657 | else if (__basefield == ios_base::hex) |
||
658 | __conv = "%LX"; |
||
659 | else if (__basefield == 0) |
||
660 | __conv = "%Li"; |
||
661 | else |
||
662 | __conv = "%Lg"; |
||
663 | |||
664 | // Stage 3: store results. |
||
665 | long double __ld; |
||
666 | int __p = sscanf(__xtrc, __conv, &__ld); |
||
667 | if (__p |
||
668 | && static_cast |
||
669 | != __traits_type::eof()) |
||
670 | __v = __ld; |
||
671 | else |
||
672 | __err |= ios_base::failbit; |
||
673 | |||
674 | return __beg; |
||
675 | } |
||
676 | #endif |
||
677 | |||
678 | template |
||
679 | _InIter |
||
680 | num_get<_CharT, _InIter>:: |
||
681 | do_get(iter_type __beg, iter_type __end, ios_base& __io, |
||
682 | ios_base::iostate& __err, void*& __v) const |
||
683 | { |
||
684 | // Prepare for hex formatted input |
||
685 | typedef ios_base::fmtflags fmtflags; |
||
686 | fmtflags __fmt = __io.flags(); |
||
687 | fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield |
||
688 | | ios_base::uppercase | ios_base::internal); |
||
689 | __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase)); |
||
690 | |||
691 | // Stage 1: extract and determine the conversion specifier. |
||
692 | // Assuming leading zeros eliminated, thus the size of 32 for |
||
693 | // integral types. |
||
694 | char __xtrc[32]= {'\0'}; |
||
695 | int __base; |
||
696 | _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); |
||
697 | |||
698 | // Stage 2: convert and store results. |
||
699 | char* __sanity; |
||
700 | errno = 0; |
||
701 | void* __vp = reinterpret_cast |
||
702 | if (!(__err & ios_base::failbit) |
||
703 | && __sanity != __xtrc && *__sanity == '\0' && errno == 0) |
||
704 | __v = __vp; |
||
705 | else |
||
706 | __err |= ios_base::failbit; |
||
707 | |||
708 | // Reset from hex formatted input |
||
709 | __io.flags(__fmt); |
||
710 | return __beg; |
||
711 | } |
||
712 | |||
713 | // __pad is specialized for ostreambuf_iterator, random access iterator. |
||
714 | template |
||
715 | inline _OutIter |
||
716 | __pad(_OutIter __s, _CharT __fill, int __padding); |
||
717 | |||
718 | template |
||
719 | _RaIter |
||
720 | __pad(_RaIter __s, _CharT __fill, int __padding, |
||
721 | random_access_iterator_tag) |
||
722 | { |
||
723 | fill_n(__s, __fill); |
||
724 | return __s + __padding; |
||
725 | } |
||
726 | |||
727 | template |
||
728 | _OutIter |
||
729 | __pad(_OutIter __s, _CharT __fill, int __padding, _Tag) |
||
730 | { |
||
731 | while (--__padding >= 0) { *__s = __fill; ++__s; } |
||
732 | return __s; |
||
733 | } |
||
734 | |||
735 | template |
||
736 | inline _OutIter |
||
737 | __pad(_OutIter __s, _CharT __fill, int __padding) |
||
738 | { |
||
739 | return __pad(__s, __fill, __padding, |
||
740 | typename iterator_traits<_OutIter>::iterator_category()); |
||
741 | } |
||
742 | |||
743 | template |
||
744 | _OutIter |
||
745 | __pad_numeric(_OutIter __s, ios_base::fmtflags /*__flags*/, |
||
746 | _CharT /*__fill*/, int /*__width*/, |
||
747 | _CharT const* /*__first*/, _CharT const* /*__middle*/, |
||
748 | _CharT const* /*__last*/) |
||
749 | { |
||
750 | // XXX Not currently done: non streambuf_iterator |
||
751 | return __s; |
||
752 | } |
||
753 | |||
754 | // Partial specialization for ostreambuf_iterator. |
||
755 | template |
||
756 | ostreambuf_iterator<_CharT> |
||
757 | __pad_numeric(ostreambuf_iterator<_CharT> __s, ios_base::fmtflags __flags, |
||
758 | _CharT __fill, int __width, _CharT const* __first, |
||
759 | _CharT const* __middle, _CharT const* __last) |
||
760 | { |
||
761 | typedef ostreambuf_iterator<_CharT> __out_iter; |
||
762 | int __padding = __width - (__last - __first); |
||
763 | if (__padding < 0) |
||
764 | __padding = 0; |
||
765 | ios_base::fmtflags __aflags = __flags & ios_base::adjustfield; |
||
766 | bool __testfield = __padding == 0 || __aflags == ios_base::left |
||
767 | || __aflags == ios_base::internal; |
||
768 | |||
769 | // This was needlessly complicated. |
||
770 | if (__first != __middle) |
||
771 | { |
||
772 | if (!__testfield) |
||
773 | { |
||
774 | __pad(__s, __fill, __padding); |
||
775 | __padding = 0; |
||
776 | } |
||
777 | copy(__first, __middle, __s); |
||
778 | } |
||
779 | __out_iter __s2 = __s; |
||
780 | |||
781 | if (__padding && __aflags != ios_base::left) |
||
782 | { |
||
783 | __pad(__s2, __fill, __padding); |
||
784 | __padding = 0; |
||
785 | } |
||
786 | __out_iter __s3 = copy(__middle, __last, __s2); |
||
787 | if (__padding) |
||
788 | __pad(__s3, __fill, __padding); |
||
789 | return __s3; |
||
790 | } |
||
791 | |||
792 | template |
||
793 | _OutIter |
||
794 | num_put<_CharT, _OutIter>:: |
||
795 | do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const |
||
796 | { |
||
797 | const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io); |
||
798 | ios_base::fmtflags __flags = __io.flags(); |
||
799 | |||
800 | if ((__flags & ios_base::boolalpha) == 0) |
||
801 | { |
||
802 | unsigned long __uv = __v; |
||
803 | return __output_integer(__s, __io, __fill, false, __uv); |
||
804 | } |
||
805 | else |
||
806 | { |
||
807 | const char_type* __first; |
||
808 | const char_type* __last; |
||
809 | if (__v) |
||
810 | { |
||
811 | __first = __fmt->_M_truename.data(); |
||
812 | __last = __first + __fmt->_M_truename.size(); |
||
813 | } |
||
814 | else |
||
815 | { |
||
816 | __first = __fmt->_M_falsename.data(); |
||
817 | __last = __first + __fmt->_M_falsename.size(); |
||
818 | } |
||
819 | copy(__first, __last, __s); |
||
820 | } |
||
821 | return __s; |
||
822 | } |
||
823 | |||
824 | // __group_digits inserts "group separator" characters into an array |
||
825 | // of characters. It's recursive, one iteration per group. It moves |
||
826 | // the characters in the buffer this way: "xxxx12345" -> "12,345xxx". |
||
827 | // Call this only with __grouping != __grend. |
||
828 | template |
||
829 | _CharT* |
||
830 | __group_digits(_CharT* __s, _CharT __grsep, char const* __grouping, |
||
831 | char const* __grend, _CharT const* __first, |
||
832 | _CharT const* __last) |
||
833 | { |
||
834 | if (__last - __first > *__grouping) |
||
835 | { |
||
836 | __s = __group_digits(__s, __grsep, |
||
837 | (__grouping + 1 == __grend ? __grouping : __grouping + 1), |
||
838 | __grend, __first, __last - *__grouping); |
||
839 | __first = __last - *__grouping; |
||
840 | *__s++ = __grsep; |
||
841 | } |
||
842 | do |
||
843 | { |
||
844 | *__s++ = *__first++; |
||
845 | } |
||
846 | while (__first != __last); |
||
847 | return __s; |
||
848 | } |
||
849 | |||
850 | template |
||
851 | _OutIter |
||
852 | __output_integer(_OutIter __s, ios_base& __io, _CharT __fill, bool __neg, |
||
853 | _ValueT __v) |
||
854 | { |
||
855 | // Leave room for "+/-," "0x," and commas. |
||
856 | const long _M_room = numeric_limits<_ValueT>::digits10 * 2 + 4; |
||
857 | _CharT __digits[_M_room]; |
||
858 | _CharT* __front = __digits + _M_room; |
||
859 | ios_base::fmtflags __flags = __io.flags(); |
||
860 | const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io); |
||
861 | char const* __table = __fmt->_S_literals + __fmt->_S_digits; |
||
862 | |||
863 | ios_base::fmtflags __basefield = (__flags & __io.basefield); |
||
864 | _CharT* __sign_end = __front; |
||
865 | if (__basefield == ios_base::hex) |
||
866 | { |
||
867 | if (__flags & ios_base::uppercase) |
||
868 | __table += 16; // use ABCDEF |
||
869 | do |
||
870 | *--__front = __table[__v & 15]; |
||
871 | while ((__v >>= 4) != 0); |
||
872 | __sign_end = __front; |
||
873 | if (__flags & ios_base::showbase) |
||
874 | { |
||
875 | *--__front = __fmt->_S_literals[__fmt->_S_x + |
||
876 | ((__flags & ios_base::uppercase) ? 1 : 0)]; |
||
877 | *--__front = __table[0]; |
||
878 | } |
||
879 | } |
||
880 | else if (__basefield == ios_base::oct) |
||
881 | { |
||
882 | do |
||
883 | *--__front = __table[__v & 7]; |
||
884 | while ((__v >>= 3) != 0); |
||
885 | if (__flags & ios_base::showbase |
||
886 | && static_cast |
||
887 | *--__front = __table[0]; |
||
888 | __sign_end = __front; |
||
889 | } |
||
890 | else |
||
891 | { |
||
892 | // NB: This is _lots_ faster than using ldiv. |
||
893 | do |
||
894 | *--__front = __table[__v % 10]; |
||
895 | while ((__v /= 10) != 0); |
||
896 | __sign_end = __front; |
||
897 | // NB: ios_base:hex || ios_base::oct assumed to be unsigned. |
||
898 | if (__neg || (__flags & ios_base::showpos)) |
||
899 | *--__front = __fmt->_S_literals[__fmt->_S_plus - __neg]; |
||
900 | } |
||
901 | |||
902 | // XXX should specialize! |
||
903 | if (!__fmt->_M_use_grouping && !__io.width()) |
||
904 | return copy(__front, __digits + _M_room, __s); |
||
905 | |||
906 | if (!__fmt->_M_use_grouping) |
||
907 | return __pad_numeric(__s, __flags, __fill, __io.width(0), |
||
908 | __front, __sign_end, __digits + _M_room); |
||
909 | |||
910 | _CharT* __p = __digits; |
||
911 | while (__front < __sign_end) |
||
912 | *__p++ = *__front++; |
||
913 | const char* __gr = __fmt->_M_grouping.data(); |
||
914 | __front = __group_digits(__p, __fmt->_M_thousands_sep, __gr, |
||
915 | __gr + __fmt->_M_grouping.size(), __sign_end, __digits + _M_room); |
||
916 | return __pad_numeric(__s, __flags, __fill, __io.width(0), |
||
917 | __digits, __p, __front); |
||
918 | } |
||
919 | |||
920 | template |
||
921 | _OutIter |
||
922 | num_put<_CharT, _OutIter>:: |
||
923 | do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const |
||
924 | { |
||
925 | unsigned long __uv = __v; |
||
926 | bool __neg = false; |
||
927 | if (__v < 0) |
||
928 | { |
||
929 | __neg = true; |
||
930 | __uv = -__uv; |
||
931 | } |
||
932 | return __output_integer(__s, __io, __fill, __neg, __uv); |
||
933 | } |
||
934 | |||
935 | template |
||
936 | _OutIter |
||
937 | num_put<_CharT, _OutIter>:: |
||
938 | do_put(iter_type __s, ios_base& __io, char_type __fill, |
||
939 | unsigned long __v) const |
||
940 | { return __output_integer(__s, __io, __fill, false, __v); } |
||
941 | |||
942 | #ifdef _GLIBCPP_USE_LONG_LONG |
||
943 | template |
||
944 | _OutIter |
||
945 | num_put<_CharT, _OutIter>:: |
||
946 | do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const |
||
947 | { |
||
948 | unsigned long long __uv = __v; |
||
949 | bool __neg = false; |
||
950 | if (__v < 0) |
||
951 | { |
||
952 | __neg = true; |
||
953 | __uv = -__uv; |
||
954 | } |
||
955 | return __output_integer(__s, __b, __fill, __neg, __uv); |
||
956 | } |
||
957 | |||
958 | template |
||
959 | _OutIter |
||
960 | num_put<_CharT, _OutIter>:: |
||
961 | do_put(iter_type __s, ios_base& __io, char_type __fill, |
||
962 | unsigned long long __v) const |
||
963 | { return __output_integer(__s, __io, __fill, false, __v); } |
||
964 | #endif |
||
965 | |||
966 | // Generic helper function |
||
967 | template |
||
968 | _OutIter |
||
969 | __output_float(_OutIter __s, ios_base& __io, _CharT __fill, |
||
970 | const char* __sptr, size_t __slen) |
||
971 | { |
||
972 | // XXX Not currently done: non streambuf_iterator |
||
973 | return __s; |
||
974 | } |
||
975 | |||
976 | // Partial specialization for ostreambuf_iterator. |
||
977 | template |
||
978 | ostreambuf_iterator<_CharT, _Traits> |
||
979 | __output_float(ostreambuf_iterator<_CharT, _Traits> __s, ios_base& __io, |
||
980 | _CharT __fill, const char* __sptr, size_t __slen) |
||
981 | { |
||
982 | size_t __padding = __io.width() > streamsize(__slen) ? |
||
983 | __io.width() -__slen : 0; |
||
984 | locale __loc = __io.getloc(); |
||
985 | ctype<_CharT> const& __ct = use_facet |
||
986 | ios_base::fmtflags __adjfield = __io.flags() & ios_base::adjustfield; |
||
987 | const char* const __eptr = __sptr + __slen; |
||
988 | // [22.2.2.2.2.19] Table 61 |
||
989 | if (__adjfield == ios_base::internal) |
||
990 | { |
||
991 | // [22.2.2.2.2.14]; widen() |
||
992 | if (__sptr < __eptr && (*__sptr == '+' || *__sptr == '-')) |
||
993 | { |
||
994 | __s = __ct.widen(*__sptr); |
||
995 | ++__s; |
||
996 | ++__sptr; |
||
997 | } |
||
998 | __s = __pad(__s, __fill, __padding); |
||
999 | __padding = 0; |
||
1000 | } |
||
1001 | else if (__adjfield != ios_base::left) |
||
1002 | { |
||
1003 | __s = __pad(__s, __fill, __padding); |
||
1004 | __padding = 0; |
||
1005 | } |
||
1006 | // the "C" locale decimal character |
||
1007 | char __decimal_point = *(localeconv()->decimal_point); |
||
1008 | const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io); |
||
1009 | for (; __sptr != __eptr; ++__s, ++__sptr) |
||
1010 | { |
||
1011 | // [22.2.2.2.2.17]; decimal point conversion |
||
1012 | if (*__sptr == __decimal_point) |
||
1013 | __s = __fmt->_M_decimal_point; |
||
1014 | // [22.2.2.2.2.14]; widen() |
||
1015 | else |
||
1016 | __s = __ct.widen(*__sptr); |
||
1017 | } |
||
1018 | // [22.2.2.2.2.19] Table 61 |
||
1019 | if (__padding) |
||
1020 | __pad(__s, __fill, __padding); |
||
1021 | __io.width(0); |
||
1022 | return __s; |
||
1023 | } |
||
1024 | |||
1025 | bool |
||
1026 | __build_float_format(ios_base& __io, char* __fptr, char __modifier, |
||
1027 | streamsize __prec); |
||
1028 | |||
1029 | template |
||
1030 | _OutIter |
||
1031 | num_put<_CharT, _OutIter>:: |
||
1032 | do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const |
||
1033 | { |
||
1034 | const streamsize __max_prec = numeric_limits |
||
1035 | streamsize __prec = __io.precision(); |
||
1036 | // Protect against sprintf() buffer overflows. |
||
1037 | if (__prec > __max_prec) |
||
1038 | __prec = __max_prec; |
||
1039 | // The *2 provides for signs, exp, 'E', and pad. |
||
1040 | char __sbuf[__max_prec * 2]; |
||
1041 | size_t __slen; |
||
1042 | // Long enough for the max format spec. |
||
1043 | char __fbuf[16]; |
||
1044 | if (__build_float_format(__io, __fbuf, 0, __prec)) |
||
1045 | __slen = sprintf(__sbuf, __fbuf, __prec, __v); |
||
1046 | else |
||
1047 | __slen = sprintf(__sbuf, __fbuf, __v); |
||
1048 | // [22.2.2.2.2] Stages 2-4. |
||
1049 | return __output_float(__s, __io, __fill, __sbuf, __slen); |
||
1050 | } |
||
1051 | |||
1052 | template |
||
1053 | _OutIter |
||
1054 | num_put<_CharT, _OutIter>:: |
||
1055 | do_put(iter_type __s, ios_base& __io, char_type __fill, |
||
1056 | long double __v) const |
||
1057 | { |
||
1058 | const streamsize __max_prec = numeric_limits |
||
1059 | streamsize __prec = __io.precision(); |
||
1060 | // Protect against sprintf() buffer overflows. |
||
1061 | if (__prec > __max_prec) |
||
1062 | __prec = __max_prec; |
||
1063 | // The *2 provides for signs, exp, 'E', and pad. |
||
1064 | char __sbuf[__max_prec * 2]; |
||
1065 | size_t __slen; |
||
1066 | // Long enough for the max format spec. |
||
1067 | char __fbuf[16]; |
||
1068 | // 'L' as per [22.2.2.2.2] Table 59 |
||
1069 | if (__build_float_format(__io, __fbuf, 'L', __prec)) |
||
1070 | __slen = sprintf(__sbuf, __fbuf, __prec, __v); |
||
1071 | else |
||
1072 | __slen = sprintf(__sbuf, __fbuf, __v); |
||
1073 | // [22.2.2.2.2] Stages 2-4 |
||
1074 | return __output_float(__s, __io, __fill, __sbuf, __slen); |
||
1075 | } |
||
1076 | |||
1077 | template |
||
1078 | _OutIter |
||
1079 | num_put<_CharT, _OutIter>:: |
||
1080 | do_put(iter_type __s, ios_base& __io, char_type __fill, |
||
1081 | const void* __v) const |
||
1082 | { |
||
1083 | typedef ios_base::fmtflags fmtflags; |
||
1084 | fmtflags __fmt = __io.flags(); |
||
1085 | fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield |
||
1086 | | ios_base::uppercase | ios_base::internal); |
||
1087 | __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase)); |
||
1088 | try { |
||
1089 | _OutIter __s2 = __output_integer(__s, __io, __fill, false, |
||
1090 | reinterpret_cast |
||
1091 | __io.flags(__fmt); |
||
1092 | return __s2; |
||
1093 | } |
||
1094 | catch (...) { |
||
1095 | __io.flags(__fmt); |
||
1096 | __throw_exception_again; |
||
1097 | } |
||
1098 | } |
||
1099 | |||
1100 | // Support for time_get: |
||
1101 | // Note that these partial specializations could, and maybe should, |
||
1102 | // be changed to full specializations (by eliminating the _Dummy |
||
1103 | // argument) and moved to a .cc file. |
||
1104 | template |
||
1105 | struct _Weekdaynames; |
||
1106 | |||
1107 | template |
||
1108 | struct _Weekdaynames |
||
1109 | { static const char* const _S_names[14]; }; |
||
1110 | |||
1111 | template |
||
1112 | const char* const |
||
1113 | _Weekdaynames |
||
1114 | { |
||
1115 | "Sun", "Sunday", |
||
1116 | "Mon", "Monday", "Tue", "Tuesday", "Wed", "Wednesday", |
||
1117 | "Thu", "Thursday", "Fri", "Friday", "Sat", "Saturday" |
||
1118 | }; |
||
1119 | |||
1120 | #ifdef _GLIBCPP_USE_WCHAR_T |
||
1121 | template |
||
1122 | struct _Weekdaynames |
||
1123 | { static const wchar_t* const _S_names[14]; }; |
||
1124 | |||
1125 | template |
||
1126 | const wchar_t* const |
||
1127 | _Weekdaynames |
||
1128 | { |
||
1129 | L"Sun", L"Sunday", |
||
1130 | L"Mon", L"Monday", L"Tue", L"Tuesday", L"Wed", L"Wednesday", |
||
1131 | L"Thu", L"Thursday", L"Fri", L"Friday", L"Sat", L"Saturday" |
||
1132 | }; |
||
1133 | #endif |
||
1134 | |||
1135 | template |
||
1136 | struct _Monthnames; |
||
1137 | |||
1138 | template |
||
1139 | struct _Monthnames |
||
1140 | { static const char* const _S_names[24]; }; |
||
1141 | |||
1142 | template |
||
1143 | const char* const |
||
1144 | _Monthnames |
||
1145 | { |
||
1146 | "Jan", "January", "Feb", "February", "Mar", "March", |
||
1147 | "Apr", "April", "May", "May", "Jun", "June", |
||
1148 | "Jul", "July", "Aug", "August", "Sep", "September", |
||
1149 | "Oct", "October", "Nov", "November", "Dec", "December" |
||
1150 | }; |
||
1151 | |||
1152 | #ifdef _GLIBCPP_USE_WCHAR_T |
||
1153 | template |
||
1154 | struct _Monthnames |
||
1155 | { static const wchar_t* const _S_names[24]; }; |
||
1156 | |||
1157 | template |
||
1158 | const wchar_t* const |
||
1159 | _Monthnames |
||
1160 | { |
||
1161 | L"Jan", L"January", L"Feb", L"February", L"Mar", L"March", |
||
1162 | L"Apr", L"April", L"May", L"May", L"Jun", L"June", |
||
1163 | L"Jul", L"July", L"Aug", L"August", L"Sep", L"September", |
||
1164 | L"Oct", L"October", L"Nov", L"November", L"Dec", L"December" |
||
1165 | }; |
||
1166 | #endif |
||
1167 | |||
1168 | template |
||
1169 | _InIter |
||
1170 | time_get<_CharT, _InIter>:: |
||
1171 | do_get_weekday(iter_type __s, iter_type __end, |
||
1172 | ios_base& __io, ios_base::iostate& __err, tm* __t) const |
||
1173 | { |
||
1174 | if (!_M_daynames) |
||
1175 | { |
||
1176 | _M_daynames = new basic_string<_CharT>[14]; |
||
1177 | for (int __i = 0; __i < 14; ++__i) |
||
1178 | _M_daynames[__i] = _Weekdaynames<_CharT>::_S_names[__i]; |
||
1179 | } |
||
1180 | bool __at_eof = false; |
||
1181 | int __remain = 0; |
||
1182 | int __matches[14]; |
||
1183 | iter_type __out = __match_parallel(__s, __end, 14, _M_daynames, |
||
1184 | __matches, __remain, __at_eof); |
||
1185 | __err = ios_base::iostate(0); |
||
1186 | if (__at_eof) __err |= __io.eofbit; |
||
1187 | if (__remain == 1 || |
||
1188 | __remain == 2 && (__matches[0]>>1) == (__matches[1]>>1)) |
||
1189 | __t->tm_wday = (__matches[0]>>1); |
||
1190 | else |
||
1191 | __err |= __io.failbit; |
||
1192 | return __out; |
||
1193 | } |
||
1194 | |||
1195 | template |
||
1196 | _InIter |
||
1197 | time_get<_CharT, _InIter>:: |
||
1198 | do_get_monthname(iter_type __s, iter_type __end, |
||
1199 | ios_base& __io, ios_base::iostate& __err, tm* __t) const |
||
1200 | { |
||
1201 | if (!_M_monthnames) |
||
1202 | { |
||
1203 | _M_monthnames = new basic_string<_CharT>[24]; |
||
1204 | for (int __i = 0; __i < 24; ++__i) |
||
1205 | _M_monthnames[__i] = _Monthnames<_CharT>::_S_names[__i]; |
||
1206 | } |
||
1207 | bool __at_eof = false; |
||
1208 | int __remain = 0; |
||
1209 | int __matches[24]; |
||
1210 | iter_type __out = __match_parallel( __s, __end, 24, _M_monthnames, |
||
1211 | __matches, __remain, __at_eof); |
||
1212 | __err = ios_base::iostate(0); |
||
1213 | if (__at_eof) __err |= __io.eofbit; |
||
1214 | if (__remain == 1 || |
||
1215 | __remain == 2 && (__matches[0]>>1) == (__matches[1]>>1)) |
||
1216 | __t->tm_mon = (__matches[0]>>1); |
||
1217 | else |
||
1218 | __err |= __io.failbit; |
||
1219 | return __out; |
||
1220 | } |
||
1221 | } // std:: |
||
1222 | |||
1223 | #endif /* _CPP_BITS_LOCFACETS_TCC */ |
||
1224 | |||
1225 | // Local Variables: |
||
1226 | // mode:c++ |
||
1227 | // End:>>>>>>>=>=>=>=>=>>>>>>>>>>> |