locale_facets.h (ctype.narrow,widen): Add cast.
[gcc.git] / libstdc++-v3 / include / bits / locale_facets.h
1 // Locale support -*- C++ -*-
2
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 //
32 // ISO C++ 14882: 22.1 Locales
33 //
34
35 /** @file locale_facets.h
36 * This is an internal header file, included by other library headers.
37 * You should not attempt to use it directly.
38 */
39
40 #ifndef _LOCALE_FACETS_H
41 #define _LOCALE_FACETS_H 1
42
43 #pragma GCC system_header
44
45 #include <ctime> // For struct tm
46 #include <cwctype> // For wctype_t
47 #include <iosfwd>
48 #include <bits/ios_base.h> // For ios_base, ios_base::iostate
49 #include <streambuf>
50
51 namespace std
52 {
53 // NB: Don't instantiate required wchar_t facets if no wchar_t support.
54 #ifdef _GLIBCXX_USE_WCHAR_T
55 # define _GLIBCXX_NUM_FACETS 28
56 #else
57 # define _GLIBCXX_NUM_FACETS 14
58 #endif
59
60 // Convert string to numeric value of type _Tv and store results.
61 // NB: This is specialized for all required types, there is no
62 // generic definition.
63 template<typename _Tv>
64 void
65 __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err,
66 const __c_locale& __cloc);
67
68 // Explicit specializations for required types.
69 template<>
70 void
71 __convert_to_v(const char*, float&, ios_base::iostate&,
72 const __c_locale&);
73
74 template<>
75 void
76 __convert_to_v(const char*, double&, ios_base::iostate&,
77 const __c_locale&);
78
79 template<>
80 void
81 __convert_to_v(const char*, long double&, ios_base::iostate&,
82 const __c_locale&);
83
84 // NB: __pad is a struct, rather than a function, so it can be
85 // partially-specialized.
86 template<typename _CharT, typename _Traits>
87 struct __pad
88 {
89 static void
90 _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
91 const _CharT* __olds, const streamsize __newlen,
92 const streamsize __oldlen, const bool __num);
93 };
94
95 // Used by both numeric and monetary facets.
96 // Check to make sure that the __grouping_tmp string constructed in
97 // money_get or num_get matches the canonical grouping for a given
98 // locale.
99 // __grouping_tmp is parsed L to R
100 // 1,222,444 == __grouping_tmp of "\1\3\3"
101 // __grouping is parsed R to L
102 // 1,222,444 == __grouping of "\3" == "\3\3\3"
103 template<typename _CharT>
104 bool
105 __verify_grouping(const basic_string<_CharT>& __grouping,
106 const basic_string<_CharT>& __grouping_tmp);
107
108 // Used by both numeric and monetary facets.
109 // Inserts "group separator" characters into an array of characters.
110 // It's recursive, one iteration per group. It moves the characters
111 // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
112 // only with __gbeg != __gend.
113 template<typename _CharT>
114 _CharT*
115 __add_grouping(_CharT* __s, _CharT __sep,
116 const char* __gbeg, const char* __gend,
117 const _CharT* __first, const _CharT* __last);
118
119 // This template permits specializing facet output code for
120 // ostreambuf_iterator. For ostreambuf_iterator, sputn is
121 // significantly more efficient than incrementing iterators.
122 template<typename _CharT>
123 inline
124 ostreambuf_iterator<_CharT>
125 __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
126 {
127 __s._M_put(__ws, __len);
128 return __s;
129 }
130
131 // This is the unspecialized form of the template.
132 template<typename _CharT, typename _OutIter>
133 inline
134 _OutIter
135 __write(_OutIter __s, const _CharT* __ws, int __len)
136 {
137 for (int __j = 0; __j < __len; __j++, ++__s)
138 *__s = __ws[__j];
139 return __s;
140 }
141
142
143 // 22.2.1.1 Template class ctype
144 // Include host and configuration specific ctype enums for ctype_base.
145 #include <bits/ctype_base.h>
146
147 // Common base for ctype<_CharT>.
148 /**
149 * @brief Common base for ctype facet
150 *
151 * This template class provides implementations of the public functions
152 * that forward to the protected virtual functions.
153 *
154 * This template also provides abtract stubs for the protected virtual
155 * functions.
156 */
157 template<typename _CharT>
158 class __ctype_abstract_base : public locale::facet, public ctype_base
159 {
160 public:
161 // Types:
162 /// Typedef for the template parameter
163 typedef _CharT char_type;
164
165 /**
166 * @brief Test char_type classification.
167 *
168 * This function finds a mask M for @a c and compares it to mask @a m.
169 * It does so by returning the value of ctype<char_type>::do_is().
170 *
171 * @param c The char_type to compare the mask of.
172 * @param m The mask to compare against.
173 * @return (M & m) != 0.
174 */
175 bool
176 is(mask __m, char_type __c) const
177 { return this->do_is(__m, __c); }
178
179 /**
180 * @brief Return a mask array.
181 *
182 * This function finds the mask for each char_type in the range [lo,hi)
183 * and successively writes it to vec. vec must have as many elements
184 * as the char array. It does so by returning the value of
185 * ctype<char_type>::do_is().
186 *
187 * @param lo Pointer to start of range.
188 * @param hi Pointer to end of range.
189 * @param vec Pointer to an array of mask storage.
190 * @return @a hi.
191 */
192 const char_type*
193 is(const char_type *__lo, const char_type *__hi, mask *__vec) const
194 { return this->do_is(__lo, __hi, __vec); }
195
196 /**
197 * @brief Find char_type matching a mask
198 *
199 * This function searches for and returns the first char_type c in
200 * [lo,hi) for which is(m,c) is true. It does so by returning
201 * ctype<char_type>::do_scan_is().
202 *
203 * @param m The mask to compare against.
204 * @param lo Pointer to start of range.
205 * @param hi Pointer to end of range.
206 * @return Pointer to matching char_type if found, else @a hi.
207 */
208 const char_type*
209 scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
210 { return this->do_scan_is(__m, __lo, __hi); }
211
212 /**
213 * @brief Find char_type not matching a mask
214 *
215 * This function searches for and returns the first char_type c in
216 * [lo,hi) for which is(m,c) is false. It does so by returning
217 * ctype<char_type>::do_scan_not().
218 *
219 * @param m The mask to compare against.
220 * @param lo Pointer to first char in range.
221 * @param hi Pointer to end of range.
222 * @return Pointer to non-matching char if found, else @a hi.
223 */
224 const char_type*
225 scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
226 { return this->do_scan_not(__m, __lo, __hi); }
227
228 /**
229 * @brief Convert to uppercase.
230 *
231 * This function converts the argument to uppercase if possible.
232 * If not possible (for example, '2'), returns the argument. It does
233 * so by returning ctype<char_type>::do_toupper().
234 *
235 * @param c The char_type to convert.
236 * @return The uppercase char_type if convertible, else @a c.
237 */
238 char_type
239 toupper(char_type __c) const
240 { return this->do_toupper(__c); }
241
242 /**
243 * @brief Convert array to uppercase.
244 *
245 * This function converts each char_type in the range [lo,hi) to
246 * uppercase if possible. Other elements remain untouched. It does so
247 * by returning ctype<char_type>:: do_toupper(lo, hi).
248 *
249 * @param lo Pointer to start of range.
250 * @param hi Pointer to end of range.
251 * @return @a hi.
252 */
253 const char_type*
254 toupper(char_type *__lo, const char_type* __hi) const
255 { return this->do_toupper(__lo, __hi); }
256
257 /**
258 * @brief Convert to lowercase.
259 *
260 * This function converts the argument to lowercase if possible. If
261 * not possible (for example, '2'), returns the argument. It does so
262 * by returning ctype<char_type>::do_tolower(c).
263 *
264 * @param c The char_type to convert.
265 * @return The lowercase char_type if convertible, else @a c.
266 */
267 char_type
268 tolower(char_type __c) const
269 { return this->do_tolower(__c); }
270
271 /**
272 * @brief Convert array to lowercase.
273 *
274 * This function converts each char_type in the range [lo,hi) to
275 * lowercase if possible. Other elements remain untouched. It does so
276 * by returning ctype<char_type>:: do_tolower(lo, hi).
277 *
278 * @param lo Pointer to start of range.
279 * @param hi Pointer to end of range.
280 * @return @a hi.
281 */
282 const char_type*
283 tolower(char_type* __lo, const char_type* __hi) const
284 { return this->do_tolower(__lo, __hi); }
285
286 /**
287 * @brief Widen char to char_type
288 *
289 * This function converts the char argument to char_type using the
290 * simplest reasonable transformation. It does so by returning
291 * ctype<char_type>::do_widen(c).
292 *
293 * Note: this is not what you want for codepage conversions. See
294 * codecvt for that.
295 *
296 * @param c The char to convert.
297 * @return The converted char_type.
298 */
299 char_type
300 widen(char __c) const
301 { return this->do_widen(__c); }
302
303 /**
304 * @brief Widen array to char_type
305 *
306 * This function converts each char in the input to char_type using the
307 * simplest reasonable transformation. It does so by returning
308 * ctype<char_type>::do_widen(c).
309 *
310 * Note: this is not what you want for codepage conversions. See
311 * codecvt for that.
312 *
313 * @param lo Pointer to start of range.
314 * @param hi Pointer to end of range.
315 * @param to Pointer to the destination array.
316 * @return @a hi.
317 */
318 const char*
319 widen(const char* __lo, const char* __hi, char_type* __to) const
320 { return this->do_widen(__lo, __hi, __to); }
321
322 /**
323 * @brief Narrow char_type to char
324 *
325 * This function converts the char_type to char using the simplest
326 * reasonable transformation. If the conversion fails, dfault is
327 * returned instead. It does so by returning
328 * ctype<char_type>::do_narrow(c).
329 *
330 * Note: this is not what you want for codepage conversions. See
331 * codecvt for that.
332 *
333 * @param c The char_type to convert.
334 * @param dfault Char to return if conversion fails.
335 * @return The converted char.
336 */
337 char
338 narrow(char_type __c, char __dfault) const
339 { return this->do_narrow(__c, __dfault); }
340
341 /**
342 * @brief Narrow array to char array
343 *
344 * This function converts each char_type in the input to char using the
345 * simplest reasonable transformation and writes the results to the
346 * destination array. For any char_type in the input that cannot be
347 * converted, @a dfault is used instead. It does so by returning
348 * ctype<char_type>::do_narrow(lo, hi, dfault, to).
349 *
350 * Note: this is not what you want for codepage conversions. See
351 * codecvt for that.
352 *
353 * @param lo Pointer to start of range.
354 * @param hi Pointer to end of range.
355 * @param dfault Char to use if conversion fails.
356 * @param to Pointer to the destination array.
357 * @return @a hi.
358 */
359 const char_type*
360 narrow(const char_type* __lo, const char_type* __hi,
361 char __dfault, char *__to) const
362 { return this->do_narrow(__lo, __hi, __dfault, __to); }
363
364 protected:
365 explicit
366 __ctype_abstract_base(size_t __refs = 0): facet(__refs) { }
367
368 virtual
369 ~__ctype_abstract_base() { }
370
371 /**
372 * @brief Test char_type classification.
373 *
374 * This function finds a mask M for @a c and compares it to mask @a m.
375 *
376 * do_is() is a hook for a derived facet to change the behavior of
377 * classifying. do_is() must always return the same result for the
378 * same input.
379 *
380 * @param c The char_type to find the mask of.
381 * @param m The mask to compare against.
382 * @return (M & m) != 0.
383 */
384 virtual bool
385 do_is(mask __m, char_type __c) const = 0;
386
387 /**
388 * @brief Return a mask array.
389 *
390 * This function finds the mask for each char_type in the range [lo,hi)
391 * and successively writes it to vec. vec must have as many elements
392 * as the input.
393 *
394 * do_is() is a hook for a derived facet to change the behavior of
395 * classifying. do_is() must always return the same result for the
396 * same input.
397 *
398 * @param lo Pointer to start of range.
399 * @param hi Pointer to end of range.
400 * @param vec Pointer to an array of mask storage.
401 * @return @a hi.
402 */
403 virtual const char_type*
404 do_is(const char_type* __lo, const char_type* __hi,
405 mask* __vec) const = 0;
406
407 /**
408 * @brief Find char_type matching mask
409 *
410 * This function searches for and returns the first char_type c in
411 * [lo,hi) for which is(m,c) is true.
412 *
413 * do_scan_is() is a hook for a derived facet to change the behavior of
414 * match searching. do_is() must always return the same result for the
415 * same input.
416 *
417 * @param m The mask to compare against.
418 * @param lo Pointer to start of range.
419 * @param hi Pointer to end of range.
420 * @return Pointer to a matching char_type if found, else @a hi.
421 */
422 virtual const char_type*
423 do_scan_is(mask __m, const char_type* __lo,
424 const char_type* __hi) const = 0;
425
426 /**
427 * @brief Find char_type not matching mask
428 *
429 * This function searches for and returns a pointer to the first
430 * char_type c of [lo,hi) for which is(m,c) is false.
431 *
432 * do_scan_is() is a hook for a derived facet to change the behavior of
433 * match searching. do_is() must always return the same result for the
434 * same input.
435 *
436 * @param m The mask to compare against.
437 * @param lo Pointer to start of range.
438 * @param hi Pointer to end of range.
439 * @return Pointer to a non-matching char_type if found, else @a hi.
440 */
441 virtual const char_type*
442 do_scan_not(mask __m, const char_type* __lo,
443 const char_type* __hi) const = 0;
444
445 /**
446 * @brief Convert to uppercase.
447 *
448 * This virtual function converts the char_type argument to uppercase
449 * if possible. If not possible (for example, '2'), returns the
450 * argument.
451 *
452 * do_toupper() is a hook for a derived facet to change the behavior of
453 * uppercasing. do_toupper() must always return the same result for
454 * the same input.
455 *
456 * @param c The char_type to convert.
457 * @return The uppercase char_type if convertible, else @a c.
458 */
459 virtual char_type
460 do_toupper(char_type) const = 0;
461
462 /**
463 * @brief Convert array to uppercase.
464 *
465 * This virtual function converts each char_type in the range [lo,hi)
466 * to uppercase if possible. Other elements remain untouched.
467 *
468 * do_toupper() is a hook for a derived facet to change the behavior of
469 * uppercasing. do_toupper() must always return the same result for
470 * the same input.
471 *
472 * @param lo Pointer to start of range.
473 * @param hi Pointer to end of range.
474 * @return @a hi.
475 */
476 virtual const char_type*
477 do_toupper(char_type* __lo, const char_type* __hi) const = 0;
478
479 /**
480 * @brief Convert to lowercase.
481 *
482 * This virtual function converts the argument to lowercase if
483 * possible. If not possible (for example, '2'), returns the argument.
484 *
485 * do_tolower() is a hook for a derived facet to change the behavior of
486 * lowercasing. do_tolower() must always return the same result for
487 * the same input.
488 *
489 * @param c The char_type to convert.
490 * @return The lowercase char_type if convertible, else @a c.
491 */
492 virtual char_type
493 do_tolower(char_type) const = 0;
494
495 /**
496 * @brief Convert array to lowercase.
497 *
498 * This virtual function converts each char_type in the range [lo,hi)
499 * to lowercase if possible. Other elements remain untouched.
500 *
501 * do_tolower() is a hook for a derived facet to change the behavior of
502 * lowercasing. do_tolower() must always return the same result for
503 * the same input.
504 *
505 * @param lo Pointer to start of range.
506 * @param hi Pointer to end of range.
507 * @return @a hi.
508 */
509 virtual const char_type*
510 do_tolower(char_type* __lo, const char_type* __hi) const = 0;
511
512 /**
513 * @brief Widen char
514 *
515 * This virtual function converts the char to char_type using the
516 * simplest reasonable transformation.
517 *
518 * do_widen() is a hook for a derived facet to change the behavior of
519 * widening. do_widen() must always return the same result for the
520 * same input.
521 *
522 * Note: this is not what you want for codepage conversions. See
523 * codecvt for that.
524 *
525 * @param c The char to convert.
526 * @return The converted char_type
527 */
528 virtual char_type
529 do_widen(char) const = 0;
530
531 /**
532 * @brief Widen char array
533 *
534 * This function converts each char in the input to char_type using the
535 * simplest reasonable transformation.
536 *
537 * do_widen() is a hook for a derived facet to change the behavior of
538 * widening. do_widen() must always return the same result for the
539 * same input.
540 *
541 * Note: this is not what you want for codepage conversions. See
542 * codecvt for that.
543 *
544 * @param lo Pointer to start range.
545 * @param hi Pointer to end of range.
546 * @param to Pointer to the destination array.
547 * @return @a hi.
548 */
549 virtual const char*
550 do_widen(const char* __lo, const char* __hi,
551 char_type* __dest) const = 0;
552
553 /**
554 * @brief Narrow char_type to char
555 *
556 * This virtual function converts the argument to char using the
557 * simplest reasonable transformation. If the conversion fails, dfault
558 * is returned instead.
559 *
560 * do_narrow() is a hook for a derived facet to change the behavior of
561 * narrowing. do_narrow() must always return the same result for the
562 * same input.
563 *
564 * Note: this is not what you want for codepage conversions. See
565 * codecvt for that.
566 *
567 * @param c The char_type to convert.
568 * @param dfault Char to return if conversion fails.
569 * @return The converted char.
570 */
571 virtual char
572 do_narrow(char_type, char __dfault) const = 0;
573
574 /**
575 * @brief Narrow char_type array to char
576 *
577 * This virtual function converts each char_type in the range [lo,hi) to
578 * char using the simplest reasonable transformation and writes the
579 * results to the destination array. For any element in the input that
580 * cannot be converted, @a dfault is used instead.
581 *
582 * do_narrow() is a hook for a derived facet to change the behavior of
583 * narrowing. do_narrow() must always return the same result for the
584 * same input.
585 *
586 * Note: this is not what you want for codepage conversions. See
587 * codecvt for that.
588 *
589 * @param lo Pointer to start of range.
590 * @param hi Pointer to end of range.
591 * @param dfault Char to use if conversion fails.
592 * @param to Pointer to the destination array.
593 * @return @a hi.
594 */
595 virtual const char_type*
596 do_narrow(const char_type* __lo, const char_type* __hi,
597 char __dfault, char* __dest) const = 0;
598 };
599
600 // NB: Generic, mostly useless implementation.
601 /**
602 * @brief Template ctype facet
603 *
604 * This template class defines classification and conversion functions for
605 * character sets. It wraps <cctype> functionality. Ctype gets used by
606 * streams for many I/O operations.
607 *
608 * This template provides the protected virtual functions the developer
609 * will have to replace in a derived class or specialization to make a
610 * working facet. The public functions that access them are defined in
611 * __ctype_abstract_base, to allow for implementation flexibility. See
612 * ctype<wchar_t> for an example. The functions are documented in
613 * __ctype_abstract_base.
614 *
615 * Note: implementations are provided for all the protected virtual
616 * functions, but will likely not be useful.
617 */
618 template<typename _CharT>
619 class ctype : public __ctype_abstract_base<_CharT>
620 {
621 public:
622 // Types:
623 typedef _CharT char_type;
624 typedef typename ctype::mask mask;
625
626 /// The facet id for ctype<char_type>
627 static locale::id id;
628
629 explicit
630 ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
631
632 protected:
633 virtual
634 ~ctype();
635
636 virtual bool
637 do_is(mask __m, char_type __c) const;
638
639 virtual const char_type*
640 do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
641
642 virtual const char_type*
643 do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
644
645 virtual const char_type*
646 do_scan_not(mask __m, const char_type* __lo,
647 const char_type* __hi) const;
648
649 virtual char_type
650 do_toupper(char_type __c) const;
651
652 virtual const char_type*
653 do_toupper(char_type* __lo, const char_type* __hi) const;
654
655 virtual char_type
656 do_tolower(char_type __c) const;
657
658 virtual const char_type*
659 do_tolower(char_type* __lo, const char_type* __hi) const;
660
661 virtual char_type
662 do_widen(char __c) const;
663
664 virtual const char*
665 do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
666
667 virtual char
668 do_narrow(char_type, char __dfault) const;
669
670 virtual const char_type*
671 do_narrow(const char_type* __lo, const char_type* __hi,
672 char __dfault, char* __dest) const;
673 };
674
675 template<typename _CharT>
676 locale::id ctype<_CharT>::id;
677
678 // 22.2.1.3 ctype<char> specialization.
679 /**
680 * @brief The ctype<char> specialization.
681 *
682 * This class defines classification and conversion functions for
683 * the char type. It gets used by char streams for many I/O
684 * operations. The char specialization provides a number of
685 * optimizations as well.
686 */
687 template<>
688 class ctype<char> : public locale::facet, public ctype_base
689 {
690 public:
691 // Types:
692 /// Typedef for the template parameter char.
693 typedef char char_type;
694
695 protected:
696 // Data Members:
697 __c_locale _M_c_locale_ctype;
698 bool _M_del;
699 __to_type _M_toupper;
700 __to_type _M_tolower;
701 const mask* _M_table;
702 mutable char _M_widen_ok;
703 mutable char _M_widen[1 + static_cast<unsigned char>(-1)];
704 mutable char _M_narrow[1 + static_cast<unsigned char>(-1)];
705 mutable char _M_narrow_ok; // 0 uninitialized, 1 init,
706 // 2 non-consecutive
707
708 public:
709 /// The facet id for ctype<char>
710 static locale::id id;
711 /// The size of the mask table. It is SCHAR_MAX + 1.
712 static const size_t table_size = 1 + static_cast<unsigned char>(-1);
713
714 /**
715 * @brief Constructor performs initialization.
716 *
717 * This is the constructor provided by the standard.
718 *
719 * @param table If non-zero, table is used as the per-char mask.
720 * Else classic_table() is used.
721 * @param del If true, passes ownership of table to this facet.
722 * @param refs Passed to the base facet class.
723 */
724 explicit
725 ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
726
727 /**
728 * @brief Constructor performs static initialization.
729 *
730 * This constructor is used to construct the initial C locale facet.
731 *
732 * @param cloc Handle to C locale data.
733 * @param table If non-zero, table is used as the per-char mask.
734 * @param del If true, passes ownership of table to this facet.
735 * @param refs Passed to the base facet class.
736 */
737 explicit
738 ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
739 size_t __refs = 0);
740
741 /**
742 * @brief Test char classification.
743 *
744 * This function compares the mask table[c] to @a m.
745 *
746 * @param c The char to compare the mask of.
747 * @param m The mask to compare against.
748 * @return True if m & table[c] is true, false otherwise.
749 */
750 inline bool
751 is(mask __m, char __c) const;
752
753 /**
754 * @brief Return a mask array.
755 *
756 * This function finds the mask for each char in the range [lo, hi) and
757 * successively writes it to vec. vec must have as many elements as
758 * the char array.
759 *
760 * @param lo Pointer to start of range.
761 * @param hi Pointer to end of range.
762 * @param vec Pointer to an array of mask storage.
763 * @return @a hi.
764 */
765 inline const char*
766 is(const char* __lo, const char* __hi, mask* __vec) const;
767
768 /**
769 * @brief Find char matching a mask
770 *
771 * This function searches for and returns the first char in [lo,hi) for
772 * which is(m,char) is true.
773 *
774 * @param m The mask to compare against.
775 * @param lo Pointer to start of range.
776 * @param hi Pointer to end of range.
777 * @return Pointer to a matching char if found, else @a hi.
778 */
779 inline const char*
780 scan_is(mask __m, const char* __lo, const char* __hi) const;
781
782 /**
783 * @brief Find char not matching a mask
784 *
785 * This function searches for and returns a pointer to the first char
786 * in [lo,hi) for which is(m,char) is false.
787 *
788 * @param m The mask to compare against.
789 * @param lo Pointer to start of range.
790 * @param hi Pointer to end of range.
791 * @return Pointer to a non-matching char if found, else @a hi.
792 */
793 inline const char*
794 scan_not(mask __m, const char* __lo, const char* __hi) const;
795
796 /**
797 * @brief Convert to uppercase.
798 *
799 * This function converts the char argument to uppercase if possible.
800 * If not possible (for example, '2'), returns the argument.
801 *
802 * toupper() acts as if it returns ctype<char>::do_toupper(c).
803 * do_toupper() must always return the same result for the same input.
804 *
805 * @param c The char to convert.
806 * @return The uppercase char if convertible, else @a c.
807 */
808 char_type
809 toupper(char_type __c) const
810 { return this->do_toupper(__c); }
811
812 /**
813 * @brief Convert array to uppercase.
814 *
815 * This function converts each char in the range [lo,hi) to uppercase
816 * if possible. Other chars remain untouched.
817 *
818 * toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi).
819 * do_toupper() must always return the same result for the same input.
820 *
821 * @param lo Pointer to first char in range.
822 * @param hi Pointer to end of range.
823 * @return @a hi.
824 */
825 const char_type*
826 toupper(char_type *__lo, const char_type* __hi) const
827 { return this->do_toupper(__lo, __hi); }
828
829 /**
830 * @brief Convert to lowercase.
831 *
832 * This function converts the char argument to lowercase if possible.
833 * If not possible (for example, '2'), returns the argument.
834 *
835 * tolower() acts as if it returns ctype<char>::do_tolower(c).
836 * do_tolower() must always return the same result for the same input.
837 *
838 * @param c The char to convert.
839 * @return The lowercase char if convertible, else @a c.
840 */
841 char_type
842 tolower(char_type __c) const
843 { return this->do_tolower(__c); }
844
845 /**
846 * @brief Convert array to lowercase.
847 *
848 * This function converts each char in the range [lo,hi) to lowercase
849 * if possible. Other chars remain untouched.
850 *
851 * tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi).
852 * do_tolower() must always return the same result for the same input.
853 *
854 * @param lo Pointer to first char in range.
855 * @param hi Pointer to end of range.
856 * @return @a hi.
857 */
858 const char_type*
859 tolower(char_type* __lo, const char_type* __hi) const
860 { return this->do_tolower(__lo, __hi); }
861
862 /**
863 * @brief Widen char
864 *
865 * This function converts the char to char_type using the simplest
866 * reasonable transformation. For an underived ctype<char> facet, the
867 * argument will be returned unchanged.
868 *
869 * This function works as if it returns ctype<char>::do_widen(c).
870 * do_widen() must always return the same result for the same input.
871 *
872 * Note: this is not what you want for codepage conversions. See
873 * codecvt for that.
874 *
875 * @param c The char to convert.
876 * @return The converted character.
877 */
878 char_type
879 widen(char __c) const
880 {
881 if (_M_widen_ok) return _M_widen[static_cast<unsigned char>(__c)];
882 this->_M_widen_init();
883 return this->do_widen(__c);
884 }
885
886 /**
887 * @brief Widen char array
888 *
889 * This function converts each char in the input to char using the
890 * simplest reasonable transformation. For an underived ctype<char>
891 * facet, the argument will be copied unchanged.
892 *
893 * This function works as if it returns ctype<char>::do_widen(c).
894 * do_widen() must always return the same result for the same input.
895 *
896 * Note: this is not what you want for codepage conversions. See
897 * codecvt for that.
898 *
899 * @param lo Pointer to first char in range.
900 * @param hi Pointer to end of range.
901 * @param to Pointer to the destination array.
902 * @return @a hi.
903 */
904 const char*
905 widen(const char* __lo, const char* __hi, char_type* __to) const
906 {
907 if (_M_widen_ok == 1)
908 {
909 memcpy(__to, __lo, __hi - __lo);
910 return __hi;
911 }
912 if (!_M_widen_ok) _M_widen_init();
913 return this->do_widen(__lo, __hi, __to);
914 }
915
916 /**
917 * @brief Narrow char
918 *
919 * This function converts the char to char using the simplest
920 * reasonable transformation. If the conversion fails, dfault is
921 * returned instead. For an underived ctype<char> facet, @a c
922 * will be returned unchanged.
923 *
924 * This function works as if it returns ctype<char>::do_narrow(c).
925 * do_narrow() must always return the same result for the same input.
926 *
927 * Note: this is not what you want for codepage conversions. See
928 * codecvt for that.
929 *
930 * @param c The char to convert.
931 * @param dfault Char to return if conversion fails.
932 * @return The converted character.
933 */
934 char
935 narrow(char_type __c, char __dfault) const
936 {
937 if (_M_narrow[static_cast<unsigned char>(__c)])
938 return _M_narrow[static_cast<unsigned char>(__c)];
939 const char __t = do_narrow(__c, __dfault);
940 if (__t != __dfault) _M_narrow[static_cast<unsigned char>(__c)] = __t;
941 return __t;
942 }
943
944 /**
945 * @brief Narrow char array
946 *
947 * This function converts each char in the input to char using the
948 * simplest reasonable transformation and writes the results to the
949 * destination array. For any char in the input that cannot be
950 * converted, @a dfault is used instead. For an underived ctype<char>
951 * facet, the argument will be copied unchanged.
952 *
953 * This function works as if it returns ctype<char>::do_narrow(lo, hi,
954 * dfault, to). do_narrow() must always return the same result for the
955 * same input.
956 *
957 * Note: this is not what you want for codepage conversions. See
958 * codecvt for that.
959 *
960 * @param lo Pointer to start of range.
961 * @param hi Pointer to end of range.
962 * @param dfault Char to use if conversion fails.
963 * @param to Pointer to the destination array.
964 * @return @a hi.
965 */
966 const char_type*
967 narrow(const char_type* __lo, const char_type* __hi,
968 char __dfault, char *__to) const
969 {
970 if (__builtin_expect(_M_narrow_ok == 1,true))
971 {
972 memcpy(__to, __lo, __hi - __lo);
973 return __hi;
974 }
975 if (!_M_narrow_ok)
976 _M_narrow_init();
977 return this->do_narrow(__lo, __hi, __dfault, __to);
978 }
979
980 protected:
981 /// Returns a pointer to the mask table provided to the constructor, or
982 /// the default from classic_table() if none was provided.
983 const mask*
984 table() const throw()
985 { return _M_table; }
986
987 /// Returns a pointer to the C locale mask table.
988 static const mask*
989 classic_table() throw();
990
991 /**
992 * @brief Destructor.
993 *
994 * This function deletes table() if @a del was true in the
995 * constructor.
996 */
997 virtual
998 ~ctype();
999
1000 /**
1001 * @brief Convert to uppercase.
1002 *
1003 * This virtual function converts the char argument to uppercase if
1004 * possible. If not possible (for example, '2'), returns the argument.
1005 *
1006 * do_toupper() is a hook for a derived facet to change the behavior of
1007 * uppercasing. do_toupper() must always return the same result for
1008 * the same input.
1009 *
1010 * @param c The char to convert.
1011 * @return The uppercase char if convertible, else @a c.
1012 */
1013 virtual char_type
1014 do_toupper(char_type) const;
1015
1016 /**
1017 * @brief Convert array to uppercase.
1018 *
1019 * This virtual function converts each char in the range [lo,hi) to
1020 * uppercase if possible. Other chars remain untouched.
1021 *
1022 * do_toupper() is a hook for a derived facet to change the behavior of
1023 * uppercasing. do_toupper() must always return the same result for
1024 * the same input.
1025 *
1026 * @param lo Pointer to start of range.
1027 * @param hi Pointer to end of range.
1028 * @return @a hi.
1029 */
1030 virtual const char_type*
1031 do_toupper(char_type* __lo, const char_type* __hi) const;
1032
1033 /**
1034 * @brief Convert to lowercase.
1035 *
1036 * This virtual function converts the char argument to lowercase if
1037 * possible. If not possible (for example, '2'), returns the argument.
1038 *
1039 * do_tolower() is a hook for a derived facet to change the behavior of
1040 * lowercasing. do_tolower() must always return the same result for
1041 * the same input.
1042 *
1043 * @param c The char to convert.
1044 * @return The lowercase char if convertible, else @a c.
1045 */
1046 virtual char_type
1047 do_tolower(char_type) const;
1048
1049 /**
1050 * @brief Convert array to lowercase.
1051 *
1052 * This virtual function converts each char in the range [lo,hi) to
1053 * lowercase if possible. Other chars remain untouched.
1054 *
1055 * do_tolower() is a hook for a derived facet to change the behavior of
1056 * lowercasing. do_tolower() must always return the same result for
1057 * the same input.
1058 *
1059 * @param lo Pointer to first char in range.
1060 * @param hi Pointer to end of range.
1061 * @return @a hi.
1062 */
1063 virtual const char_type*
1064 do_tolower(char_type* __lo, const char_type* __hi) const;
1065
1066 /**
1067 * @brief Widen char
1068 *
1069 * This virtual function converts the char to char using the simplest
1070 * reasonable transformation. For an underived ctype<char> facet, the
1071 * argument will be returned unchanged.
1072 *
1073 * do_widen() is a hook for a derived facet to change the behavior of
1074 * widening. do_widen() must always return the same result for the
1075 * same input.
1076 *
1077 * Note: this is not what you want for codepage conversions. See
1078 * codecvt for that.
1079 *
1080 * @param c The char to convert.
1081 * @return The converted character.
1082 */
1083 virtual char_type
1084 do_widen(char __c) const
1085 { return __c; }
1086
1087 /**
1088 * @brief Widen char array
1089 *
1090 * This function converts each char in the range [lo,hi) to char using
1091 * the simplest reasonable transformation. For an underived
1092 * ctype<char> facet, the argument will be copied unchanged.
1093 *
1094 * do_widen() is a hook for a derived facet to change the behavior of
1095 * widening. do_widen() must always return the same result for the
1096 * same input.
1097 *
1098 * Note: this is not what you want for codepage conversions. See
1099 * codecvt for that.
1100 *
1101 * @param lo Pointer to start of range.
1102 * @param hi Pointer to end of range.
1103 * @param to Pointer to the destination array.
1104 * @return @a hi.
1105 */
1106 virtual const char*
1107 do_widen(const char* __lo, const char* __hi, char_type* __dest) const
1108 {
1109 memcpy(__dest, __lo, __hi - __lo);
1110 return __hi;
1111 }
1112
1113 /**
1114 * @brief Narrow char
1115 *
1116 * This virtual function converts the char to char using the simplest
1117 * reasonable transformation. If the conversion fails, dfault is
1118 * returned instead. For an underived ctype<char> facet, @a c will be
1119 * returned unchanged.
1120 *
1121 * do_narrow() is a hook for a derived facet to change the behavior of
1122 * narrowing. do_narrow() must always return the same result for the
1123 * same input.
1124 *
1125 * Note: this is not what you want for codepage conversions. See
1126 * codecvt for that.
1127 *
1128 * @param c The char to convert.
1129 * @param dfault Char to return if conversion fails.
1130 * @return The converted char.
1131 */
1132 virtual char
1133 do_narrow(char_type __c, char) const
1134 { return __c; }
1135
1136 /**
1137 * @brief Narrow char array to char array
1138 *
1139 * This virtual function converts each char in the range [lo,hi) to
1140 * char using the simplest reasonable transformation and writes the
1141 * results to the destination array. For any char in the input that
1142 * cannot be converted, @a dfault is used instead. For an underived
1143 * ctype<char> facet, the argument will be copied unchanged.
1144 *
1145 * do_narrow() is a hook for a derived facet to change the behavior of
1146 * narrowing. do_narrow() must always return the same result for the
1147 * same input.
1148 *
1149 * Note: this is not what you want for codepage conversions. See
1150 * codecvt for that.
1151 *
1152 * @param lo Pointer to start of range.
1153 * @param hi Pointer to end of range.
1154 * @param dfault Char to use if conversion fails.
1155 * @param to Pointer to the destination array.
1156 * @return @a hi.
1157 */
1158 virtual const char_type*
1159 do_narrow(const char_type* __lo, const char_type* __hi,
1160 char, char* __dest) const
1161 {
1162 memcpy(__dest, __lo, __hi - __lo);
1163 return __hi;
1164 }
1165
1166 private:
1167
1168 void _M_widen_init() const
1169 {
1170 char __tmp[sizeof(_M_widen)];
1171 for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
1172 __tmp[__i] = __i;
1173 do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
1174
1175 _M_widen_ok = 1;
1176 // Set _M_widen_ok to 2 if memcpy can't be used.
1177 for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
1178 if (__tmp[__i] != _M_widen[__i])
1179 {
1180 _M_widen_ok = 2;
1181 break;
1182 }
1183 }
1184
1185 // Fill in the narrowing cache and flag whether all values are
1186 // valid or not. _M_narrow_ok is set to 1 if the whole table is
1187 // narrowed, 2 if only some values could be narrowed.
1188 void _M_narrow_init() const
1189 {
1190 char __tmp[sizeof(_M_narrow)];
1191 for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
1192 __tmp[__i] = __i;
1193 do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
1194
1195 // Check if any default values were created. Do this by
1196 // renarrowing with a different default value and comparing.
1197 bool __consecutive = true;
1198 for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
1199 if (!_M_narrow[__i])
1200 {
1201 char __c;
1202 do_narrow(__tmp + __i, __tmp + __i + 1, 1, &__c);
1203 if (__c == 1)
1204 {
1205 __consecutive = false;
1206 break;
1207 }
1208 }
1209 _M_narrow_ok = __consecutive ? 1 : 2;
1210 }
1211 };
1212
1213 template<>
1214 const ctype<char>&
1215 use_facet<ctype<char> >(const locale& __loc);
1216
1217 #ifdef _GLIBCXX_USE_WCHAR_T
1218 // 22.2.1.3 ctype<wchar_t> specialization
1219 /**
1220 * @brief The ctype<wchar_t> specialization.
1221 *
1222 * This class defines classification and conversion functions for the
1223 * wchar_t type. It gets used by wchar_t streams for many I/O operations.
1224 * The wchar_t specialization provides a number of optimizations as well.
1225 *
1226 * ctype<wchar_t> inherits its public methods from
1227 * __ctype_abstract_base<wchar_t>.
1228 */
1229 template<>
1230 class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
1231 {
1232 public:
1233 // Types:
1234 /// Typedef for the template parameter wchar_t.
1235 typedef wchar_t char_type;
1236 typedef wctype_t __wmask_type;
1237
1238 protected:
1239 __c_locale _M_c_locale_ctype;
1240
1241 // Pre-computed narrowed and widened chars.
1242 bool _M_narrow_ok;
1243 char _M_narrow[128];
1244 wint_t _M_widen[1 + static_cast<unsigned char>(-1)];
1245
1246 // Pre-computed elements for do_is.
1247 mask _M_bit[16];
1248 __wmask_type _M_wmask[16];
1249
1250 public:
1251 // Data Members:
1252 /// The facet id for ctype<wchar_t>
1253 static locale::id id;
1254
1255 /**
1256 * @brief Constructor performs initialization.
1257 *
1258 * This is the constructor provided by the standard.
1259 *
1260 * @param refs Passed to the base facet class.
1261 */
1262 explicit
1263 ctype(size_t __refs = 0);
1264
1265 /**
1266 * @brief Constructor performs static initialization.
1267 *
1268 * This constructor is used to construct the initial C locale facet.
1269 *
1270 * @param cloc Handle to C locale data.
1271 * @param refs Passed to the base facet class.
1272 */
1273 explicit
1274 ctype(__c_locale __cloc, size_t __refs = 0);
1275
1276 protected:
1277 __wmask_type
1278 _M_convert_to_wmask(const mask __m) const;
1279
1280 /// Destructor
1281 virtual
1282 ~ctype();
1283
1284 /**
1285 * @brief Test wchar_t classification.
1286 *
1287 * This function finds a mask M for @a c and compares it to mask @a m.
1288 *
1289 * do_is() is a hook for a derived facet to change the behavior of
1290 * classifying. do_is() must always return the same result for the
1291 * same input.
1292 *
1293 * @param c The wchar_t to find the mask of.
1294 * @param m The mask to compare against.
1295 * @return (M & m) != 0.
1296 */
1297 virtual bool
1298 do_is(mask __m, char_type __c) const;
1299
1300 /**
1301 * @brief Return a mask array.
1302 *
1303 * This function finds the mask for each wchar_t in the range [lo,hi)
1304 * and successively writes it to vec. vec must have as many elements
1305 * as the input.
1306 *
1307 * do_is() is a hook for a derived facet to change the behavior of
1308 * classifying. do_is() must always return the same result for the
1309 * same input.
1310 *
1311 * @param lo Pointer to start of range.
1312 * @param hi Pointer to end of range.
1313 * @param vec Pointer to an array of mask storage.
1314 * @return @a hi.
1315 */
1316 virtual const char_type*
1317 do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
1318
1319 /**
1320 * @brief Find wchar_t matching mask
1321 *
1322 * This function searches for and returns the first wchar_t c in
1323 * [lo,hi) for which is(m,c) is true.
1324 *
1325 * do_scan_is() is a hook for a derived facet to change the behavior of
1326 * match searching. do_is() must always return the same result for the
1327 * same input.
1328 *
1329 * @param m The mask to compare against.
1330 * @param lo Pointer to start of range.
1331 * @param hi Pointer to end of range.
1332 * @return Pointer to a matching wchar_t if found, else @a hi.
1333 */
1334 virtual const char_type*
1335 do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
1336
1337 /**
1338 * @brief Find wchar_t not matching mask
1339 *
1340 * This function searches for and returns a pointer to the first
1341 * wchar_t c of [lo,hi) for which is(m,c) is false.
1342 *
1343 * do_scan_is() is a hook for a derived facet to change the behavior of
1344 * match searching. do_is() must always return the same result for the
1345 * same input.
1346 *
1347 * @param m The mask to compare against.
1348 * @param lo Pointer to start of range.
1349 * @param hi Pointer to end of range.
1350 * @return Pointer to a non-matching wchar_t if found, else @a hi.
1351 */
1352 virtual const char_type*
1353 do_scan_not(mask __m, const char_type* __lo,
1354 const char_type* __hi) const;
1355
1356 /**
1357 * @brief Convert to uppercase.
1358 *
1359 * This virtual function converts the wchar_t argument to uppercase if
1360 * possible. If not possible (for example, '2'), returns the argument.
1361 *
1362 * do_toupper() is a hook for a derived facet to change the behavior of
1363 * uppercasing. do_toupper() must always return the same result for
1364 * the same input.
1365 *
1366 * @param c The wchar_t to convert.
1367 * @return The uppercase wchar_t if convertible, else @a c.
1368 */
1369 virtual char_type
1370 do_toupper(char_type) const;
1371
1372 /**
1373 * @brief Convert array to uppercase.
1374 *
1375 * This virtual function converts each wchar_t in the range [lo,hi) to
1376 * uppercase if possible. Other elements remain untouched.
1377 *
1378 * do_toupper() is a hook for a derived facet to change the behavior of
1379 * uppercasing. do_toupper() must always return the same result for
1380 * the same input.
1381 *
1382 * @param lo Pointer to start of range.
1383 * @param hi Pointer to end of range.
1384 * @return @a hi.
1385 */
1386 virtual const char_type*
1387 do_toupper(char_type* __lo, const char_type* __hi) const;
1388
1389 /**
1390 * @brief Convert to lowercase.
1391 *
1392 * This virtual function converts the argument to lowercase if
1393 * possible. If not possible (for example, '2'), returns the argument.
1394 *
1395 * do_tolower() is a hook for a derived facet to change the behavior of
1396 * lowercasing. do_tolower() must always return the same result for
1397 * the same input.
1398 *
1399 * @param c The wchar_t to convert.
1400 * @return The lowercase wchar_t if convertible, else @a c.
1401 */
1402 virtual char_type
1403 do_tolower(char_type) const;
1404
1405 /**
1406 * @brief Convert array to lowercase.
1407 *
1408 * This virtual function converts each wchar_t in the range [lo,hi) to
1409 * lowercase if possible. Other elements remain untouched.
1410 *
1411 * do_tolower() is a hook for a derived facet to change the behavior of
1412 * lowercasing. do_tolower() must always return the same result for
1413 * the same input.
1414 *
1415 * @param lo Pointer to start of range.
1416 * @param hi Pointer to end of range.
1417 * @return @a hi.
1418 */
1419 virtual const char_type*
1420 do_tolower(char_type* __lo, const char_type* __hi) const;
1421
1422 /**
1423 * @brief Widen char to wchar_t
1424 *
1425 * This virtual function converts the char to wchar_t using the
1426 * simplest reasonable transformation. For an underived ctype<wchar_t>
1427 * facet, the argument will be cast to wchar_t.
1428 *
1429 * do_widen() is a hook for a derived facet to change the behavior of
1430 * widening. do_widen() must always return the same result for the
1431 * same input.
1432 *
1433 * Note: this is not what you want for codepage conversions. See
1434 * codecvt for that.
1435 *
1436 * @param c The char to convert.
1437 * @return The converted wchar_t.
1438 */
1439 virtual char_type
1440 do_widen(char) const;
1441
1442 /**
1443 * @brief Widen char array to wchar_t array
1444 *
1445 * This function converts each char in the input to wchar_t using the
1446 * simplest reasonable transformation. For an underived ctype<wchar_t>
1447 * facet, the argument will be copied, casting each element to wchar_t.
1448 *
1449 * do_widen() is a hook for a derived facet to change the behavior of
1450 * widening. do_widen() must always return the same result for the
1451 * same input.
1452 *
1453 * Note: this is not what you want for codepage conversions. See
1454 * codecvt for that.
1455 *
1456 * @param lo Pointer to start range.
1457 * @param hi Pointer to end of range.
1458 * @param to Pointer to the destination array.
1459 * @return @a hi.
1460 */
1461 virtual const char*
1462 do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
1463
1464 /**
1465 * @brief Narrow wchar_t to char
1466 *
1467 * This virtual function converts the argument to char using the
1468 * simplest reasonable transformation. If the conversion fails, dfault
1469 * is returned instead. For an underived ctype<wchar_t> facet, @a c will
1470 * be cast to char and returned.
1471 *
1472 * do_narrow() is a hook for a derived facet to change the behavior of
1473 * narrowing. do_narrow() must always return the same result for the
1474 * same input.
1475 *
1476 * Note: this is not what you want for codepage conversions. See
1477 * codecvt for that.
1478 *
1479 * @param c The wchar_t to convert.
1480 * @param dfault Char to return if conversion fails.
1481 * @return The converted char.
1482 */
1483 virtual char
1484 do_narrow(char_type, char __dfault) const;
1485
1486 /**
1487 * @brief Narrow wchar_t array to char array
1488 *
1489 * This virtual function converts each wchar_t in the range [lo,hi) to
1490 * char using the simplest reasonable transformation and writes the
1491 * results to the destination array. For any wchar_t in the input that
1492 * cannot be converted, @a dfault is used instead. For an underived
1493 * ctype<wchar_t> facet, the argument will be copied, casting each
1494 * element to char.
1495 *
1496 * do_narrow() is a hook for a derived facet to change the behavior of
1497 * narrowing. do_narrow() must always return the same result for the
1498 * same input.
1499 *
1500 * Note: this is not what you want for codepage conversions. See
1501 * codecvt for that.
1502 *
1503 * @param lo Pointer to start of range.
1504 * @param hi Pointer to end of range.
1505 * @param dfault Char to use if conversion fails.
1506 * @param to Pointer to the destination array.
1507 * @return @a hi.
1508 */
1509 virtual const char_type*
1510 do_narrow(const char_type* __lo, const char_type* __hi,
1511 char __dfault, char* __dest) const;
1512
1513 // For use at construction time only.
1514 void
1515 _M_initialize_ctype();
1516 };
1517
1518 template<>
1519 const ctype<wchar_t>&
1520 use_facet<ctype<wchar_t> >(const locale& __loc);
1521 #endif //_GLIBCXX_USE_WCHAR_T
1522
1523 // Include host and configuration specific ctype inlines.
1524 #include <bits/ctype_inline.h>
1525
1526 // 22.2.1.2 Template class ctype_byname
1527 template<typename _CharT>
1528 class ctype_byname : public ctype<_CharT>
1529 {
1530 public:
1531 typedef _CharT char_type;
1532
1533 explicit
1534 ctype_byname(const char* __s, size_t __refs = 0);
1535
1536 protected:
1537 virtual
1538 ~ctype_byname() { };
1539 };
1540
1541 // 22.2.1.4 Class ctype_byname specializations.
1542 template<>
1543 ctype_byname<char>::ctype_byname(const char*, size_t refs);
1544
1545 template<>
1546 ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);
1547
1548 // 22.2.1.5 Template class codecvt
1549 #include <bits/codecvt.h>
1550
1551 // 22.2.2 The numeric category.
1552 class __num_base
1553 {
1554 public:
1555 // NB: Code depends on the order of _S_atoms_out elements.
1556 // Below are the indices into _S_atoms_out.
1557 enum
1558 {
1559 _S_ominus,
1560 _S_oplus,
1561 _S_ox,
1562 _S_oX,
1563 _S_odigits,
1564 _S_odigits_end = _S_odigits + 16,
1565 _S_oudigits = _S_odigits_end,
1566 _S_oudigits_end = _S_oudigits + 16,
1567 _S_oe = _S_odigits + 14, // For scientific notation, 'e'
1568 _S_oE = _S_oudigits + 14, // For scientific notation, 'E'
1569 _S_oend = _S_oudigits_end
1570 };
1571
1572 // A list of valid numeric literals for output. This array
1573 // contains chars that will be passed through the current locale's
1574 // ctype<_CharT>.widen() and then used to render numbers.
1575 // For the standard "C" locale, this is
1576 // "-+xX0123456789abcdef0123456789ABCDEF".
1577 static const char* _S_atoms_out;
1578
1579 // String literal of acceptable (narrow) input, for num_get.
1580 // "-+xX0123456789abcdefABCDEF"
1581 static const char* _S_atoms_in;
1582
1583 enum
1584 {
1585 _S_iminus,
1586 _S_iplus,
1587 _S_ix,
1588 _S_iX,
1589 _S_izero,
1590 _S_ie = _S_izero + 14,
1591 _S_iE = _S_izero + 20,
1592 _S_iend = 26
1593 };
1594
1595 // num_put
1596 // Construct and return valid scanf format for floating point types.
1597 static void
1598 _S_format_float(const ios_base& __io, char* __fptr, char __mod);
1599 };
1600
1601 template<typename _CharT>
1602 struct __numpunct_cache : public locale::facet
1603 {
1604 const char* _M_grouping;
1605 bool _M_use_grouping;
1606 const _CharT* _M_truename;
1607 const _CharT* _M_falsename;
1608 _CharT _M_decimal_point;
1609 _CharT _M_thousands_sep;
1610
1611 // A list of valid numeric literals for output: in the standard
1612 // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF".
1613 // This array contains the chars after having been passed
1614 // through the current locale's ctype<_CharT>.widen().
1615 _CharT _M_atoms_out[__num_base::_S_oend + 1];
1616
1617 // A list of valid numeric literals for input: in the standard
1618 // "C" locale, this is "-+xX0123456789abcdefABCDEF"
1619 // This array contains the chars after having been passed
1620 // through the current locale's ctype<_CharT>.widen().
1621 _CharT _M_atoms_in[__num_base::_S_iend + 1];
1622
1623 bool _M_allocated;
1624
1625 __numpunct_cache(size_t __refs = 0) : facet(__refs),
1626 _M_grouping(NULL), _M_use_grouping(false), _M_truename(NULL),
1627 _M_falsename(NULL), _M_decimal_point(_CharT()),
1628 _M_thousands_sep(_CharT()), _M_allocated(false)
1629 { }
1630
1631 ~__numpunct_cache();
1632
1633 void
1634 _M_cache(const locale& __loc);
1635 };
1636
1637 template<typename _CharT>
1638 void
1639 __numpunct_cache<_CharT>::_M_cache(const locale& __loc)
1640 {
1641 _M_allocated = true;
1642
1643 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
1644
1645 const string::size_type __len = __np.grouping().size();
1646 char* __grouping = new char[__len + 1];
1647 __np.grouping().copy(__grouping, __len);
1648 __grouping[__len] = char();
1649 _M_grouping = __grouping;
1650 _M_use_grouping = __len && __np.grouping()[0] != 0;
1651
1652 typedef basic_string<_CharT> __string_type;
1653 typename __string_type::size_type __lentf = __np.truename().size();
1654 _CharT* __truename = new _CharT[__lentf + 1];
1655 __np.truename().copy(__truename, __lentf);
1656 __truename[__lentf] = _CharT();
1657 _M_truename = __truename;
1658
1659 __lentf = __np.falsename().size();
1660 _CharT* __falsename = new _CharT[__lentf + 1];
1661 __np.falsename().copy(__falsename, __lentf);
1662 __falsename[__lentf] = _CharT();
1663 _M_falsename = __falsename;
1664
1665 _M_decimal_point = __np.decimal_point();
1666 _M_thousands_sep = __np.thousands_sep();
1667
1668 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
1669 __ct.widen(__num_base::_S_atoms_out,
1670 __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
1671 _M_atoms_out[__num_base::_S_oend] = _CharT();
1672 __ct.widen(__num_base::_S_atoms_in,
1673 __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
1674 _M_atoms_in[__num_base::_S_iend] = _CharT();
1675 }
1676
1677 template<typename _CharT>
1678 __numpunct_cache<_CharT>::~__numpunct_cache()
1679 {
1680 if (_M_allocated)
1681 {
1682 delete [] _M_grouping;
1683 delete [] _M_truename;
1684 delete [] _M_falsename;
1685 }
1686 }
1687
1688 template<typename _CharT>
1689 class numpunct : public locale::facet
1690 {
1691 public:
1692 // Types:
1693 typedef _CharT char_type;
1694 typedef basic_string<_CharT> string_type;
1695 typedef __numpunct_cache<_CharT> __cache_type;
1696
1697 protected:
1698 __cache_type* _M_data;
1699
1700 public:
1701 static locale::id id;
1702
1703 explicit
1704 numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
1705 { _M_initialize_numpunct(); }
1706
1707 explicit
1708 numpunct(__cache_type* __cache, size_t __refs = 0)
1709 : facet(__refs), _M_data(__cache)
1710 { _M_initialize_numpunct(); }
1711
1712 explicit
1713 numpunct(__c_locale __cloc, size_t __refs = 0)
1714 : facet(__refs), _M_data(NULL)
1715 { _M_initialize_numpunct(__cloc); }
1716
1717 char_type
1718 decimal_point() const
1719 { return this->do_decimal_point(); }
1720
1721 char_type
1722 thousands_sep() const
1723 { return this->do_thousands_sep(); }
1724
1725 string
1726 grouping() const
1727 { return this->do_grouping(); }
1728
1729 string_type
1730 truename() const
1731 { return this->do_truename(); }
1732
1733 string_type
1734 falsename() const
1735 { return this->do_falsename(); }
1736
1737 protected:
1738 virtual
1739 ~numpunct();
1740
1741 virtual char_type
1742 do_decimal_point() const
1743 { return _M_data->_M_decimal_point; }
1744
1745 virtual char_type
1746 do_thousands_sep() const
1747 { return _M_data->_M_thousands_sep; }
1748
1749 virtual string
1750 do_grouping() const
1751 { return _M_data->_M_grouping; }
1752
1753 virtual string_type
1754 do_truename() const
1755 { return _M_data->_M_truename; }
1756
1757 virtual string_type
1758 do_falsename() const
1759 { return _M_data->_M_falsename; }
1760
1761 // For use at construction time only.
1762 void
1763 _M_initialize_numpunct(__c_locale __cloc = NULL);
1764 };
1765
1766 template<typename _CharT>
1767 locale::id numpunct<_CharT>::id;
1768
1769 template<>
1770 numpunct<char>::~numpunct();
1771
1772 template<>
1773 void
1774 numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
1775
1776 #ifdef _GLIBCXX_USE_WCHAR_T
1777 template<>
1778 numpunct<wchar_t>::~numpunct();
1779
1780 template<>
1781 void
1782 numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
1783 #endif
1784
1785 template<typename _CharT>
1786 class numpunct_byname : public numpunct<_CharT>
1787 {
1788 public:
1789 typedef _CharT char_type;
1790 typedef basic_string<_CharT> string_type;
1791
1792 explicit
1793 numpunct_byname(const char* __s, size_t __refs = 0)
1794 : numpunct<_CharT>(__refs)
1795 {
1796 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
1797 {
1798 __c_locale __tmp;
1799 this->_S_create_c_locale(__tmp, __s);
1800 this->_M_initialize_numpunct(__tmp);
1801 this->_S_destroy_c_locale(__tmp);
1802 }
1803 }
1804
1805 protected:
1806 virtual
1807 ~numpunct_byname() { }
1808 };
1809
1810 template<typename _CharT, typename _InIter>
1811 class num_get : public locale::facet, public __num_base
1812 {
1813 public:
1814 // Types:
1815 typedef _CharT char_type;
1816 typedef _InIter iter_type;
1817
1818 static locale::id id;
1819
1820 explicit
1821 num_get(size_t __refs = 0) : facet(__refs) { }
1822
1823 iter_type
1824 get(iter_type __in, iter_type __end, ios_base& __io,
1825 ios_base::iostate& __err, bool& __v) const
1826 { return this->do_get(__in, __end, __io, __err, __v); }
1827
1828 iter_type
1829 get(iter_type __in, iter_type __end, ios_base& __io,
1830 ios_base::iostate& __err, long& __v) const
1831 { return this->do_get(__in, __end, __io, __err, __v); }
1832
1833 iter_type
1834 get(iter_type __in, iter_type __end, ios_base& __io,
1835 ios_base::iostate& __err, unsigned short& __v) const
1836 { return this->do_get(__in, __end, __io, __err, __v); }
1837
1838 iter_type
1839 get(iter_type __in, iter_type __end, ios_base& __io,
1840 ios_base::iostate& __err, unsigned int& __v) const
1841 { return this->do_get(__in, __end, __io, __err, __v); }
1842
1843 iter_type
1844 get(iter_type __in, iter_type __end, ios_base& __io,
1845 ios_base::iostate& __err, unsigned long& __v) const
1846 { return this->do_get(__in, __end, __io, __err, __v); }
1847
1848 #ifdef _GLIBCXX_USE_LONG_LONG
1849 iter_type
1850 get(iter_type __in, iter_type __end, ios_base& __io,
1851 ios_base::iostate& __err, long long& __v) const
1852 { return this->do_get(__in, __end, __io, __err, __v); }
1853
1854 iter_type
1855 get(iter_type __in, iter_type __end, ios_base& __io,
1856 ios_base::iostate& __err, unsigned long long& __v) const
1857 { return this->do_get(__in, __end, __io, __err, __v); }
1858 #endif
1859
1860 iter_type
1861 get(iter_type __in, iter_type __end, ios_base& __io,
1862 ios_base::iostate& __err, float& __v) const
1863 { return this->do_get(__in, __end, __io, __err, __v); }
1864
1865 iter_type
1866 get(iter_type __in, iter_type __end, ios_base& __io,
1867 ios_base::iostate& __err, double& __v) const
1868 { return this->do_get(__in, __end, __io, __err, __v); }
1869
1870 iter_type
1871 get(iter_type __in, iter_type __end, ios_base& __io,
1872 ios_base::iostate& __err, long double& __v) const
1873 { return this->do_get(__in, __end, __io, __err, __v); }
1874
1875 iter_type
1876 get(iter_type __in, iter_type __end, ios_base& __io,
1877 ios_base::iostate& __err, void*& __v) const
1878 { return this->do_get(__in, __end, __io, __err, __v); }
1879
1880 protected:
1881 virtual ~num_get() { }
1882
1883 iter_type
1884 _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
1885 string& __xtrc) const;
1886
1887 template<typename _ValueT>
1888 iter_type
1889 _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
1890 _ValueT& __v) const;
1891
1892 virtual iter_type
1893 do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
1894
1895
1896 virtual iter_type
1897 do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
1898
1899 virtual iter_type
1900 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1901 unsigned short&) const;
1902
1903 virtual iter_type
1904 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1905 unsigned int&) const;
1906
1907 virtual iter_type
1908 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1909 unsigned long&) const;
1910
1911 #ifdef _GLIBCXX_USE_LONG_LONG
1912 virtual iter_type
1913 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1914 long long&) const;
1915
1916 virtual iter_type
1917 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1918 unsigned long long&) const;
1919 #endif
1920
1921 virtual iter_type
1922 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1923 float&) const;
1924
1925 virtual iter_type
1926 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1927 double&) const;
1928
1929 virtual iter_type
1930 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1931 long double&) const;
1932
1933 virtual iter_type
1934 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
1935 void*&) const;
1936 };
1937
1938 template<typename _CharT, typename _InIter>
1939 locale::id num_get<_CharT, _InIter>::id;
1940
1941
1942 template<typename _CharT, typename _OutIter>
1943 class num_put : public locale::facet, public __num_base
1944 {
1945 public:
1946 // Types:
1947 typedef _CharT char_type;
1948 typedef _OutIter iter_type;
1949 static locale::id id;
1950
1951 explicit
1952 num_put(size_t __refs = 0) : facet(__refs) { }
1953
1954 iter_type
1955 put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
1956 { return this->do_put(__s, __f, __fill, __v); }
1957
1958 iter_type
1959 put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
1960 { return this->do_put(__s, __f, __fill, __v); }
1961
1962 iter_type
1963 put(iter_type __s, ios_base& __f, char_type __fill,
1964 unsigned long __v) const
1965 { return this->do_put(__s, __f, __fill, __v); }
1966
1967 #ifdef _GLIBCXX_USE_LONG_LONG
1968 iter_type
1969 put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
1970 { return this->do_put(__s, __f, __fill, __v); }
1971
1972 iter_type
1973 put(iter_type __s, ios_base& __f, char_type __fill,
1974 unsigned long long __v) const
1975 { return this->do_put(__s, __f, __fill, __v); }
1976 #endif
1977
1978 iter_type
1979 put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
1980 { return this->do_put(__s, __f, __fill, __v); }
1981
1982 iter_type
1983 put(iter_type __s, ios_base& __f, char_type __fill,
1984 long double __v) const
1985 { return this->do_put(__s, __f, __fill, __v); }
1986
1987 iter_type
1988 put(iter_type __s, ios_base& __f, char_type __fill,
1989 const void* __v) const
1990 { return this->do_put(__s, __f, __fill, __v); }
1991
1992 protected:
1993 template<typename _ValueT>
1994 iter_type
1995 _M_insert_float(iter_type, ios_base& __io, char_type __fill,
1996 char __mod, _ValueT __v) const;
1997
1998 void
1999 _M_group_float(const string& __grouping, char_type __sep,
2000 const char_type* __p, char_type* __new, char_type* __cs,
2001 int& __len) const;
2002
2003 template<typename _ValueT>
2004 iter_type
2005 _M_insert_int(iter_type, ios_base& __io, char_type __fill,
2006 _ValueT __v) const;
2007
2008 void
2009 _M_group_int(const string& __grouping, char_type __sep,
2010 ios_base& __io, char_type* __new, char_type* __cs,
2011 int& __len) const;
2012
2013 void
2014 _M_pad(char_type __fill, streamsize __w, ios_base& __io,
2015 char_type* __new, const char_type* __cs, int& __len) const;
2016
2017 virtual
2018 ~num_put() { };
2019
2020 virtual iter_type
2021 do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
2022
2023 virtual iter_type
2024 do_put(iter_type, ios_base&, char_type __fill, long __v) const;
2025
2026 virtual iter_type
2027 do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
2028
2029 #ifdef _GLIBCXX_USE_LONG_LONG
2030 virtual iter_type
2031 do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
2032
2033 virtual iter_type
2034 do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
2035 #endif
2036
2037 virtual iter_type
2038 do_put(iter_type, ios_base&, char_type __fill, double __v) const;
2039
2040 virtual iter_type
2041 do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
2042
2043 virtual iter_type
2044 do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
2045 };
2046
2047 template <typename _CharT, typename _OutIter>
2048 locale::id num_put<_CharT, _OutIter>::id;
2049
2050
2051 template<typename _CharT>
2052 class collate : public locale::facet
2053 {
2054 public:
2055 // Types:
2056 typedef _CharT char_type;
2057 typedef basic_string<_CharT> string_type;
2058
2059 protected:
2060 // Underlying "C" library locale information saved from
2061 // initialization, needed by collate_byname as well.
2062 __c_locale _M_c_locale_collate;
2063
2064 public:
2065 static locale::id id;
2066
2067 explicit
2068 collate(size_t __refs = 0)
2069 : facet(__refs)
2070 { _M_c_locale_collate = _S_get_c_locale(); }
2071
2072 explicit
2073 collate(__c_locale __cloc, size_t __refs = 0)
2074 : facet(__refs)
2075 { _M_c_locale_collate = _S_clone_c_locale(__cloc); }
2076
2077 int
2078 compare(const _CharT* __lo1, const _CharT* __hi1,
2079 const _CharT* __lo2, const _CharT* __hi2) const
2080 { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
2081
2082 string_type
2083 transform(const _CharT* __lo, const _CharT* __hi) const
2084 { return this->do_transform(__lo, __hi); }
2085
2086 long
2087 hash(const _CharT* __lo, const _CharT* __hi) const
2088 { return this->do_hash(__lo, __hi); }
2089
2090 // Used to abstract out _CharT bits in virtual member functions, below.
2091 int
2092 _M_compare(const _CharT*, const _CharT*) const;
2093
2094 size_t
2095 _M_transform(_CharT*, const _CharT*, size_t) const;
2096
2097 protected:
2098 virtual
2099 ~collate()
2100 { _S_destroy_c_locale(_M_c_locale_collate); }
2101
2102 virtual int
2103 do_compare(const _CharT* __lo1, const _CharT* __hi1,
2104 const _CharT* __lo2, const _CharT* __hi2) const;
2105
2106 virtual string_type
2107 do_transform(const _CharT* __lo, const _CharT* __hi) const;
2108
2109 virtual long
2110 do_hash(const _CharT* __lo, const _CharT* __hi) const;
2111 };
2112
2113 template<typename _CharT>
2114 locale::id collate<_CharT>::id;
2115
2116 // Specializations.
2117 template<>
2118 int
2119 collate<char>::_M_compare(const char*, const char*) const;
2120
2121 template<>
2122 size_t
2123 collate<char>::_M_transform(char*, const char*, size_t) const;
2124
2125 #ifdef _GLIBCXX_USE_WCHAR_T
2126 template<>
2127 int
2128 collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
2129
2130 template<>
2131 size_t
2132 collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
2133 #endif
2134
2135 template<typename _CharT>
2136 class collate_byname : public collate<_CharT>
2137 {
2138 public:
2139 typedef _CharT char_type;
2140 typedef basic_string<_CharT> string_type;
2141
2142 explicit
2143 collate_byname(const char* __s, size_t __refs = 0)
2144 : collate<_CharT>(__refs)
2145 {
2146 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
2147 {
2148 this->_S_destroy_c_locale(this->_M_c_locale_collate);
2149 this->_S_create_c_locale(this->_M_c_locale_collate, __s);
2150 }
2151 }
2152
2153 protected:
2154 virtual
2155 ~collate_byname() { }
2156 };
2157
2158
2159 class time_base
2160 {
2161 public:
2162 enum dateorder { no_order, dmy, mdy, ymd, ydm };
2163 };
2164
2165 template<typename _CharT>
2166 struct __timepunct_cache : public locale::facet
2167 {
2168 // List of all known timezones, with GMT first.
2169 static const _CharT* _S_timezones[14];
2170
2171 const _CharT* _M_date_format;
2172 const _CharT* _M_date_era_format;
2173 const _CharT* _M_time_format;
2174 const _CharT* _M_time_era_format;
2175 const _CharT* _M_date_time_format;
2176 const _CharT* _M_date_time_era_format;
2177 const _CharT* _M_am;
2178 const _CharT* _M_pm;
2179 const _CharT* _M_am_pm_format;
2180
2181 // Day names, starting with "C"'s Sunday.
2182 const _CharT* _M_day1;
2183 const _CharT* _M_day2;
2184 const _CharT* _M_day3;
2185 const _CharT* _M_day4;
2186 const _CharT* _M_day5;
2187 const _CharT* _M_day6;
2188 const _CharT* _M_day7;
2189
2190 // Abbreviated day names, starting with "C"'s Sun.
2191 const _CharT* _M_aday1;
2192 const _CharT* _M_aday2;
2193 const _CharT* _M_aday3;
2194 const _CharT* _M_aday4;
2195 const _CharT* _M_aday5;
2196 const _CharT* _M_aday6;
2197 const _CharT* _M_aday7;
2198
2199 // Month names, starting with "C"'s January.
2200 const _CharT* _M_month01;
2201 const _CharT* _M_month02;
2202 const _CharT* _M_month03;
2203 const _CharT* _M_month04;
2204 const _CharT* _M_month05;
2205 const _CharT* _M_month06;
2206 const _CharT* _M_month07;
2207 const _CharT* _M_month08;
2208 const _CharT* _M_month09;
2209 const _CharT* _M_month10;
2210 const _CharT* _M_month11;
2211 const _CharT* _M_month12;
2212
2213 // Abbreviated month names, starting with "C"'s Jan.
2214 const _CharT* _M_amonth01;
2215 const _CharT* _M_amonth02;
2216 const _CharT* _M_amonth03;
2217 const _CharT* _M_amonth04;
2218 const _CharT* _M_amonth05;
2219 const _CharT* _M_amonth06;
2220 const _CharT* _M_amonth07;
2221 const _CharT* _M_amonth08;
2222 const _CharT* _M_amonth09;
2223 const _CharT* _M_amonth10;
2224 const _CharT* _M_amonth11;
2225 const _CharT* _M_amonth12;
2226
2227 bool _M_allocated;
2228
2229 __timepunct_cache(size_t __refs = 0) : facet(__refs),
2230 _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL),
2231 _M_time_era_format(NULL), _M_date_time_format(NULL),
2232 _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL),
2233 _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL),
2234 _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL),
2235 _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL),
2236 _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL),
2237 _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL),
2238 _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL),
2239 _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL),
2240 _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL),
2241 _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL),
2242 _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL),
2243 _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false)
2244 { }
2245
2246 ~__timepunct_cache();
2247
2248 void
2249 _M_cache(const locale& __loc);
2250 };
2251
2252 template<typename _CharT>
2253 __timepunct_cache<_CharT>::~__timepunct_cache()
2254 {
2255 if (_M_allocated)
2256 {
2257 // XXX.
2258 }
2259 }
2260
2261 // Specializations.
2262 template<>
2263 const char*
2264 __timepunct_cache<char>::_S_timezones[14];
2265
2266 #ifdef _GLIBCXX_USE_WCHAR_T
2267 template<>
2268 const wchar_t*
2269 __timepunct_cache<wchar_t>::_S_timezones[14];
2270 #endif
2271
2272 // Generic.
2273 template<typename _CharT>
2274 const _CharT* __timepunct_cache<_CharT>::_S_timezones[14];
2275
2276 template<typename _CharT>
2277 class __timepunct : public locale::facet
2278 {
2279 public:
2280 // Types:
2281 typedef _CharT __char_type;
2282 typedef basic_string<_CharT> __string_type;
2283 typedef __timepunct_cache<_CharT> __cache_type;
2284
2285 protected:
2286 __cache_type* _M_data;
2287 __c_locale _M_c_locale_timepunct;
2288 const char* _M_name_timepunct;
2289
2290 public:
2291 static locale::id id;
2292
2293 explicit
2294 __timepunct(size_t __refs = 0);
2295
2296 explicit
2297 __timepunct(__cache_type* __cache, size_t __refs = 0);
2298
2299 explicit
2300 __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
2301
2302 void
2303 _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
2304 const tm* __tm) const;
2305
2306 void
2307 _M_date_formats(const _CharT** __date) const
2308 {
2309 // Always have default first.
2310 __date[0] = _M_data->_M_date_format;
2311 __date[1] = _M_data->_M_date_era_format;
2312 }
2313
2314 void
2315 _M_time_formats(const _CharT** __time) const
2316 {
2317 // Always have default first.
2318 __time[0] = _M_data->_M_time_format;
2319 __time[1] = _M_data->_M_time_era_format;
2320 }
2321
2322 void
2323 _M_ampm(const _CharT** __ampm) const
2324 {
2325 __ampm[0] = _M_data->_M_am;
2326 __ampm[1] = _M_data->_M_pm;
2327 }
2328
2329 void
2330 _M_date_time_formats(const _CharT** __dt) const
2331 {
2332 // Always have default first.
2333 __dt[0] = _M_data->_M_date_time_format;
2334 __dt[1] = _M_data->_M_date_time_era_format;
2335 }
2336
2337 void
2338 _M_days(const _CharT** __days) const
2339 {
2340 __days[0] = _M_data->_M_day1;
2341 __days[1] = _M_data->_M_day2;
2342 __days[2] = _M_data->_M_day3;
2343 __days[3] = _M_data->_M_day4;
2344 __days[4] = _M_data->_M_day5;
2345 __days[5] = _M_data->_M_day6;
2346 __days[6] = _M_data->_M_day7;
2347 }
2348
2349 void
2350 _M_days_abbreviated(const _CharT** __days) const
2351 {
2352 __days[0] = _M_data->_M_aday1;
2353 __days[1] = _M_data->_M_aday2;
2354 __days[2] = _M_data->_M_aday3;
2355 __days[3] = _M_data->_M_aday4;
2356 __days[4] = _M_data->_M_aday5;
2357 __days[5] = _M_data->_M_aday6;
2358 __days[6] = _M_data->_M_aday7;
2359 }
2360
2361 void
2362 _M_months(const _CharT** __months) const
2363 {
2364 __months[0] = _M_data->_M_month01;
2365 __months[1] = _M_data->_M_month02;
2366 __months[2] = _M_data->_M_month03;
2367 __months[3] = _M_data->_M_month04;
2368 __months[4] = _M_data->_M_month05;
2369 __months[5] = _M_data->_M_month06;
2370 __months[6] = _M_data->_M_month07;
2371 __months[7] = _M_data->_M_month08;
2372 __months[8] = _M_data->_M_month09;
2373 __months[9] = _M_data->_M_month10;
2374 __months[10] = _M_data->_M_month11;
2375 __months[11] = _M_data->_M_month12;
2376 }
2377
2378 void
2379 _M_months_abbreviated(const _CharT** __months) const
2380 {
2381 __months[0] = _M_data->_M_amonth01;
2382 __months[1] = _M_data->_M_amonth02;
2383 __months[2] = _M_data->_M_amonth03;
2384 __months[3] = _M_data->_M_amonth04;
2385 __months[4] = _M_data->_M_amonth05;
2386 __months[5] = _M_data->_M_amonth06;
2387 __months[6] = _M_data->_M_amonth07;
2388 __months[7] = _M_data->_M_amonth08;
2389 __months[8] = _M_data->_M_amonth09;
2390 __months[9] = _M_data->_M_amonth10;
2391 __months[10] = _M_data->_M_amonth11;
2392 __months[11] = _M_data->_M_amonth12;
2393 }
2394
2395 protected:
2396 virtual
2397 ~__timepunct();
2398
2399 // For use at construction time only.
2400 void
2401 _M_initialize_timepunct(__c_locale __cloc = NULL);
2402 };
2403
2404 template<typename _CharT>
2405 locale::id __timepunct<_CharT>::id;
2406
2407 // Specializations.
2408 template<>
2409 void
2410 __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);
2411
2412 template<>
2413 void
2414 __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
2415
2416 #ifdef _GLIBCXX_USE_WCHAR_T
2417 template<>
2418 void
2419 __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);
2420
2421 template<>
2422 void
2423 __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,
2424 const tm*) const;
2425 #endif
2426
2427 // Include host and configuration specific timepunct functions.
2428 #include <bits/time_members.h>
2429
2430 template<typename _CharT, typename _InIter>
2431 class time_get : public locale::facet, public time_base
2432 {
2433 public:
2434 // Types:
2435 typedef _CharT char_type;
2436 typedef _InIter iter_type;
2437 typedef basic_string<_CharT> __string_type;
2438
2439 static locale::id id;
2440
2441 explicit
2442 time_get(size_t __refs = 0)
2443 : facet (__refs) { }
2444
2445 dateorder
2446 date_order() const
2447 { return this->do_date_order(); }
2448
2449 iter_type
2450 get_time(iter_type __beg, iter_type __end, ios_base& __io,
2451 ios_base::iostate& __err, tm* __tm) const
2452 { return this->do_get_time(__beg, __end, __io, __err, __tm); }
2453
2454 iter_type
2455 get_date(iter_type __beg, iter_type __end, ios_base& __io,
2456 ios_base::iostate& __err, tm* __tm) const
2457 { return this->do_get_date(__beg, __end, __io, __err, __tm); }
2458
2459 iter_type
2460 get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
2461 ios_base::iostate& __err, tm* __tm) const
2462 { return this->do_get_weekday(__beg, __end, __io, __err, __tm); }
2463
2464 iter_type
2465 get_monthname(iter_type __beg, iter_type __end, ios_base& __io,
2466 ios_base::iostate& __err, tm* __tm) const
2467 { return this->do_get_monthname(__beg, __end, __io, __err, __tm); }
2468
2469 iter_type
2470 get_year(iter_type __beg, iter_type __end, ios_base& __io,
2471 ios_base::iostate& __err, tm* __tm) const
2472 { return this->do_get_year(__beg, __end, __io, __err, __tm); }
2473
2474 protected:
2475 virtual
2476 ~time_get() { }
2477
2478 virtual dateorder
2479 do_date_order() const;
2480
2481 virtual iter_type
2482 do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
2483 ios_base::iostate& __err, tm* __tm) const;
2484
2485 virtual iter_type
2486 do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
2487 ios_base::iostate& __err, tm* __tm) const;
2488
2489 virtual iter_type
2490 do_get_weekday(iter_type __beg, iter_type __end, ios_base&,
2491 ios_base::iostate& __err, tm* __tm) const;
2492
2493 virtual iter_type
2494 do_get_monthname(iter_type __beg, iter_type __end, ios_base&,
2495 ios_base::iostate& __err, tm* __tm) const;
2496
2497 virtual iter_type
2498 do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
2499 ios_base::iostate& __err, tm* __tm) const;
2500
2501 // Extract numeric component of length __len.
2502 void
2503 _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
2504 int __min, int __max, size_t __len,
2505 const ctype<_CharT>& __ctype,
2506 ios_base::iostate& __err) const;
2507
2508 // Extract day or month name, or any unique array of string
2509 // literals in a const _CharT* array.
2510 void
2511 _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
2512 const _CharT** __names, size_t __indexlen,
2513 const ctype<_CharT>& __ctype,
2514 ios_base::iostate& __err) const;
2515
2516 // Extract on a component-by-component basis, via __format argument.
2517 void
2518 _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
2519 ios_base::iostate& __err, tm* __tm,
2520 const _CharT* __format) const;
2521 };
2522
2523 template<typename _CharT, typename _InIter>
2524 locale::id time_get<_CharT, _InIter>::id;
2525
2526 template<typename _CharT, typename _InIter>
2527 class time_get_byname : public time_get<_CharT, _InIter>
2528 {
2529 public:
2530 // Types:
2531 typedef _CharT char_type;
2532 typedef _InIter iter_type;
2533
2534 explicit
2535 time_get_byname(const char*, size_t __refs = 0)
2536 : time_get<_CharT, _InIter>(__refs) { }
2537
2538 protected:
2539 virtual
2540 ~time_get_byname() { }
2541 };
2542
2543 template<typename _CharT, typename _OutIter>
2544 class time_put : public locale::facet, public time_base
2545 {
2546 public:
2547 // Types:
2548 typedef _CharT char_type;
2549 typedef _OutIter iter_type;
2550
2551 static locale::id id;
2552
2553 explicit
2554 time_put(size_t __refs = 0)
2555 : facet(__refs) { }
2556
2557 iter_type
2558 put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
2559 const _CharT* __beg, const _CharT* __end) const;
2560
2561 iter_type
2562 put(iter_type __s, ios_base& __io, char_type __fill,
2563 const tm* __tm, char __format, char __mod = 0) const
2564 { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
2565
2566 protected:
2567 virtual
2568 ~time_put()
2569 { }
2570
2571 virtual iter_type
2572 do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
2573 char __format, char __mod) const;
2574 };
2575
2576 template<typename _CharT, typename _OutIter>
2577 locale::id time_put<_CharT, _OutIter>::id;
2578
2579 template<typename _CharT, typename _OutIter>
2580 class time_put_byname : public time_put<_CharT, _OutIter>
2581 {
2582 public:
2583 // Types:
2584 typedef _CharT char_type;
2585 typedef _OutIter iter_type;
2586
2587 explicit
2588 time_put_byname(const char*, size_t __refs = 0)
2589 : time_put<_CharT, _OutIter>(__refs)
2590 { };
2591
2592 protected:
2593 virtual
2594 ~time_put_byname() { }
2595 };
2596
2597
2598 class money_base
2599 {
2600 public:
2601 enum part { none, space, symbol, sign, value };
2602 struct pattern { char field[4]; };
2603
2604 static const pattern _S_default_pattern;
2605
2606 // Construct and return valid pattern consisting of some combination of:
2607 // space none symbol sign value
2608 static pattern
2609 _S_construct_pattern(char __precedes, char __space, char __posn);
2610 };
2611
2612 template<typename _CharT>
2613 struct __moneypunct_cache : public locale::facet
2614 {
2615 const char* _M_grouping;
2616 bool _M_use_grouping;
2617 _CharT _M_decimal_point;
2618 _CharT _M_thousands_sep;
2619 const _CharT* _M_curr_symbol;
2620 const _CharT* _M_positive_sign;
2621 const _CharT* _M_negative_sign;
2622 int _M_frac_digits;
2623 money_base::pattern _M_pos_format;
2624 money_base::pattern _M_neg_format;
2625
2626 bool _M_allocated;
2627
2628 __moneypunct_cache(size_t __refs = 0) : facet(__refs),
2629 _M_grouping(NULL), _M_use_grouping(false), _M_decimal_point(_CharT()),
2630 _M_thousands_sep(_CharT()), _M_curr_symbol(NULL), _M_positive_sign(NULL),
2631 _M_negative_sign(NULL), _M_frac_digits(0),
2632 _M_pos_format(money_base::pattern()),
2633 _M_neg_format(money_base::pattern()), _M_allocated(false)
2634 { }
2635
2636 ~__moneypunct_cache();
2637
2638 void
2639 _M_cache(const locale& __loc);
2640 };
2641
2642 template<typename _CharT>
2643 __moneypunct_cache<_CharT>::~__moneypunct_cache()
2644 {
2645 if (_M_allocated)
2646 {
2647 // XXX.
2648 }
2649 }
2650
2651 template<typename _CharT, bool _Intl>
2652 class moneypunct : public locale::facet, public money_base
2653 {
2654 public:
2655 // Types:
2656 typedef _CharT char_type;
2657 typedef basic_string<_CharT> string_type;
2658 typedef __moneypunct_cache<_CharT> __cache_type;
2659
2660 private:
2661 __cache_type* _M_data;
2662
2663 public:
2664 static const bool intl = _Intl;
2665 static locale::id id;
2666
2667 explicit
2668 moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
2669 { _M_initialize_moneypunct(); }
2670
2671 explicit
2672 moneypunct(__cache_type* __cache, size_t __refs = 0)
2673 : facet(__refs), _M_data(__cache)
2674 { _M_initialize_moneypunct(); }
2675
2676 explicit
2677 moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
2678 : facet(__refs), _M_data(NULL)
2679 { _M_initialize_moneypunct(__cloc, __s); }
2680
2681 char_type
2682 decimal_point() const
2683 { return this->do_decimal_point(); }
2684
2685 char_type
2686 thousands_sep() const
2687 { return this->do_thousands_sep(); }
2688
2689 string
2690 grouping() const
2691 { return this->do_grouping(); }
2692
2693 string_type
2694 curr_symbol() const
2695 { return this->do_curr_symbol(); }
2696
2697 string_type
2698 positive_sign() const
2699 { return this->do_positive_sign(); }
2700
2701 string_type
2702 negative_sign() const
2703 { return this->do_negative_sign(); }
2704
2705 int
2706 frac_digits() const
2707 { return this->do_frac_digits(); }
2708
2709 pattern
2710 pos_format() const
2711 { return this->do_pos_format(); }
2712
2713 pattern
2714 neg_format() const
2715 { return this->do_neg_format(); }
2716
2717 protected:
2718 virtual
2719 ~moneypunct();
2720
2721 virtual char_type
2722 do_decimal_point() const
2723 { return _M_data->_M_decimal_point; }
2724
2725 virtual char_type
2726 do_thousands_sep() const
2727 { return _M_data->_M_thousands_sep; }
2728
2729 virtual string
2730 do_grouping() const
2731 { return _M_data->_M_grouping; }
2732
2733 virtual string_type
2734 do_curr_symbol() const
2735 { return _M_data->_M_curr_symbol; }
2736
2737 virtual string_type
2738 do_positive_sign() const
2739 { return _M_data->_M_positive_sign; }
2740
2741 virtual string_type
2742 do_negative_sign() const
2743 { return _M_data->_M_negative_sign; }
2744
2745 virtual int
2746 do_frac_digits() const
2747 { return _M_data->_M_frac_digits; }
2748
2749 virtual pattern
2750 do_pos_format() const
2751 { return _M_data->_M_pos_format; }
2752
2753 virtual pattern
2754 do_neg_format() const
2755 { return _M_data->_M_neg_format; }
2756
2757 // For use at construction time only.
2758 void
2759 _M_initialize_moneypunct(__c_locale __cloc = NULL,
2760 const char* __name = NULL);
2761 };
2762
2763 template<typename _CharT, bool _Intl>
2764 locale::id moneypunct<_CharT, _Intl>::id;
2765
2766 template<typename _CharT, bool _Intl>
2767 const bool moneypunct<_CharT, _Intl>::intl;
2768
2769 template<>
2770 moneypunct<char, true>::~moneypunct();
2771
2772 template<>
2773 moneypunct<char, false>::~moneypunct();
2774
2775 template<>
2776 void
2777 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
2778
2779 template<>
2780 void
2781 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
2782
2783 #ifdef _GLIBCXX_USE_WCHAR_T
2784 template<>
2785 moneypunct<wchar_t, true>::~moneypunct();
2786
2787 template<>
2788 moneypunct<wchar_t, false>::~moneypunct();
2789
2790 template<>
2791 void
2792 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
2793 const char*);
2794
2795 template<>
2796 void
2797 moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
2798 const char*);
2799 #endif
2800
2801 template<typename _CharT, bool _Intl>
2802 class moneypunct_byname : public moneypunct<_CharT, _Intl>
2803 {
2804 public:
2805 typedef _CharT char_type;
2806 typedef basic_string<_CharT> string_type;
2807
2808 static const bool intl = _Intl;
2809
2810 explicit
2811 moneypunct_byname(const char* __s, size_t __refs = 0)
2812 : moneypunct<_CharT, _Intl>(__refs)
2813 {
2814 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
2815 {
2816 __c_locale __tmp;
2817 this->_S_create_c_locale(__tmp, __s);
2818 this->_M_initialize_moneypunct(__tmp);
2819 this->_S_destroy_c_locale(__tmp);
2820 }
2821 }
2822
2823 protected:
2824 virtual
2825 ~moneypunct_byname() { }
2826 };
2827
2828 template<typename _CharT, bool _Intl>
2829 const bool moneypunct_byname<_CharT, _Intl>::intl;
2830
2831 template<typename _CharT, typename _InIter>
2832 class money_get : public locale::facet
2833 {
2834 public:
2835 // Types:
2836 typedef _CharT char_type;
2837 typedef _InIter iter_type;
2838 typedef basic_string<_CharT> string_type;
2839
2840 static locale::id id;
2841
2842 explicit
2843 money_get(size_t __refs = 0) : facet(__refs) { }
2844
2845 iter_type
2846 get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
2847 ios_base::iostate& __err, long double& __units) const
2848 { return this->do_get(__s, __end, __intl, __io, __err, __units); }
2849
2850 iter_type
2851 get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
2852 ios_base::iostate& __err, string_type& __digits) const
2853 { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
2854
2855 protected:
2856 virtual
2857 ~money_get() { }
2858
2859 virtual iter_type
2860 do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
2861 ios_base::iostate& __err, long double& __units) const;
2862
2863 virtual iter_type
2864 do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
2865 ios_base::iostate& __err, string_type& __digits) const;
2866 };
2867
2868 template<typename _CharT, typename _InIter>
2869 locale::id money_get<_CharT, _InIter>::id;
2870
2871 template<typename _CharT, typename _OutIter>
2872 class money_put : public locale::facet
2873 {
2874 public:
2875 typedef _CharT char_type;
2876 typedef _OutIter iter_type;
2877 typedef basic_string<_CharT> string_type;
2878
2879 static locale::id id;
2880
2881 explicit
2882 money_put(size_t __refs = 0) : facet(__refs) { }
2883
2884 iter_type
2885 put(iter_type __s, bool __intl, ios_base& __io,
2886 char_type __fill, long double __units) const
2887 { return this->do_put(__s, __intl, __io, __fill, __units); }
2888
2889 iter_type
2890 put(iter_type __s, bool __intl, ios_base& __io,
2891 char_type __fill, const string_type& __digits) const
2892 { return this->do_put(__s, __intl, __io, __fill, __digits); }
2893
2894 protected:
2895 virtual
2896 ~money_put() { }
2897
2898 virtual iter_type
2899 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
2900 long double __units) const;
2901
2902 virtual iter_type
2903 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
2904 const string_type& __digits) const;
2905 };
2906
2907 template<typename _CharT, typename _OutIter>
2908 locale::id money_put<_CharT, _OutIter>::id;
2909
2910
2911 struct messages_base
2912 {
2913 typedef int catalog;
2914 };
2915
2916 template<typename _CharT>
2917 class messages : public locale::facet, public messages_base
2918 {
2919 public:
2920 // Types:
2921 typedef _CharT char_type;
2922 typedef basic_string<_CharT> string_type;
2923
2924 protected:
2925 // Underlying "C" library locale information saved from
2926 // initialization, needed by messages_byname as well.
2927 __c_locale _M_c_locale_messages;
2928 const char* _M_name_messages;
2929
2930 public:
2931 static locale::id id;
2932
2933 explicit
2934 messages(size_t __refs = 0);
2935
2936 // Non-standard.
2937 explicit
2938 messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
2939
2940 catalog
2941 open(const basic_string<char>& __s, const locale& __loc) const
2942 { return this->do_open(__s, __loc); }
2943
2944 // Non-standard and unorthodox, yet effective.
2945 catalog
2946 open(const basic_string<char>&, const locale&, const char*) const;
2947
2948 string_type
2949 get(catalog __c, int __set, int __msgid, const string_type& __s) const
2950 { return this->do_get(__c, __set, __msgid, __s); }
2951
2952 void
2953 close(catalog __c) const
2954 { return this->do_close(__c); }
2955
2956 protected:
2957 virtual
2958 ~messages();
2959
2960 virtual catalog
2961 do_open(const basic_string<char>&, const locale&) const;
2962
2963 virtual string_type
2964 do_get(catalog, int, int, const string_type& __dfault) const;
2965
2966 virtual void
2967 do_close(catalog) const;
2968
2969 // Returns a locale and codeset-converted string, given a char* message.
2970 char*
2971 _M_convert_to_char(const string_type& __msg) const
2972 {
2973 // XXX
2974 return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
2975 }
2976
2977 // Returns a locale and codeset-converted string, given a char* message.
2978 string_type
2979 _M_convert_from_char(char* __msg) const
2980 {
2981 // Length of message string without terminating null.
2982 size_t __len = char_traits<char>::length(__msg) - 1;
2983
2984 // "everybody can easily convert the string using
2985 // mbsrtowcs/wcsrtombs or with iconv()"
2986 #if 0
2987 // Convert char* to _CharT in locale used to open catalog.
2988 // XXX need additional template parameter on messages class for this..
2989 // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
2990 typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
2991
2992 __codecvt_type::state_type __state;
2993 // XXX may need to initialize state.
2994 //initialize_state(__state._M_init());
2995
2996 char* __from_next;
2997 // XXX what size for this string?
2998 _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
2999 const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
3000 __cvt.out(__state, __msg, __msg + __len, __from_next,
3001 __to, __to + __len + 1, __to_next);
3002 return string_type(__to);
3003 #endif
3004 #if 0
3005 typedef ctype<_CharT> __ctype_type;
3006 // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
3007 const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
3008 // XXX Again, proper length of converted string an issue here.
3009 // For now, assume the converted length is not larger.
3010 _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
3011 __cvt.widen(__msg, __msg + __len, __dest);
3012 return basic_string<_CharT>(__dest);
3013 #endif
3014 return string_type();
3015 }
3016 };
3017
3018 template<typename _CharT>
3019 locale::id messages<_CharT>::id;
3020
3021 // Specializations for required instantiations.
3022 template<>
3023 string
3024 messages<char>::do_get(catalog, int, int, const string&) const;
3025
3026 #ifdef _GLIBCXX_USE_WCHAR_T
3027 template<>
3028 wstring
3029 messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
3030 #endif
3031
3032 template<typename _CharT>
3033 class messages_byname : public messages<_CharT>
3034 {
3035 public:
3036 typedef _CharT char_type;
3037 typedef basic_string<_CharT> string_type;
3038
3039 explicit
3040 messages_byname(const char* __s, size_t __refs = 0);
3041
3042 protected:
3043 virtual
3044 ~messages_byname()
3045 { }
3046 };
3047
3048 // Include host and configuration specific messages functions.
3049 #include <bits/messages_members.h>
3050
3051
3052 // Subclause convenience interfaces, inlines.
3053 // NB: These are inline because, when used in a loop, some compilers
3054 // can hoist the body out of the loop; then it's just as fast as the
3055 // C is*() function.
3056 template<typename _CharT>
3057 inline bool
3058 isspace(_CharT __c, const locale& __loc)
3059 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
3060
3061 template<typename _CharT>
3062 inline bool
3063 isprint(_CharT __c, const locale& __loc)
3064 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
3065
3066 template<typename _CharT>
3067 inline bool
3068 iscntrl(_CharT __c, const locale& __loc)
3069 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
3070
3071 template<typename _CharT>
3072 inline bool
3073 isupper(_CharT __c, const locale& __loc)
3074 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
3075
3076 template<typename _CharT>
3077 inline bool islower(_CharT __c, const locale& __loc)
3078 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
3079
3080 template<typename _CharT>
3081 inline bool
3082 isalpha(_CharT __c, const locale& __loc)
3083 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
3084
3085 template<typename _CharT>
3086 inline bool
3087 isdigit(_CharT __c, const locale& __loc)
3088 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
3089
3090 template<typename _CharT>
3091 inline bool
3092 ispunct(_CharT __c, const locale& __loc)
3093 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
3094
3095 template<typename _CharT>
3096 inline bool
3097 isxdigit(_CharT __c, const locale& __loc)
3098 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
3099
3100 template<typename _CharT>
3101 inline bool
3102 isalnum(_CharT __c, const locale& __loc)
3103 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
3104
3105 template<typename _CharT>
3106 inline bool
3107 isgraph(_CharT __c, const locale& __loc)
3108 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
3109
3110 template<typename _CharT>
3111 inline _CharT
3112 toupper(_CharT __c, const locale& __loc)
3113 { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
3114
3115 template<typename _CharT>
3116 inline _CharT
3117 tolower(_CharT __c, const locale& __loc)
3118 { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
3119 } // namespace std
3120
3121 #endif