aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits/locale_facets.tcc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/bits/locale_facets.tcc')
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc519
1 files changed, 411 insertions, 108 deletions
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 02ae96eeb51..d362c33f87f 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -41,9 +41,7 @@
#include <cmath> // For ceil
#include <cctype> // For isspace
#include <limits> // For numeric_limits
-#include <memory> // For auto_ptr
#include <bits/streambuf_iterator.h>
-#include <vector>
#include <typeinfo> // For bad_cast.
namespace std
@@ -72,21 +70,20 @@ namespace std
const _Facet&
use_facet(const locale& __loc)
{
- size_t __i = _Facet::id._M_index;
- locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
- const locale::facet* __fp = (*__facet)[__i];
- if (__fp == 0 || __i >= __facet->size())
+ size_t __i = _Facet::id._M_id();
+ locale::facet** __facets = __loc._M_impl->_M_facets;
+ if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
__throw_bad_cast();
- return static_cast<const _Facet&>(*__fp);
+ return static_cast<const _Facet&>(*__facets[__i]);
}
template<typename _Facet>
bool
has_facet(const locale& __loc) throw()
{
- size_t __i = _Facet::id._M_index;
- locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
- return (__i < __facet->size() && (*__facet)[__i] != 0);
+ size_t __i = _Facet::id._M_id();
+ locale::facet** __facets = __loc._M_impl->_M_facets;
+ return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
}
@@ -174,7 +171,11 @@ namespace std
}
else if (__c == __dec && !__found_dec)
{
- __found_grouping += static_cast<char>(__sep_pos);
+ // According to the standard, if no grouping chars are seen,
+ // no grouping check is applied. Therefore __found_grouping
+ // must be adjusted only if __dec comes after some __sep.
+ if (__found_grouping.size())
+ __found_grouping += static_cast<char>(__sep_pos);
++__pos;
__xtrc += '.';
__c = *(++__beg);
@@ -310,7 +311,7 @@ namespace std
__ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
string __found_grouping;
const string __grouping = __np.grouping();
- bool __check_grouping = __grouping.size() && __base == 10;
+ bool __check_grouping = __grouping.size();
int __sep_pos = 0;
const char_type __sep = __np.thousands_sep();
while (__beg != __end)
@@ -393,19 +394,21 @@ namespace std
// Parse bool values as alphanumeric
else
{
+ typedef basic_string<_CharT> __string_type;
locale __loc = __io.getloc();
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- const char_type* __true = __np.truename().c_str();
- const char_type* __false = __np.falsename().c_str();
-
- const size_t __truen = __np.truename().size() - 1;
- const size_t __falsen = __np.falsename().size() - 1;
+ const __string_type __true = __np.truename();
+ const __string_type __false = __np.falsename();
+ const char_type* __trues = __true.c_str();
+ const char_type* __falses = __false.c_str();
+ const size_t __truen = __true.size() - 1;
+ const size_t __falsen = __false.size() - 1;
for (size_t __n = 0; __beg != __end; ++__n)
{
char_type __c = *__beg++;
- bool __testf = __n <= __falsen ? __c == __false[__n] : false;
- bool __testt = __n <= __truen ? __c == __true[__n] : false;
+ bool __testf = __n <= __falsen ? __c == __falses[__n] : false;
+ bool __testt = __n <= __truen ? __c == __trues[__n] : false;
if (!(__testf || __testt))
{
__err |= ios_base::failbit;
@@ -589,16 +592,15 @@ namespace std
return __beg;
}
-
- // The following code uses sprintf() to convert floating point
- // values for insertion into a stream. An optimization would be to
- // replace sprintf() with code that works directly on a wide buffer
- // and then use __pad to do the padding. It would be good
- // to replace sprintf() anyway to avoid accidental buffer overruns
- // and to gain back the efficiency that C++ provides by knowing up
- // front the type of the values to insert. This implementation
- // follows the C++ standard fairly directly as outlined in 22.2.2.2
- // [lib.locale.num.put]
+ // The following code uses snprintf (or sprintf(), when _GLIBCPP_USE_C99
+ // is not defined) to convert floating point values for insertion into a
+ // stream. An optimization would be to replace them with code that works
+ // directly on a wide buffer and then use __pad to do the padding.
+ // It would be good to replace them anyway to gain back the efficiency
+ // that C++ provides by knowing up front the type of the values to insert.
+ // Also, sprintf is dangerous since may lead to accidental buffer overruns.
+ // This implementation follows the C++ standard fairly directly as
+ // outlined in 22.2.2.2 [lib.locale.num.put]
template<typename _CharT, typename _OutIter>
template<typename _ValueT>
_OutIter
@@ -606,15 +608,45 @@ namespace std
_M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
_ValueT __v) const
{
- const int __max_digits = numeric_limits<_ValueT>::digits10;
+ // Note: digits10 is rounded down. We need to add 1 to ensure
+ // we get the full available precision.
+ const int __max_digits = numeric_limits<_ValueT>::digits10 + 1;
streamsize __prec = __io.precision();
- // Protect against sprintf() buffer overflows.
+
if (__prec > static_cast<streamsize>(__max_digits))
__prec = static_cast<streamsize>(__max_digits);
// Long enough for the max format spec.
char __fbuf[16];
+ // [22.2.2.2.2] Stage 1, numeric conversion to character.
+ int __len;
+#ifdef _GLIBCPP_USE_C99
+ // First try a buffer perhaps big enough (for sure sufficient for
+ // non-ios_base::fixed outputs)
+ int __cs_size = __max_digits * 3;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+
+ const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec);
+ if (__fp)
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale, __prec);
+ else
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
+
+ // If the buffer was not large enough, try again with the correct size.
+ if (__len >= __cs_size)
+ {
+ __cs_size = __len + 1;
+ __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ if (__fp)
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale, __prec);
+ else
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale);
+ }
+#else
// Consider the possibility of long ios_base::fixed outputs
const bool __fixed = __io.flags() & ios_base::fixed;
const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
@@ -627,12 +659,11 @@ namespace std
: __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
- int __len;
- // [22.2.2.2.2] Stage 1, numeric conversion to character.
if (_S_format_float(__io, __fbuf, __mod, __prec))
- __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale, __prec);
+ __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
else
- __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
+ __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
+#endif
return _M_widen_float(__s, __io, __fill, __cs, __len);
}
@@ -644,13 +675,30 @@ namespace std
char __modl, _ValueT __v) const
{
// [22.2.2.2.2] Stage 1, numeric conversion to character.
- // Leave room for "+/-," "0x," and commas. This size is
- // arbitrary, but should work.
- char __cs[64];
+
// Long enough for the max format spec.
char __fbuf[16];
_S_format_int(__io, __fbuf, __mod, __modl);
- int __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
+#ifdef _GLIBCPP_USE_C99
+ // First try a buffer perhaps big enough.
+ int __cs_size = 64;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale);
+ // If the buffer was not large enough, try again with the correct size.
+ if (__len >= __cs_size)
+ {
+ __cs_size = __len + 1;
+ __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale);
+ }
+#else
+ // Leave room for "+/-," "0x," and commas. This size is
+ // arbitrary, but should be largely sufficient.
+ char __cs[128];
+ int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
+#endif
return _M_widen_int(__s, __io, __fill, __cs, __len);
}
@@ -726,18 +774,33 @@ namespace std
* __len * 2));
__ctype.widen(__cs, __cs + __len, __ws);
- // Add grouping, if necessary.
+ // Add grouping, if necessary.
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
const string __grouping = __np.grouping();
- ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
- bool __dec = __basefield != ios_base::oct
- && __basefield != ios_base::hex;
- if (__grouping.size() && __dec)
+ const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+ if (__grouping.size())
{
+ // By itself __add_grouping cannot deal correctly with __ws when
+ // ios::showbase is set and ios_base::oct || ios_base::hex.
+ // Therefore we take care "by hand" of the initial 0, 0x or 0X.
+ streamsize __off = 0;
+ if (__io.flags() & ios_base::showbase)
+ if (__basefield == ios_base::oct)
+ {
+ __off = 1;
+ *__ws2 = *__ws;
+ }
+ else if (__basefield == ios_base::hex)
+ {
+ __off = 2;
+ *__ws2 = *__ws;
+ *(__ws2 + 1) = *(__ws + 1);
+ }
_CharT* __p;
- __p = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(),
+ __p = __add_grouping(__ws2 + __off, __np.thousands_sep(),
+ __grouping.c_str(),
__grouping.c_str() + __grouping.size(),
- __ws, __ws + __len);
+ __ws + __off, __ws + __len);
__len = __p - __ws2;
// Switch strings.
__ws = __ws2;
@@ -786,21 +849,15 @@ namespace std
}
else
{
+ typedef basic_string<_CharT> __string_type;
locale __loc = __io.getloc();
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- const char_type* __ws;
- int __len;
+ __string_type __name;
if (__v)
- {
- __ws = __np.truename().c_str();
- __len = __np.truename().size();
- }
+ __name = __np.truename();
else
- {
- __ws = __np.falsename().c_str();
- __len = __np.falsename().size();
- }
- __s = _M_insert(__s, __io, __fill, __ws, __len);
+ __name = __np.falsename();
+ __s = _M_insert(__s, __io, __fill, __name.c_str(), __name.size());
}
return __s;
}
@@ -881,7 +938,7 @@ namespace std
__beg = this->do_get(__beg, __end, __intl, __io, __err, __str);
const int __n = numeric_limits<long double>::digits10;
- char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
+ char* __cs = static_cast<char*>(__builtin_alloca(__n));
const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
const _CharT* __wcs = __str.c_str();
@@ -943,15 +1000,16 @@ namespace std
switch (__which)
{
case money_base::symbol:
- if (__io.flags() & ios_base::showbase
- || __i < 2
- || (__i == 2 && static_cast<part>(__p.field[3]) != money_base::none)
- || __sign.size() > 1)
+ if (__io.flags() & ios_base::showbase
+ || __i < 2 || __sign.size() > 1
+ || ((static_cast<part>(__p.field[3]) != money_base::none)
+ && __i == 2))
{
- // According to 22.2.6.1.2.2, symbol is required if
- // (__io.flags() & ios_base::showbase), otherwise is optional
- // and consumed only if other characters are needed to complete
- // the format.
+ // According to 22.2.6.1.2.2, symbol is required
+ // if (__io.flags() & ios_base::showbase),
+ // otherwise is optional and consumed only if
+ // other characters are needed to complete the
+ // format.
const string_type __symbol = __intl ? __mpt.curr_symbol()
: __mpf.curr_symbol();
size_type __len = __symbol.size();
@@ -962,7 +1020,8 @@ namespace std
__c = *(++__beg);
++__j;
}
- // When (__io.flags() & ios_base::showbase) symbol is required.
+ // When (__io.flags() & ios_base::showbase)
+ // symbol is required.
if (__j != __len && (__io.flags() & ios_base::showbase))
__testvalid = false;
}
@@ -1091,11 +1150,29 @@ namespace std
long double __units) const
{
const locale __loc = __io.getloc();
- const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
- const int __n = numeric_limits<long double>::digits10;
- char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
- _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
- int __len = __convert_from_v(__cs, "%.01Lf", __units, _S_c_locale);
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+#ifdef _GLIBCPP_USE_C99
+ // First try a buffer perhaps big enough.
+ int __cs_size = 64;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units,
+ _S_c_locale);
+ // If the buffer was not large enough, try again with the correct size.
+ if (__len >= __cs_size)
+ {
+ __cs_size = __len + 1;
+ __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units,
+ _S_c_locale);
+ }
+#else
+ // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
+ // decimal digit, '\0'.
+ const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+ int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
+#endif
+ _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size));
__ctype.widen(__cs, __cs + __len, __ws);
string_type __digits(__ws);
return this->do_put(__s, __intl, __io, __fill, __digits);
@@ -1187,8 +1264,9 @@ namespace std
: __mpf.thousands_sep();
const char* __gbeg = __grouping.c_str();
const char* __gend = __gbeg + __grouping.size();
- const int __n = numeric_limits<long double>::digits10 * 2;
- _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
+ const int __n = (__end - __beg) * 2;
+ _CharT* __ws2 =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
_CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg,
__gend, __beg, __end);
__value.insert(0, __ws2, __ws_end - __ws2);
@@ -1776,7 +1854,8 @@ namespace std
// NB: This size is arbitrary. Should this be a data member,
// initialized at construction?
const size_t __maxlen = 64;
- char_type* __res = static_cast<char_type*>(__builtin_alloca(__maxlen));
+ char_type* __res =
+ static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
// NB: In IEE 1003.1-200x, and perhaps other locale models, it
// is possible that the format character will be longer than one
@@ -1797,7 +1876,7 @@ namespace std
__fmt[3] = char_type();
}
- __tp._M_put_helper(__res, __maxlen, __fmt, __tm);
+ __tp._M_put(__res, __maxlen, __fmt, __tm);
// Write resulting, fully-formatted string to output iterator.
size_t __len = char_traits<char_type>::length(__res);
@@ -1810,13 +1889,13 @@ namespace std
// Generic version does nothing.
template<typename _CharT>
int
- collate<_CharT>::_M_compare_helper(const _CharT*, const _CharT*) const
+ collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
{ return 0; }
// Generic version does nothing.
template<typename _CharT>
size_t
- collate<_CharT>::_M_transform_helper(_CharT*, const _CharT*, size_t) const
+ collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
{ return 0; }
template<typename _CharT>
@@ -1827,7 +1906,7 @@ namespace std
{
const string_type __one(__lo1, __hi1);
const string_type __two(__lo2, __hi2);
- return _M_compare_helper(__one.c_str(), __two.c_str());
+ return _M_compare(__one.c_str(), __two.c_str());
}
template<typename _CharT>
@@ -1835,16 +1914,17 @@ namespace std
collate<_CharT>::
do_transform(const _CharT* __lo, const _CharT* __hi) const
{
- size_t __len = __hi - __lo;
- _CharT* __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
- size_t __res = _M_transform_helper(__c, __lo, __len);
+ size_t __len = (__hi - __lo) * 2;
+ // First try a buffer perhaps big enough.
+ _CharT* __c =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
+ size_t __res = _M_transform(__c, __lo, __len);
+ // If the buffer was not large enough, try again with the correct size.
if (__res >= __len)
{
- // Try to increment size of translated string.
- size_t __len2 = __len * 2;
- _CharT* __c2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len2));
- __res = _M_transform_helper(__c2, __lo, __len);
- // XXX Throw exception if still indeterminate?
+ __c =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__res + 1)));
+ _M_transform(__c, __lo, __res + 1);
}
return string_type(__c);
}
@@ -1870,20 +1950,39 @@ namespace std
const __c_locale& __cloc, int __base = 10);
// Convert numeric value of type _Tv to string and return length of string.
+ // If snprintf is available use it, otherwise fall back to the unsafe sprintf
+ // which, in general, can be dangerous and should be avoided.
+#ifdef _GLIBCPP_USE_C99
template<typename _Tv>
int
- __convert_from_v(char* __out, const char* __fmt, _Tv __v,
+ __convert_from_v(char* __out, const int __size, const char* __fmt,
+ _Tv __v, const __c_locale&, int __prec = -1)
+ {
+ int __ret;
+ const char* __old = setlocale(LC_ALL, "C");
+ if (__prec >= 0)
+ __ret = snprintf(__out, __size, __fmt, __prec, __v);
+ else
+ __ret = snprintf(__out, __size, __fmt, __v);
+ setlocale(LC_ALL, __old);
+ return __ret;
+ }
+#else
+ template<typename _Tv>
+ int
+ __convert_from_v(char* __out, const int, const char* __fmt, _Tv __v,
const __c_locale&, int __prec = -1)
{
int __ret;
const char* __old = setlocale(LC_ALL, "C");
if (__prec >= 0)
- __ret = sprintf(__out, __fmt, __prec, __v);
+ __ret = sprintf(__out, __fmt, __prec, __v);
else
- __ret = sprintf(__out, __fmt, __v);
+ __ret = sprintf(__out, __fmt, __v);
setlocale(LC_ALL, __old);
return __ret;
}
+#endif
// Construct correctly padded string, as per 22.2.2.2.2
// Assumes
@@ -2048,32 +2147,32 @@ namespace std
extern template class moneypunct<char, true>;
extern template class moneypunct_byname<char, false>;
extern template class moneypunct_byname<char, true>;
- extern template class money_get<char, istreambuf_iterator<char> >;
- extern template class money_put<char, ostreambuf_iterator<char> >;
+ extern template class money_get<char>;
+ extern template class money_put<char>;
extern template class moneypunct<wchar_t, false>;
extern template class moneypunct<wchar_t, true>;
extern template class moneypunct_byname<wchar_t, false>;
extern template class moneypunct_byname<wchar_t, true>;
- extern template class money_get<wchar_t, istreambuf_iterator<wchar_t> >;
- extern template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >;
+ extern template class money_get<wchar_t>;
+ extern template class money_put<wchar_t>;
extern template class numpunct<char>;
extern template class numpunct_byname<char>;
- extern template class num_get<char, istreambuf_iterator<char> >;
- extern template class num_put<char, ostreambuf_iterator<char> >;
+ extern template class num_get<char>;
+ extern template class num_put<char>;
extern template class numpunct<wchar_t>;
extern template class numpunct_byname<wchar_t>;
- extern template class num_get<wchar_t, istreambuf_iterator<wchar_t> >;
- extern template class num_put<wchar_t, ostreambuf_iterator<wchar_t> >;
+ extern template class num_get<wchar_t>;
+ extern template class num_put<wchar_t>;
extern template class __timepunct<char>;
- extern template class time_put<char, ostreambuf_iterator<char> >;
- extern template class time_put_byname<char, ostreambuf_iterator<char> >;
- extern template class time_get<char, istreambuf_iterator<char> >;
- extern template class time_get_byname<char, istreambuf_iterator<char> >;
+ extern template class time_put<char>;
+ extern template class time_put_byname<char>;
+ extern template class time_get<char>;
+ extern template class time_get_byname<char>;
extern template class __timepunct<wchar_t>;
- extern template class time_put<wchar_t, ostreambuf_iterator<wchar_t> >;
- extern template class time_put_byname<wchar_t, ostreambuf_iterator<wchar_t> >;
- extern template class time_get<wchar_t, istreambuf_iterator<wchar_t> >;
- extern template class time_get_byname<wchar_t, istreambuf_iterator<wchar_t> >;
+ extern template class time_put<wchar_t>;
+ extern template class time_put_byname<wchar_t>;
+ extern template class time_get<wchar_t>;
+ extern template class time_get_byname<wchar_t>;
extern template class messages<char>;
extern template class messages_byname<char>;
extern template class messages<wchar_t>;
@@ -2086,13 +2185,217 @@ namespace std
extern template class collate_byname<char>;
extern template class collate<wchar_t>;
extern template class collate_byname<wchar_t>;
-} // namespace std
-#endif
+ extern template
+ const codecvt<char, char, mbstate_t>&
+ use_facet<codecvt<char, char, mbstate_t> >(const locale&);
+
+ extern template
+ const collate<char>&
+ use_facet<collate<char> >(const locale&);
+
+ extern template
+ const numpunct<char>&
+ use_facet<numpunct<char> >(const locale&);
+ extern template
+ const num_put<char>&
+ use_facet<num_put<char> >(const locale&);
+ extern template
+ const num_get<char>&
+ use_facet<num_get<char> >(const locale&);
+ extern template
+ const moneypunct<char, true>&
+ use_facet<moneypunct<char, true> >(const locale&);
+
+ extern template
+ const moneypunct<char, false>&
+ use_facet<moneypunct<char, false> >(const locale&);
+
+ extern template
+ const money_put<char>&
+ use_facet<money_put<char> >(const locale&);
+
+ extern template
+ const money_get<char>&
+ use_facet<money_get<char> >(const locale&);
+
+ extern template
+ const __timepunct<char>&
+ use_facet<__timepunct<char> >(const locale&);
+
+ extern template
+ const time_put<char>&
+ use_facet<time_put<char> >(const locale&);
+
+ extern template
+ const time_get<char>&
+ use_facet<time_get<char> >(const locale&);
+
+ extern template
+ const messages<char>&
+ use_facet<messages<char> >(const locale&);
+
+ extern template
+ const codecvt<wchar_t, char, mbstate_t>&
+ use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&);
+
+ extern template
+ const collate<wchar_t>&
+ use_facet<collate<wchar_t> >(const locale&);
+
+ extern template
+ const numpunct<wchar_t>&
+ use_facet<numpunct<wchar_t> >(const locale&);
+
+ extern template
+ const num_put<wchar_t>&
+ use_facet<num_put<wchar_t> >(const locale&);
+
+ extern template
+ const num_get<wchar_t>&
+ use_facet<num_get<wchar_t> >(const locale&);
+
+ extern template
+ const moneypunct<wchar_t, true>&
+ use_facet<moneypunct<wchar_t, true> >(const locale&);
+
+ extern template
+ const moneypunct<wchar_t, false>&
+ use_facet<moneypunct<wchar_t, false> >(const locale&);
+
+ extern template
+ const money_put<wchar_t>&
+ use_facet<money_put<wchar_t> >(const locale&);
+ extern template
+ const money_get<wchar_t>&
+ use_facet<money_get<wchar_t> >(const locale&);
+ extern template
+ const __timepunct<wchar_t>&
+ use_facet<__timepunct<wchar_t> >(const locale&);
+
+ extern template
+ const time_put<wchar_t>&
+ use_facet<time_put<wchar_t> >(const locale&);
+
+ extern template
+ const time_get<wchar_t>&
+ use_facet<time_get<wchar_t> >(const locale&);
+
+ extern template
+ const messages<wchar_t>&
+ use_facet<messages<wchar_t> >(const locale&);
+
+
+ extern template
+ bool
+ has_facet<ctype<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<codecvt<char, char, mbstate_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<collate<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<numpunct<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<num_put<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<num_get<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<moneypunct<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<money_put<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<money_get<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<__timepunct<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<time_put<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<time_get<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<messages<char> >(const locale&);
+
+ extern template
+ bool
+ has_facet<ctype<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<collate<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<numpunct<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<num_put<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<num_get<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<moneypunct<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<money_put<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<money_get<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<__timepunct<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<time_put<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<time_get<wchar_t> >(const locale&);
+
+ extern template
+ bool
+ has_facet<messages<wchar_t> >(const locale&);
+} // namespace std
+
+#endif