1 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 2, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING. If not, write to the Free
16 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // As a special exception, you may use this file as part of a free software
20 // library without restriction. Specifically, if other files instantiate
21 // templates or use macros or inline functions from this file, or you compile
22 // this file and link it with other files to produce an executable, this
23 // file does not by itself cause the resulting executable to be covered by
24 // the GNU General Public License. This exception does not however
25 // invalidate any other reasons why the executable file might be covered by
26 // the GNU General Public License.
28 #include <bits/std_clocale.h>
29 #include <bits/std_cstring.h>
30 #include <bits/std_cassert.h>
31 #include <bits/std_cctype.h>
32 #include <bits/std_limits.h>
34 #include <bits/std_stdexcept.h>
35 #include <bits/std_locale.h>
36 #include <bits/std_istream.h>
37 #include <bits/std_ostream.h>
38 #include <bits/std_vector.h>
39 #include <bits/std_memory.h> // for auto_ptr
40 #ifdef _GLIBCPP_USE_WCHAR_T
41 # include <bits/std_cwctype.h> // for towupper, etc.
46 // Defined in globals.cc.
47 extern locale::_Impl locale_impl_c
;
48 extern locale locale_c
;
50 // Definitions for static const data members of locale.
51 const locale::category
locale::none
;
52 const locale::category
locale::ctype
;
53 const locale::category
locale::numeric
;
54 const locale::category
locale::collate
;
55 const locale::category
locale::time
;
56 const locale::category
locale::monetary
;
57 const locale::category
locale::messages
;
58 const locale::category
locale::all
;
60 locale::_Impl
* locale::_S_classic
;
61 locale::_Impl
* locale::_S_global
;
62 const size_t locale::_S_num_categories
;
63 const size_t locale::_S_num_facets
;
65 // Definitions for locale::id of standard facets.
66 locale::id ctype
<char>::id
;
67 locale::id codecvt
<char, char, mbstate_t>::id
;
69 #ifdef _GLIBCPP_USE_WCHAR_T
70 locale::id ctype
<wchar_t>::id
;
71 locale::id codecvt
<wchar_t, char, mbstate_t>::id
;
74 // Definitions for static const data members of locale::id
75 size_t locale::id::_S_highwater
; // init'd to 0 by linker
77 // Definitions for static const data members of locale::_Impl
78 const locale::id
* const
79 locale::_Impl::_S_id_ctype
[] =
81 &std::ctype
<char>::id
,
82 &codecvt
<char, char, mbstate_t>::id
,
83 #ifdef _GLIBCPP_USE_WCHAR_T
84 &std::ctype
<wchar_t>::id
,
85 &codecvt
<wchar_t, char, mbstate_t>::id
,
90 const locale::id
* const
91 locale::_Impl::_S_id_numeric
[] =
96 #ifdef _GLIBCPP_USE_WCHAR_T
97 &num_get
<wchar_t>::id
,
98 &num_put
<wchar_t>::id
,
99 &numpunct
<wchar_t>::id
,
104 const locale::id
* const
105 locale::_Impl::_S_id_collate
[] =
107 &std::collate
<char>::id
,
108 #ifdef _GLIBCPP_USE_WCHAR_T
109 &std::collate
<wchar_t>::id
,
114 const locale::id
* const
115 locale::_Impl::_S_id_time
[] =
119 #ifdef _GLIBCPP_USE_WCHAR_T
120 &time_get
<wchar_t>::id
,
121 &time_put
<wchar_t>::id
,
126 const locale::id
* const
127 locale::_Impl::_S_id_monetary
[] =
129 &money_get
<char>::id
,
130 &money_put
<char>::id
,
131 &moneypunct
<char, false>::id
,
132 &moneypunct
<char, true >::id
,
133 #ifdef _GLIBCPP_USE_WCHAR_T
134 &money_get
<wchar_t>::id
,
135 &money_put
<wchar_t>::id
,
136 &moneypunct
<wchar_t, false>::id
,
137 &moneypunct
<wchar_t, true >::id
,
142 const locale::id
* const
143 locale::_Impl::_S_id_messages
[] =
145 &std::messages
<char>::id
,
146 #ifdef _GLIBCPP_USE_WCHAR_T
147 &std::messages
<wchar_t>::id
,
152 const locale::id
* const* const
153 locale::_Impl::_S_facet_categories
[] =
155 // Order must match the decl order in class locale.
156 locale::_Impl::_S_id_ctype
,
157 locale::_Impl::_S_id_numeric
,
158 locale::_Impl::_S_id_collate
,
159 locale::_Impl::_S_id_time
,
160 locale::_Impl::_S_id_monetary
,
161 locale::_Impl::_S_id_messages
,
165 // Construct and return valid pattern consisting of some combination of:
166 // space none symbol sign value
168 money_base::_S_construct_pattern(char __preceeds
, char __space
, char __posn
)
172 // This insanely complicated routine attempts to construct a valid
173 // pattern for use with monyepunct. A couple of invariants:
175 // if (__preceeds) symbol -> value
176 // else value -> symbol
178 // if (__space) space
181 // none == never first
182 // space never first or last
184 // Any elegant implementations of this are welcome.
188 // 1 The sign precedes the value and symbol.
191 // Pattern starts with sign.
194 __ret
.field
[1] = symbol
;
195 __ret
.field
[2] = space
;
196 __ret
.field
[3] = value
;
200 __ret
.field
[1] = value
;
201 __ret
.field
[2] = space
;
202 __ret
.field
[3] = symbol
;
204 __ret
.field
[0] = sign
;
208 // Pattern starts with sign and ends with none.
211 __ret
.field
[1] = symbol
;
212 __ret
.field
[2] = value
;
216 __ret
.field
[1] = value
;
217 __ret
.field
[2] = symbol
;
219 __ret
.field
[0] = sign
;
220 __ret
.field
[3] = none
;
224 // 2 The sign follows the value and symbol.
227 // Pattern either ends with sign.
230 __ret
.field
[0] = symbol
;
231 __ret
.field
[1] = space
;
232 __ret
.field
[2] = value
;
236 __ret
.field
[0] = value
;
237 __ret
.field
[1] = space
;
238 __ret
.field
[2] = symbol
;
240 __ret
.field
[3] = sign
;
244 // Pattern ends with sign then none.
247 __ret
.field
[0] = symbol
;
248 __ret
.field
[1] = value
;
252 __ret
.field
[0] = value
;
253 __ret
.field
[1] = symbol
;
255 __ret
.field
[2] = sign
;
256 __ret
.field
[3] = none
;
260 // 3 The sign immediately precedes the symbol.
266 __ret
.field
[0] = sign
;
267 __ret
.field
[1] = symbol
;
268 __ret
.field
[2] = space
;
269 __ret
.field
[3] = value
;
273 __ret
.field
[0] = value
;
274 __ret
.field
[1] = space
;
275 __ret
.field
[2] = sign
;
276 __ret
.field
[3] = symbol
;
284 __ret
.field
[0] = sign
;
285 __ret
.field
[1] = symbol
;
286 __ret
.field
[2] = value
;
290 __ret
.field
[0] = value
;
291 __ret
.field
[1] = sign
;
292 __ret
.field
[2] = symbol
;
294 __ret
.field
[3] = none
;
298 // 4 The sign immediately follows the symbol.
304 __ret
.field
[0] = symbol
;
305 __ret
.field
[1] = sign
;
306 __ret
.field
[2] = space
;
307 __ret
.field
[3] = value
;
311 __ret
.field
[0] = value
;
312 __ret
.field
[1] = space
;
313 __ret
.field
[2] = symbol
;
314 __ret
.field
[3] = sign
;
322 __ret
.field
[0] = symbol
;
323 __ret
.field
[1] = sign
;
324 __ret
.field
[2] = value
;
328 __ret
.field
[0] = value
;
329 __ret
.field
[1] = symbol
;
330 __ret
.field
[2] = sign
;
332 __ret
.field
[3] = none
;
341 locale::~locale() throw()
342 { _M_impl
->_M_remove_reference(); }
345 locale::_M_coalesce(const locale
& __base
, const locale
& __add
,
348 __cat
= _S_normalize_category(__cat
);
349 _M_impl
= new _Impl(*__base
._M_impl
, 1);
352 { _M_impl
->_M_replace_categories(__add
._M_impl
, __cat
); }
355 _M_impl
->_M_remove_reference();
356 __throw_exception_again
;
360 locale::locale() throw()
363 (_M_impl
= _S_global
)->_M_add_reference();
366 locale::locale(const locale
& __other
) throw()
367 { (_M_impl
= __other
._M_impl
)->_M_add_reference(); }
369 // This is used to initialize global and classic locales, and
370 // assumes that the _Impl objects are constructed correctly.
371 locale::locale(_Impl
* __ip
) throw() : _M_impl(__ip
)
374 locale::locale(const char* __s
)
379 if (strcmp(__s
, "C") == 0 || strcmp(__s
, "POSIX") == 0)
380 (_M_impl
= _S_classic
)->_M_add_reference();
382 _M_impl
= new _Impl(__s
, 1);
385 __throw_runtime_error("attempt to create locale from NULL name");
388 locale::locale(const locale
& __base
, const char* __s
, category __cat
)
390 // NB: There are complicated, yet more efficient ways to do
391 // this. Building up locales on a per-category way is tedious, so
392 // let's do it this way until people complain.
394 _M_coalesce(__base
, __add
, __cat
);
397 locale::locale(const locale
& __base
, const locale
& __add
, category __cat
)
398 { _M_coalesce(__base
, __add
, __cat
); }
401 locale::operator==(const locale
& __rhs
) const throw()
403 string __name
= this->name();
404 return (_M_impl
== __rhs
._M_impl
405 || (__name
!= "*" && __name
== __rhs
.name()));
409 locale::operator=(const locale
& __other
) throw()
411 __other
._M_impl
->_M_add_reference();
412 _M_impl
->_M_remove_reference();
413 _M_impl
= __other
._M_impl
;
418 locale::global(const locale
& __other
)
422 _Impl
* __old
= _S_global
;
423 __other
._M_impl
->_M_add_reference();
424 _S_global
= __other
._M_impl
;
425 if (_S_global
->_M_check_same_name() && _S_global
->_M_names
[0] != "*")
426 setlocale(LC_ALL
, __other
.name().c_str());
428 // Reference count sanity check: one reference removed for the
429 // subsition of __other locale, one added by return-by-value. Net
430 // difference: zero. When the returned locale object's destrutor
431 // is called, then the reference count is decremented and possibly
433 return locale(__old
);
440 // Need some kind of separator character. This one was pretty much
441 // arbitrarily chosen as to not conflict with glibc locales: the
442 // exact formatting is not set in stone.
443 const char __separator
= '|';
445 if (_M_impl
->_M_check_same_name())
446 __ret
= _M_impl
->_M_names
[0];
449 for (size_t i
= 0; i
< _S_num_categories
; ++i
)
450 __ret
+= __separator
+ _M_impl
->_M_names
[i
];
463 // 26 Standard facets, 2 references.
464 // One reference for _M_classic, one for _M_global
465 _S_classic
= new (&locale_impl_c
) _Impl("C", 2);
466 _S_global
= _S_classic
;
467 new (&locale_c
) locale(_S_classic
);
471 // Just call destructor, so that locale_impl_c's memory is
472 // not deallocated via a call to delete.
474 _S_classic
->~_Impl();
475 _S_classic
= _S_global
= 0;
476 __throw_exception_again
;
483 locale::_S_normalize_category(category __cat
)
486 if (__cat
== none
|| (__cat
& all
) && !(__cat
& ~all
))
490 // NB: May be a C-style "LC_ALL" category; convert.
508 #ifdef _GLIBCPP_HAVE_LC_MESSAGES
517 __throw_runtime_error("bad locale category");
524 facet(size_t __refs
) throw() : _M_references(__refs
)
529 _M_add_reference() throw()
530 { ++_M_references
; } // XXX MT
534 _M_remove_reference() throw()
536 if (_M_references
-- == 0)
545 // Definitions for static const data members of ctype_base.
546 const ctype_base::mask
ctype_base::space
;
547 const ctype_base::mask
ctype_base::print
;
548 const ctype_base::mask
ctype_base::cntrl
;
549 const ctype_base::mask
ctype_base::upper
;
550 const ctype_base::mask
ctype_base::lower
;
551 const ctype_base::mask
ctype_base::alpha
;
552 const ctype_base::mask
ctype_base::digit
;
553 const ctype_base::mask
ctype_base::punct
;
554 const ctype_base::mask
ctype_base::xdigit
;
555 const ctype_base::mask
ctype_base::alnum
;
556 const ctype_base::mask
ctype_base::graph
;
558 // Platform-specific initialization code for ctype tables.
559 #include <bits/ctype_noninline.h>
561 const size_t ctype
<char>::table_size
;
563 ctype
<char>::~ctype()
564 { if (_M_del
) delete[] this->table(); }
566 // These are dummy placeholders as these virtual functions are never called.
568 ctype
<char>::do_is(mask
, char_type
) const
572 ctype
<char>::do_is(const char_type
* __c
, const char_type
*, mask
*) const
576 ctype
<char>::do_scan_is(mask
, const char_type
* __c
, const char_type
*) const
580 ctype
<char>::do_scan_not(mask
, const char_type
* __c
, const char_type
*) const
584 ctype
<char>::do_widen(char __c
) const
588 ctype
<char>::do_widen(const char* __lo
, const char* __hi
, char* __dest
) const
590 memcpy(__dest
, __lo
, __hi
- __lo
);
595 ctype
<char>::do_narrow(char __c
, char /*__dfault*/) const
599 ctype
<char>::do_narrow(const char* __lo
, const char* __hi
,
600 char /*__dfault*/, char* __dest
) const
602 memcpy(__dest
, __lo
, __hi
- __lo
);
607 ctype_byname
<char>::ctype_byname(const char* /*__s*/, size_t __refs
)
608 : ctype
<char>(new mask
[table_size
], true, __refs
)
611 // Definitions for static const data members of money_base
612 const money_base::pattern
613 money_base::_S_default_pattern
= {{symbol
, sign
, none
, value
}};
616 _Format_cache
<char>::_Format_cache()
618 _M_decimal_point('.'), _M_thousands_sep(','),
619 _M_truename("true"), _M_falsename("false"), _M_use_grouping(false)
622 #ifdef _GLIBCPP_USE_WCHAR_T
624 _Format_cache
<wchar_t>::_Format_cache()
626 _M_decimal_point(L
'.'), _M_thousands_sep(L
','),
627 _M_truename(L
"true"), _M_falsename(L
"false"), _M_use_grouping(false)
633 use_facet
<ctype
<char> >(const locale
& __loc
)
635 size_t __i
= ctype
<char>::id
._M_index
;
636 const locale::_Impl
* __tmp
= __loc
._M_impl
;
637 return static_cast<const ctype
<char>&>(* (*(__tmp
->_M_facets
))[__i
]);
640 #ifdef _GLIBCPP_USE_WCHAR_T
642 const ctype
<wchar_t>&
643 use_facet
<ctype
<wchar_t> >(const locale
& __loc
)
645 size_t __i
= ctype
<wchar_t>::id
._M_index
;
646 const locale::_Impl
* __tmp
= __loc
._M_impl
;
647 return static_cast<const ctype
<wchar_t>&>(* (*(__tmp
->_M_facets
))[__i
]);
653 num_get
<char, istreambuf_iterator
<char> >::
654 _M_extract(istreambuf_iterator
<char> __beg
,
655 istreambuf_iterator
<char> __end
, ios_base
& __io
,
656 ios_base::iostate
& __err
, char* __xtrc
, int& __base
,
659 typedef _Format_cache
<char> __cache_type
;
661 // Prepare for possible failure
664 // Stage 1: determine a conversion specifier.
665 ios_base::fmtflags __basefield
= __io
.flags() & ios_base::basefield
;
666 if (__basefield
== ios_base::dec
)
668 else if (__basefield
== ios_base::oct
)
670 else if (__basefield
== ios_base::hex
)
674 // As far as I can tell, bases other than 10 are not available for
675 // floating point types
679 // Stage 2: extract characters.
680 __cache_type
const* __fmt
= __cache_type::_S_get(__io
);
682 // Fail quickly if !__valid
685 __err
|= (ios_base::eofbit
| ios_base::failbit
);
689 // Acceptable formats for numbers here are based on 22.2.3.1
693 const char* __lits
= __fmt
->_S_literals
;
696 // Check first for sign
697 bool __testsign
= false;
698 if ((__c
== __lits
[__cache_type::_S_minus
])
699 || (__c
== __lits
[__cache_type::_S_plus
]))
702 __xtrc
[__pos
++] = __c
;
706 // Whitespace may follow a sign
707 while ((__beg
!= __end
) && (isspace(__c
)))
713 // There had better be more to come...
716 __xtrc
[__pos
] = '\0';
717 __err
|= (ios_base::eofbit
| ios_base::failbit
);
722 // Now check if first character is a zero.
723 bool __testzero
= false;
724 if (__c
== __lits
[__cache_type::_S_digits
])
730 // We have to check for __beg == __end here. If so,
731 // a plain '0' (possibly with a sign) can be got rid of now
734 __xtrc
[__pos
++] = __lits
[__cache_type::_S_digits
];
735 __xtrc
[__pos
] = '\0';
736 __err
|= ios_base::eofbit
;
740 // Figure out base for integer types only
741 // Based on Table 55 of 22.2.2.1.2
742 if (!__fp
&& __base
!= 10 && __base
!= 8)
744 // Here, __base == 0 or 16
745 if ((__c
== __lits
[__cache_type::_S_x
])
746 || (__c
== __lits
[__cache_type::_S_X
]))
751 __testzero
= false; // "0x" is not a leading zero
753 else if (__base
== 0)
757 // Remove any more leading zeros
758 while (__beg
!= __end
)
760 if (__c
== __lits
[__cache_type::_S_digits
])
770 else if (__base
== 0) // 1st character is not zero
773 // We now seek "units", i.e. digits and thousands separators.
774 // We may need to know if anything is found here. A leading zero
775 // (removed by now) would count.
776 bool __testunits
= __testzero
;
777 while (__beg
!= __end
)
779 const char* __p
= strchr(__lits
, __c
);
781 // NB: strchr returns true for __c == 0x0
783 &&((__p
>= &__lits
[__cache_type::_S_digits
]
784 && __p
< &__lits
[__cache_type::_S_digits
+ __base
])
785 || (__p
>= &__lits
[__cache_type::_S_udigits
]
786 && __p
< &__lits
[__cache_type::_S_udigits
+ __base
])))
788 // Try first for acceptable digit; record it if found.
789 __xtrc
[__pos
++] = __c
;
795 else if (__c
== __fmt
->_M_thousands_sep
&& __fmt
->_M_use_grouping
)
797 // NB: Thousands separator at the beginning of a string
798 // is a no-no, as is two consecutive thousands
802 __grp
+= static_cast<char>(__sep_pos
);
809 __err
|= ios_base::failbit
;
814 // Not a valid input item.
818 // Digit grouping is checked. If _M_groupings() doesn't
819 // match, then get very very upset, and set failbit.
820 if (__fmt
->_M_use_grouping
&& !__grp
.empty())
822 // Add the ending grouping
823 __grp
+= static_cast<char>(__sep_pos
);
825 // __grp is parsed L to R
826 // 1,222,444 == __grp of "/1/3/3"
827 // __fmt->_M_grouping is parsed R to L
828 // 1,222,444 == __fmt->_M_grouping of "/3" == "/3/3/3"
831 const int __len
= __fmt
->_M_grouping
.size();
832 int __n
= __grp
.size();
835 // Parsed number groupings have to match the
836 // numpunct::grouping string exactly, starting at the
837 // right-most point of the parsed sequence of elements ...
838 while (__test
&& __i
< __n
- 1)
839 for (__j
= 0; __test
&& __j
< __len
&& __i
< __n
- 1; ++__j
,++__i
)
840 __test
&= __fmt
->_M_grouping
[__j
] == __grp
[__n
- __i
- 1];
841 // ... but the last parsed grouping can be <= numpunct
843 __j
== __len
? __j
= 0 : __j
;
844 __test
&= __fmt
->_M_grouping
[__j
] >= __grp
[__n
- __i
- 1];
848 __err
|= ios_base::failbit
;
849 __xtrc
[__pos
] = '\0';
851 __err
|= ios_base::eofbit
;
856 // If there was nothing but zeros, put one in the output string
857 if (__testzero
&& (__pos
== 0 || (__pos
== 1 && __testsign
)))
858 __xtrc
[__pos
++] = __lits
[__cache_type::_S_digits
];
860 // That's it for integer types. Remaining code is for floating point
861 if (__fp
&& __beg
!= __end
)
863 // Check first for decimal point. There MUST be one if
864 // __testunits is false.
865 bool __testdec
= false; // Is there a decimal point
866 // with digits following it?
867 if (__c
== __fmt
->_M_decimal_point
)
869 __xtrc
[__pos
++] = '.';
873 // Now we get any digits after the decimal point
874 // There MUST be some if __testunits is false.
875 while (__beg
!= __end
)
877 const char* __p
= strchr(__lits
, __c
);
878 if ((__p
>= &__lits
[__cache_type::_S_digits
]
879 && __p
< &__lits
[__cache_type::_S_digits
+ __base
])
880 || (__p
>= &__lits
[__cache_type::_S_udigits
]
881 && __p
< &__lits
[__cache_type::_S_udigits
+ __base
]))
883 __xtrc
[__pos
++] = __c
;
892 if (!__testunits
&& !__testdec
) // Ill formed
894 __err
|= ios_base::failbit
;
895 __xtrc
[__pos
] = '\0';
897 __err
|= ios_base::eofbit
;
901 // Now we may find an exponent
904 if ((__c
== __lits
[__cache_type::_S_ee
])
905 || (__c
== __lits
[__cache_type::_S_Ee
]))
907 __xtrc
[__pos
++] = __c
;
911 // Now there may be a sign
914 if ((__c
== __lits
[__cache_type::_S_minus
])
915 || (__c
== __lits
[__cache_type::_S_plus
]))
917 __xtrc
[__pos
++] = __c
;
920 // whitespace may follow a sign
921 while ((__beg
!= __end
) && (isspace(__c
)))
928 // And now there must be some digits
931 __xtrc
[__pos
] = '\0';
932 __err
|= (ios_base::eofbit
| ios_base::failbit
);
935 while (__beg
!= __end
)
937 const char* __p
= strchr(__lits
, __c
);
938 if ((__p
>= &__lits
[__cache_type::_S_digits
]
939 && __p
< &__lits
[__cache_type::_S_digits
+ __base
])
940 || (__p
>= &__lits
[__cache_type::_S_udigits
]
941 && __p
< &__lits
[__cache_type::_S_udigits
+ __base
]))
943 __xtrc
[__pos
++] = __c
;
952 // Finally, that's it for floating point
956 __xtrc
[__pos
] = '\0';
958 __err
|= ios_base::eofbit
;
961 // The following code uses sprintf() to convert floating point
962 // values for insertion into a stream. The current implementation
963 // replicates the code in _S_pad_numeric() (in _S_output_float()) in
964 // order to prevent having to create a "wide" buffer in addition to
965 // the "narrow" buffer passed to sprintf(). An optimization would be
966 // to replace sprintf() with code that works directly on a wide
967 // buffer and then use _S_pad_numeric() to do the padding. It would
968 // be good to replace sprintf() anyway to avoid accidental buffer
969 // overruns and to gain back the efficiency that C++ provides by
970 // knowing up front the type of the values to insert. This
971 // implementation follows the C++ standard fairly directly as
972 // outlined in 22.2.2.2 [lib.locale.num.put]
974 __build_float_format(ios_base
& __io
, char* __fptr
, char __modifier
,
977 bool __incl_prec
= false;
978 ios_base::fmtflags __flags
= __io
.flags();
980 // [22.2.2.2.2] Table 60
981 if (__flags
& ios_base::showpos
)
983 if (__flags
& ios_base::showpoint
)
985 // As per [22.2.2.2.2.11]
986 if (__flags
& ios_base::fixed
|| __prec
> 0)
993 *__fptr
++ = __modifier
;
994 ios_base::fmtflags __fltfield
= __flags
& ios_base::floatfield
;
995 // [22.2.2.2.2] Table 58
996 if (__fltfield
== ios_base::fixed
)
998 else if (__fltfield
== ios_base::scientific
)
999 *__fptr
++ = (__flags
& ios_base::uppercase
) ? 'E' : 'e';
1001 *__fptr
++ = (__flags
& ios_base::uppercase
) ? 'G' : 'g';
1007 collate
<char>::collate(size_t __refs
)
1008 : locale::facet(__refs
) { }
1011 collate
<char>::~collate() { }
1015 collate
<char>::do_compare(const char* __lo1
, const char* __hi1
,
1016 const char* __lo2
, const char* __hi2
) const
1018 for (; __lo1
< __hi1
&& __lo2
< __hi2
; ++__lo1
, ++__lo2
)
1019 if (*__lo1
!= *__lo2
)
1020 return (*__lo1
< *__lo2
) ? -1 : 1;
1023 else if (__lo2
< __hi2
)
1032 do_transform(const char* __lo
, const char* __hi
) const
1033 { return string(__lo
, __hi
- __lo
); }
1038 do_hash(const char* __lo
, const char* __hi
) const
1040 unsigned long __val
= 0xdeadbeef;
1041 for (; __lo
< __hi
; ++__lo
)
1042 __val
= *__lo
^ ((__val
<< 7) &
1043 (__val
>> (numeric_limits
<unsigned long>::digits
- 1)));
1048 collate_byname
<char>::collate_byname(const char* /*__s*/, size_t __refs
)
1049 : collate
<char>(__refs
) { }
1052 moneypunct_byname
<char, false>::moneypunct_byname(const char* /*__s*/,
1054 : moneypunct
<char, false>(__refs
) { }
1057 moneypunct_byname
<char, true>::moneypunct_byname(const char* /*__s*/,
1059 : moneypunct
<char, true>(__refs
) { }
1062 messages_byname
<char>::
1063 messages_byname(const char* /*__s*/, size_t __refs
)
1064 : messages
<char>(__refs
) { }
1066 #ifdef _GLIBCPP_USE_WCHAR_T
1067 ctype
<wchar_t>::__wmask_type
1068 ctype
<wchar_t>::_M_convert_to_wmask(const mask __m
) const
1074 __ret
= wctype("space");
1077 __ret
= wctype("print");
1080 __ret
= wctype("cntrl");
1083 __ret
= wctype("upper");
1086 __ret
= wctype("lower");
1089 __ret
= wctype("alpha");
1092 __ret
= wctype("digit");
1095 __ret
= wctype("punct");
1098 __ret
= wctype("xdigit");
1101 __ret
= wctype("alnum");
1104 __ret
= wctype("graph");
1112 ctype
<wchar_t>::~ctype() { }
1114 // NB: These ctype<wchar_t> methods are not configuration-specific,
1115 // unlike the ctype<char> bits.
1116 ctype
<wchar_t>::ctype(size_t __refs
) : __ctype_abstract_base
<wchar_t>(__refs
)
1120 ctype
<wchar_t>::do_toupper(wchar_t __c
) const
1121 { return towupper(__c
); }
1124 ctype
<wchar_t>::do_toupper(wchar_t* __lo
, const wchar_t* __hi
) const
1128 *__lo
= towupper(*__lo
);
1135 ctype
<wchar_t>::do_tolower(wchar_t __c
) const
1136 { return towlower(__c
); }
1139 ctype
<wchar_t>::do_tolower(wchar_t* __lo
, const wchar_t* __hi
) const
1143 *__lo
= towlower(*__lo
);
1151 do_is(mask __m
, char_type __c
) const
1152 { return static_cast<bool>(iswctype(__c
, _M_convert_to_wmask(__m
))); }
1156 do_is(const wchar_t* __lo
, const wchar_t* __hi
, mask
* __m
) const
1158 while (__lo
< __hi
&& !this->is(*__m
, *__lo
))
1165 do_scan_is(mask __m
, const wchar_t* __lo
, const wchar_t* __hi
) const
1167 while (__lo
< __hi
&& !this->is(__m
, *__lo
))
1174 do_scan_not(mask __m
, const char_type
* __lo
, const char_type
* __hi
) const
1176 while (__lo
< __hi
&& this->is(__m
, *__lo
) != 0)
1183 do_widen(char __c
) const
1184 { return btowc(__c
); }
1188 do_widen(const char* __lo
, const char* __hi
, wchar_t* __dest
) const
1191 memset(static_cast<void*>(&__state
), 0, sizeof(mbstate_t));
1192 mbsrtowcs(__dest
, &__lo
, __hi
- __lo
, &__state
);
1198 do_narrow(wchar_t __wc
, char __dfault
) const
1200 int __c
= wctob(__wc
);
1201 return (__c
== EOF
? __dfault
: static_cast<char>(__c
));
1206 do_narrow(const wchar_t* __lo
, const wchar_t* __hi
, char __dfault
,
1210 memset(static_cast<void*>(&__state
), 0, sizeof(mbstate_t));
1211 size_t __len
= __hi
- __lo
;
1212 size_t __conv
= wcsrtombs(__dest
, &__lo
, __len
, &__state
);
1213 if (__conv
== __len
)
1219 ctype_byname
<wchar_t>::
1220 ctype_byname(const char* /*__s*/, size_t __refs
)
1221 : ctype
<wchar_t>(__refs
) { }
1225 collate(size_t __refs
): locale::facet(__refs
) { }
1234 do_compare(const wchar_t* /*__lo1*/, const wchar_t* /*__hi1*/,
1235 const wchar_t* /*__lo2*/, const wchar_t* /*__hi2*/) const
1237 return 0; // XXX not done
1241 wstring collate
<wchar_t>::
1242 do_transform(const wchar_t* /*__lo*/, const wchar_t* /*__hi*/) const
1244 return wstring(); // XXX not done
1248 long collate
<wchar_t>::
1249 do_hash(const wchar_t* /*__lo*/, const wchar_t* /*__hi*/) const
1251 return 0; // XXX not done
1255 collate_byname
<wchar_t>::
1256 collate_byname(const char* /*__s*/, size_t __refs
)
1257 : collate
<wchar_t> (__refs
) { }
1260 messages_byname
<wchar_t>::
1261 messages_byname(const char* /*__s*/, size_t __refs
)
1262 : messages
<wchar_t> (__refs
) { }
1263 #endif // _GLIBCPP_USE_WCHAR_T