| 1 |
/* |
| 2 |
* Copyright (c) 1999 |
| 3 |
* Silicon Graphics Computer Systems, Inc. |
| 4 |
* |
| 5 |
* Copyright (c) 1999 |
| 6 |
* Boris Fomitchev |
| 7 |
* |
| 8 |
* This material is provided "as is", with absolutely no warranty expressed |
| 9 |
* or implied. Any use is at your own risk. |
| 10 |
* |
| 11 |
* Permission to use or copy this software for any purpose is hereby granted |
| 12 |
* without fee, provided the above notices are retained on all copies. |
| 13 |
* Permission to modify the code and to distribute modified code is granted, |
| 14 |
* provided the above notices are retained, and a notice that the code was |
| 15 |
* modified is included with the above copyright notice. |
| 16 |
* |
| 17 |
*/ |
| 18 |
|
| 19 |
#include "stlport_prefix.h" |
| 20 |
|
| 21 |
#include <locale> |
| 22 |
#include <stdexcept> |
| 23 |
|
| 24 |
#include "c_locale.h" |
| 25 |
#include "locale_impl.h" |
| 26 |
|
| 27 |
_STLP_BEGIN_NAMESPACE |
| 28 |
|
| 29 |
static const string _Nameless("*"); |
| 30 |
|
| 31 |
static inline bool is_C_locale_name (const char* name) |
| 32 |
{ return ((name[0] == 'C') && (name[1] == 0)); } |
| 33 |
|
| 34 |
locale* _Stl_get_classic_locale(); |
| 35 |
locale* _Stl_get_global_locale(); |
| 36 |
|
| 37 |
#if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) || \ |
| 38 |
defined (_STLP_SIGNAL_RUNTIME_COMPATIBILITY) || defined (_STLP_CHECK_RUNTIME_COMPATIBILITY) |
| 39 |
# define locale _STLP_NO_MEM_T_NAME(loc) |
| 40 |
#endif |
| 41 |
|
| 42 |
locale::facet::~facet() {} |
| 43 |
|
| 44 |
#if defined (_STLP_INLINE_MEMBER_TEMPLATES) |
| 45 |
// members that fail to be templates |
| 46 |
bool locale::operator()(const string& __x, |
| 47 |
const string& __y) const |
| 48 |
{ return __locale_do_operator_call(*this, __x, __y); } |
| 49 |
|
| 50 |
# if !defined (_STLP_NO_WCHAR_T) |
| 51 |
bool locale::operator()(const wstring& __x, |
| 52 |
const wstring& __y) const |
| 53 |
{ return __locale_do_operator_call(*this, __x, __y); } |
| 54 |
# endif |
| 55 |
#endif |
| 56 |
|
| 57 |
void _STLP_CALL locale::_M_throw_on_null_name() |
| 58 |
{ _STLP_THROW(runtime_error("Invalid null locale name")); } |
| 59 |
|
| 60 |
void _STLP_CALL locale::_M_throw_on_combine_error(const string& name) { |
| 61 |
string what = "Unable to find facet"; |
| 62 |
what += " in "; |
| 63 |
what += name.empty() ? "system" : name.c_str(); |
| 64 |
what += " locale"; |
| 65 |
_STLP_THROW(runtime_error(what.c_str())); |
| 66 |
} |
| 67 |
|
| 68 |
void _STLP_CALL locale::_M_throw_on_creation_failure(int __err_code, |
| 69 |
const char* name, const char* facet) { |
| 70 |
string what; |
| 71 |
switch (__err_code) { |
| 72 |
case _STLP_LOC_UNSUPPORTED_FACET_CATEGORY: |
| 73 |
what = "No platform localization support for "; |
| 74 |
what += facet; |
| 75 |
what += " facet category, unable to create facet for "; |
| 76 |
what += name[0] == 0 ? "system" : name; |
| 77 |
what += " locale"; |
| 78 |
break; |
| 79 |
case _STLP_LOC_NO_PLATFORM_SUPPORT: |
| 80 |
what = "No platform localization support, unable to create "; |
| 81 |
what += name[0] == 0 ? "system" : name; |
| 82 |
what += " locale"; |
| 83 |
break; |
| 84 |
default: |
| 85 |
case _STLP_LOC_UNKNOWN_NAME: |
| 86 |
what = "Unable to create facet "; |
| 87 |
what += facet; |
| 88 |
what += " from name '"; |
| 89 |
what += name; |
| 90 |
what += "'"; |
| 91 |
break; |
| 92 |
case _STLP_LOC_NO_MEMORY: |
| 93 |
_STLP_THROW_BAD_ALLOC; |
| 94 |
break; |
| 95 |
} |
| 96 |
|
| 97 |
_STLP_THROW(runtime_error(what.c_str())); |
| 98 |
} |
| 99 |
|
| 100 |
// Takes a reference to a locale::id, assign a numeric index if not already |
| 101 |
// affected and returns it. The returned index is always positive. |
| 102 |
static const locale::id& _Stl_loc_get_index(locale::id& id) { |
| 103 |
if (id._M_index == 0) { |
| 104 |
#if defined (_STLP_ATOMIC_INCREMENT) && !defined (_STLP_WIN95_LIKE) |
| 105 |
static _STLP_VOLATILE __stl_atomic_t _S_index = __STATIC_CAST(__stl_atomic_t, locale::id::_S_max); |
| 106 |
id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index); |
| 107 |
#else |
| 108 |
static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER; |
| 109 |
_STLP_auto_lock sentry(_Index_lock); |
| 110 |
size_t new_index = locale::id::_S_max++; |
| 111 |
id._M_index = new_index; |
| 112 |
#endif |
| 113 |
} |
| 114 |
return id; |
| 115 |
} |
| 116 |
|
| 117 |
// Default constructor: create a copy of the global locale. |
| 118 |
locale::locale() _STLP_NOTHROW |
| 119 |
: _M_impl(_get_Locale_impl(_Stl_get_global_locale()->_M_impl)) |
| 120 |
{} |
| 121 |
|
| 122 |
// Copy constructor |
| 123 |
locale::locale(const locale& L) _STLP_NOTHROW |
| 124 |
: _M_impl( _get_Locale_impl( L._M_impl ) ) |
| 125 |
{} |
| 126 |
|
| 127 |
void locale::_M_insert(facet* f, locale::id& n) { |
| 128 |
if (f) |
| 129 |
_M_impl->insert(f, _Stl_loc_get_index(n)); |
| 130 |
} |
| 131 |
|
| 132 |
locale::locale( _Locale_impl* impl ) : |
| 133 |
_M_impl( _get_Locale_impl( impl ) ) |
| 134 |
{} |
| 135 |
|
| 136 |
// Create a locale from a name. |
| 137 |
locale::locale(const char* name) |
| 138 |
: _M_impl(0) { |
| 139 |
if (!name) |
| 140 |
_M_throw_on_null_name(); |
| 141 |
|
| 142 |
if (is_C_locale_name(name)) { |
| 143 |
_M_impl = _get_Locale_impl( locale::classic()._M_impl ); |
| 144 |
return; |
| 145 |
} |
| 146 |
|
| 147 |
_Locale_impl* impl = 0; |
| 148 |
_STLP_TRY { |
| 149 |
impl = new _Locale_impl(locale::id::_S_max, name); |
| 150 |
|
| 151 |
// Insert categories one at a time. |
| 152 |
const char* ctype_name = name; |
| 153 |
char ctype_buf[_Locale_MAX_SIMPLE_NAME]; |
| 154 |
const char* numeric_name = name; |
| 155 |
char numeric_buf[_Locale_MAX_SIMPLE_NAME]; |
| 156 |
const char* time_name = name; |
| 157 |
char time_buf[_Locale_MAX_SIMPLE_NAME]; |
| 158 |
const char* collate_name = name; |
| 159 |
char collate_buf[_Locale_MAX_SIMPLE_NAME]; |
| 160 |
const char* monetary_name = name; |
| 161 |
char monetary_buf[_Locale_MAX_SIMPLE_NAME]; |
| 162 |
const char* messages_name = name; |
| 163 |
char messages_buf[_Locale_MAX_SIMPLE_NAME]; |
| 164 |
impl->insert_ctype_facets(ctype_name, ctype_buf ); |
| 165 |
impl->insert_numeric_facets(numeric_name, numeric_buf ); |
| 166 |
impl->insert_time_facets(time_name, time_buf ); |
| 167 |
impl->insert_collate_facets(collate_name, collate_buf ); |
| 168 |
impl->insert_monetary_facets(monetary_name, monetary_buf ); |
| 169 |
impl->insert_messages_facets(messages_name, messages_buf ); |
| 170 |
|
| 171 |
// Try to use a normalize locale name in order to have the == operator |
| 172 |
// to behave correctly: |
| 173 |
if (strcmp(ctype_name, numeric_name) == 0 && |
| 174 |
strcmp(ctype_name, time_name) == 0 && |
| 175 |
strcmp(ctype_name, collate_name) == 0 && |
| 176 |
strcmp(ctype_name, monetary_name) == 0 && |
| 177 |
strcmp(ctype_name, messages_name) == 0) { |
| 178 |
impl->name = ctype_name; |
| 179 |
} |
| 180 |
// else we keep current name. |
| 181 |
|
| 182 |
// reassign impl |
| 183 |
_M_impl = _get_Locale_impl( impl ); |
| 184 |
} |
| 185 |
_STLP_UNWIND(delete impl); |
| 186 |
} |
| 187 |
|
| 188 |
static void _Stl_loc_combine_names_aux(_Locale_impl* L, |
| 189 |
const char* name, |
| 190 |
const char* ctype_name, const char* time_name, const char* numeric_name, |
| 191 |
const char* collate_name, const char* monetary_name, const char* messages_name, |
| 192 |
locale::category c) { |
| 193 |
// This function is only called when names has been validated so using _Locale_extract_*_name |
| 194 |
// can't fail. |
| 195 |
int __err_code; |
| 196 |
char buf[_Locale_MAX_SIMPLE_NAME]; |
| 197 |
L->name = string("LC_CTYPE=") + _Locale_extract_ctype_name((c & locale::ctype) ? ctype_name : name, buf, 0, &__err_code) + ";"; |
| 198 |
L->name += string("LC_TIME=") + _Locale_extract_time_name((c & locale::time) ? time_name : name, buf, 0, &__err_code) + ";"; |
| 199 |
L->name += string("LC_NUMERIC=") + _Locale_extract_numeric_name((c & locale::numeric) ? numeric_name : name, buf, 0, &__err_code) + ";"; |
| 200 |
L->name += string("LC_COLLATE=") + _Locale_extract_collate_name((c & locale::collate) ? collate_name : name, buf, 0, &__err_code) + ";"; |
| 201 |
L->name += string("LC_MONETARY=") + _Locale_extract_monetary_name((c & locale::monetary) ? monetary_name : name, buf, 0, &__err_code) + ";"; |
| 202 |
L->name += string("LC_MESSAGES=") + _Locale_extract_messages_name((c & locale::messages) ? messages_name : name, buf, 0, &__err_code); |
| 203 |
} |
| 204 |
|
| 205 |
// Give L a name where all facets except those in category c |
| 206 |
// are taken from name1, and those in category c are taken from name2. |
| 207 |
static void _Stl_loc_combine_names(_Locale_impl* L, |
| 208 |
const char* name1, const char* name2, |
| 209 |
locale::category c) { |
| 210 |
if ((c & locale::all) == 0 || strcmp(name1, name1) == 0) |
| 211 |
L->name = name1; |
| 212 |
else if ((c & locale::all) == locale::all) |
| 213 |
L->name = name2; |
| 214 |
else { |
| 215 |
_Stl_loc_combine_names_aux(L, name1, name2, name2, name2, name2, name2, name2, c); |
| 216 |
} |
| 217 |
} |
| 218 |
|
| 219 |
static void _Stl_loc_combine_names(_Locale_impl* L, |
| 220 |
const char* name, |
| 221 |
const char* ctype_name, const char* time_name, const char* numeric_name, |
| 222 |
const char* collate_name, const char* monetary_name, const char* messages_name, |
| 223 |
locale::category c) { |
| 224 |
if ((c & locale::all) == 0 || (strcmp(name, ctype_name) == 0 && |
| 225 |
strcmp(name, time_name) == 0 && |
| 226 |
strcmp(name, numeric_name) == 0 && |
| 227 |
strcmp(name, collate_name) == 0 && |
| 228 |
strcmp(name, monetary_name) == 0 && |
| 229 |
strcmp(name, messages_name) == 0)) |
| 230 |
L->name = name; |
| 231 |
else if ((c & locale::all) == locale::all && strcmp(ctype_name, time_name) == 0 && |
| 232 |
strcmp(ctype_name, numeric_name) == 0 && |
| 233 |
strcmp(ctype_name, collate_name) == 0 && |
| 234 |
strcmp(ctype_name, monetary_name) == 0 && |
| 235 |
strcmp(ctype_name, messages_name) == 0) |
| 236 |
L->name = ctype_name; |
| 237 |
else { |
| 238 |
_Stl_loc_combine_names_aux(L, name, ctype_name, time_name, numeric_name, collate_name, monetary_name, messages_name, c); |
| 239 |
} |
| 240 |
} |
| 241 |
|
| 242 |
|
| 243 |
// Create a locale that's a copy of L, except that all of the facets |
| 244 |
// in category c are instead constructed by name. |
| 245 |
locale::locale(const locale& L, const char* name, locale::category c) |
| 246 |
: _M_impl(0) { |
| 247 |
if (!name) |
| 248 |
_M_throw_on_null_name(); |
| 249 |
|
| 250 |
if (_Nameless == name) |
| 251 |
_STLP_THROW(runtime_error((string("Invalid locale name '") + _Nameless + "'").c_str())); |
| 252 |
|
| 253 |
_Locale_impl* impl = 0; |
| 254 |
|
| 255 |
_STLP_TRY { |
| 256 |
impl = new _Locale_impl(*L._M_impl); |
| 257 |
|
| 258 |
const char* ctype_name = name; |
| 259 |
char ctype_buf[_Locale_MAX_SIMPLE_NAME]; |
| 260 |
const char* numeric_name = name; |
| 261 |
char numeric_buf[_Locale_MAX_SIMPLE_NAME]; |
| 262 |
const char* time_name = name; |
| 263 |
char time_buf[_Locale_MAX_SIMPLE_NAME]; |
| 264 |
const char* collate_name = name; |
| 265 |
char collate_buf[_Locale_MAX_SIMPLE_NAME]; |
| 266 |
const char* monetary_name = name; |
| 267 |
char monetary_buf[_Locale_MAX_SIMPLE_NAME]; |
| 268 |
const char* messages_name = name; |
| 269 |
char messages_buf[_Locale_MAX_SIMPLE_NAME]; |
| 270 |
if (c & locale::ctype) |
| 271 |
impl->insert_ctype_facets(ctype_name, ctype_buf ); |
| 272 |
if (c & locale::numeric) |
| 273 |
impl->insert_numeric_facets(numeric_name, numeric_buf ); |
| 274 |
if (c & locale::time) |
| 275 |
impl->insert_time_facets(time_name, time_buf ); |
| 276 |
if (c & locale::collate) |
| 277 |
impl->insert_collate_facets(collate_name, collate_buf ); |
| 278 |
if (c & locale::monetary) |
| 279 |
impl->insert_monetary_facets(monetary_name, monetary_buf ); |
| 280 |
if (c & locale::messages) |
| 281 |
impl->insert_messages_facets(messages_name, messages_buf ); |
| 282 |
|
| 283 |
_Stl_loc_combine_names(impl, L._M_impl->name.c_str(), |
| 284 |
ctype_name, time_name, numeric_name, |
| 285 |
collate_name, monetary_name, messages_name, c); |
| 286 |
_M_impl = _get_Locale_impl( impl ); |
| 287 |
} |
| 288 |
_STLP_UNWIND(delete impl) |
| 289 |
} |
| 290 |
|
| 291 |
// Contruct a new locale where all facets that aren't in category c |
| 292 |
// come from L1, and all those that are in category c come from L2. |
| 293 |
locale::locale(const locale& L1, const locale& L2, category c) |
| 294 |
: _M_impl(0) { |
| 295 |
_Locale_impl* impl = new _Locale_impl(*L1._M_impl); |
| 296 |
|
| 297 |
_Locale_impl* i2 = L2._M_impl; |
| 298 |
|
| 299 |
if (L1.name() != _Nameless && L2.name() != _Nameless) |
| 300 |
_Stl_loc_combine_names(impl, L1._M_impl->name.c_str(), L2._M_impl->name.c_str(), c); |
| 301 |
else { |
| 302 |
impl->name = _Nameless; |
| 303 |
} |
| 304 |
|
| 305 |
if (c & collate) { |
| 306 |
impl->insert( i2, _STLP_STD::collate<char>::id); |
| 307 |
# ifndef _STLP_NO_WCHAR_T |
| 308 |
impl->insert( i2, _STLP_STD::collate<wchar_t>::id); |
| 309 |
# endif |
| 310 |
} |
| 311 |
if (c & ctype) { |
| 312 |
impl->insert( i2, _STLP_STD::ctype<char>::id); |
| 313 |
impl->insert( i2, _STLP_STD::codecvt<char, char, mbstate_t>::id); |
| 314 |
# ifndef _STLP_NO_WCHAR_T |
| 315 |
impl->insert( i2, _STLP_STD::ctype<wchar_t>::id); |
| 316 |
impl->insert( i2, _STLP_STD::codecvt<wchar_t, char, mbstate_t>::id); |
| 317 |
# endif |
| 318 |
} |
| 319 |
if (c & monetary) { |
| 320 |
impl->insert( i2, _STLP_STD::moneypunct<char, true>::id); |
| 321 |
impl->insert( i2, _STLP_STD::moneypunct<char, false>::id); |
| 322 |
impl->insert( i2, _STLP_STD::money_get<char, istreambuf_iterator<char, char_traits<char> > >::id); |
| 323 |
impl->insert( i2, _STLP_STD::money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); |
| 324 |
# ifndef _STLP_NO_WCHAR_T |
| 325 |
impl->insert( i2, _STLP_STD::moneypunct<wchar_t, true>::id); |
| 326 |
impl->insert( i2, _STLP_STD::moneypunct<wchar_t, false>::id); |
| 327 |
impl->insert( i2, _STLP_STD::money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
| 328 |
impl->insert( i2, _STLP_STD::money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
| 329 |
# endif |
| 330 |
} |
| 331 |
if (c & numeric) { |
| 332 |
impl->insert( i2, _STLP_STD::numpunct<char>::id); |
| 333 |
impl->insert( i2, _STLP_STD::num_get<char, istreambuf_iterator<char, char_traits<char> > >::id); |
| 334 |
impl->insert( i2, _STLP_STD::num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); |
| 335 |
# ifndef _STLP_NO_WCHAR_T |
| 336 |
impl->insert( i2, _STLP_STD::numpunct<wchar_t>::id); |
| 337 |
impl->insert( i2, _STLP_STD::num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
| 338 |
impl->insert( i2, _STLP_STD::num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
| 339 |
# endif |
| 340 |
} |
| 341 |
if (c & time) { |
| 342 |
impl->insert( i2, _STLP_STD::time_get<char, istreambuf_iterator<char, char_traits<char> > >::id); |
| 343 |
impl->insert( i2, _STLP_STD::time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); |
| 344 |
# ifndef _STLP_NO_WCHAR_T |
| 345 |
impl->insert( i2, _STLP_STD::time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
| 346 |
impl->insert( i2, _STLP_STD::time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); |
| 347 |
# endif |
| 348 |
} |
| 349 |
if (c & messages) { |
| 350 |
impl->insert( i2, _STLP_STD::messages<char>::id); |
| 351 |
# ifndef _STLP_NO_WCHAR_T |
| 352 |
impl->insert( i2, _STLP_STD::messages<wchar_t>::id); |
| 353 |
# endif |
| 354 |
} |
| 355 |
_M_impl = _get_Locale_impl( impl ); |
| 356 |
} |
| 357 |
|
| 358 |
// Destructor. |
| 359 |
locale::~locale() _STLP_NOTHROW { |
| 360 |
if (_M_impl) |
| 361 |
_release_Locale_impl(_M_impl); |
| 362 |
} |
| 363 |
|
| 364 |
// Assignment operator. Much like the copy constructor: just a bit of |
| 365 |
// pointer twiddling. |
| 366 |
const locale& locale::operator=(const locale& L) _STLP_NOTHROW { |
| 367 |
if (this->_M_impl != L._M_impl) { |
| 368 |
if (this->_M_impl) |
| 369 |
_release_Locale_impl(this->_M_impl); |
| 370 |
this->_M_impl = _get_Locale_impl(L._M_impl); |
| 371 |
} |
| 372 |
return *this; |
| 373 |
} |
| 374 |
|
| 375 |
locale::facet* locale::_M_get_facet(const locale::id& n) const { |
| 376 |
return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0; |
| 377 |
} |
| 378 |
|
| 379 |
locale::facet* locale::_M_use_facet(const locale::id& n) const { |
| 380 |
locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0); |
| 381 |
if (!f) |
| 382 |
_M_impl->_M_throw_bad_cast(); |
| 383 |
return f; |
| 384 |
} |
| 385 |
|
| 386 |
string locale::name() const { |
| 387 |
return _M_impl->name; |
| 388 |
} |
| 389 |
|
| 390 |
// Compare two locales for equality. |
| 391 |
bool locale::operator==(const locale& L) const { |
| 392 |
return this->_M_impl == L._M_impl || |
| 393 |
(this->name() == L.name() && this->name() != _Nameless); |
| 394 |
} |
| 395 |
|
| 396 |
bool locale::operator!=(const locale& L) const { |
| 397 |
return !(*this == L); |
| 398 |
} |
| 399 |
|
| 400 |
// static data members. |
| 401 |
|
| 402 |
const locale& _STLP_CALL locale::classic() { |
| 403 |
return *_Stl_get_classic_locale(); |
| 404 |
} |
| 405 |
|
| 406 |
#if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) |
| 407 |
locale _STLP_CALL locale::global(const locale& L) { |
| 408 |
#else |
| 409 |
_Locale_impl* _STLP_CALL locale::global(const locale& L) { |
| 410 |
#endif |
| 411 |
locale old(_Stl_get_global_locale()->_M_impl); |
| 412 |
if (_Stl_get_global_locale()->_M_impl != L._M_impl) { |
| 413 |
_release_Locale_impl(_Stl_get_global_locale()->_M_impl); |
| 414 |
// this assign should be atomic, should be fixed here: |
| 415 |
_Stl_get_global_locale()->_M_impl = _get_Locale_impl(L._M_impl); |
| 416 |
|
| 417 |
// Set the global C locale, if appropriate. |
| 418 |
#if !defined(_STLP_NO_LOCALE_SUPPORT) |
| 419 |
if (L.name() != _Nameless) |
| 420 |
setlocale(LC_ALL, L.name().c_str()); |
| 421 |
#endif |
| 422 |
} |
| 423 |
|
| 424 |
#if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) |
| 425 |
return old; |
| 426 |
#else |
| 427 |
return old._M_impl; |
| 428 |
#endif |
| 429 |
} |
| 430 |
|
| 431 |
#if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION) |
| 432 |
const locale::category locale::none; |
| 433 |
const locale::category locale::collate; |
| 434 |
const locale::category locale::ctype; |
| 435 |
const locale::category locale::monetary; |
| 436 |
const locale::category locale::numeric; |
| 437 |
const locale::category locale::time; |
| 438 |
const locale::category locale::messages; |
| 439 |
const locale::category locale::all; |
| 440 |
#endif |
| 441 |
|
| 442 |
_STLP_END_NAMESPACE |