00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
#ifndef _CPP_BITS_LOCALE_CLASSES_H
00041
#define _CPP_BITS_LOCALE_CLASSES_H 1
00042
00043
#pragma GCC system_header
00044
00045
#include <bits/localefwd.h>
00046
#include <cstring>
00047
#include <string>
00048
#include <bits/atomicity.h>
00049
00050
namespace std
00051 {
00052
class __locale_cache_base;
00053
template<
typename _Facet>
class __locale_cache;
00054
00055
00056
class locale
00057 {
00058
public:
00059
00060
typedef unsigned int category;
00061
00062
00063
class facet;
00064
class id;
00065
class _Impl;
00066
00067
friend class facet;
00068
friend class _Impl;
00069
00070
template<
typename _Facet>
00071
friend const _Facet&
00072 use_facet(
const locale&);
00073
00074
template<
typename _Facet>
00075
friend bool
00076 has_facet(
const locale&) throw();
00077
00078 template<typename _Facet>
00079 friend const __locale_cache<_Facet>&
00080 __use_cache(const locale&);
00081
00082
00083
00084 static const category none = 0;
00085 static const category ctype = 1L << 0;
00086 static const category numeric = 1L << 1;
00087 static const category collate = 1L << 2;
00088 static const category time = 1L << 3;
00089 static const category monetary = 1L << 4;
00090 static const category messages = 1L << 5;
00091 static const category all = (ctype | numeric | collate |
00092 time | monetary | messages);
00093
00094
00095 locale() throw();
00096
00097 locale(const locale& __other) throw();
00098
00099 explicit
00100 locale(const
char* __s);
00101
00102 locale(const locale& __base, const
char* __s, category __cat);
00103
00104 locale(const locale& __base, const locale& __add, category __cat);
00105
00106 template<typename _Facet>
00107 locale(const locale& __other, _Facet* __f);
00108
00109 ~locale() throw();
00110
00111 const locale&
00112 operator=(const locale& __other) throw();
00113
00114 template<typename _Facet>
00115 locale
00116 combine(const locale& __other) const;
00117
00118
00119 string
00120 name() const;
00121
00122
bool
00123 operator==(const locale& __other) const throw ();
00124
00125 inline
bool
00126 operator!=(const locale& __other) const throw ()
00127 {
return !(this->
operator==(__other)); }
00128
00129
template<
typename _Char,
typename _Traits,
typename _Alloc>
00130
bool
00131 operator()(
const basic_string<_Char, _Traits, _Alloc>& __s1,
00132
const basic_string<_Char, _Traits, _Alloc>& __s2)
const;
00133
00134
00135
static locale
00136 global(
const locale&);
00137
00138
static const locale&
00139 classic();
00140
00141
private:
00142
00143 _Impl* _M_impl;
00144
00145
00146
static _Impl* _S_classic;
00147
00148
00149
static _Impl* _S_global;
00150
00151
00152
00153
00154
00155
00156
static const size_t _S_categories_size = 6;
00157
00158
00159
00160
00161
00162
00163
static const size_t _S_extra_categories_size = _GLIBCPP_NUM_CATEGORIES;
00164
00165
00166
00167
00168
00169
static const char* _S_categories[_S_categories_size
00170 + _S_extra_categories_size];
00171
00172
explicit
00173 locale(_Impl*) throw();
00174
00175 static inline
void
00176 _S_initialize()
00177 {
00178
if (!_S_classic)
00179 classic();
00180 }
00181
00182
static category
00183 _S_normalize_category(category);
00184
00185
void
00186 _M_coalesce(
const locale& __base,
const locale& __add, category __cat);
00187 };
00188
00189
00190
00191
class locale::_Impl
00192 {
00193
public:
00194
00195
friend class locale;
00196
friend class locale::facet;
00197
00198
template<
typename _Facet>
00199
friend const _Facet&
00200 use_facet(
const locale&);
00201
00202
template<
typename _Facet>
00203
friend bool
00204 has_facet(
const locale&) throw();
00205
00206 template<typename _Facet>
00207 friend const __locale_cache<_Facet>&
00208 __use_cache(const locale&);
00209
00210 private:
00211
00212 _Atomic_word _M_references;
00213 facet** _M_facets;
00214 size_t _M_facets_size;
00215
00216
char* _M_names[_S_categories_size
00217 + _S_extra_categories_size];
00218 static const locale::
id* const _S_id_ctype[];
00219 static const locale::
id* const _S_id_numeric[];
00220 static const locale::
id* const _S_id_collate[];
00221 static const locale::
id* const _S_id_time[];
00222 static const locale::
id* const _S_id_monetary[];
00223 static const locale::
id* const _S_id_messages[];
00224 static const locale::
id* const* const _S_facet_categories[];
00225
00226 inline
void
00227 _M_add_reference() throw()
00228 { __atomic_add(&_M_references, 1); }
00229
00230
inline void
00231 _M_remove_reference() throw()
00232 {
00233
if (__exchange_and_add(&_M_references, -1) == 1)
00234 {
00235
try
00236 {
delete this; }
00237
catch(...)
00238 { }
00239 }
00240 }
00241
00242 _Impl(
const _Impl&, size_t);
00243 _Impl(
const char*, size_t);
00244 _Impl(facet**, size_t,
bool);
00245
00246 ~_Impl() throw();
00247
00248 _Impl(const _Impl&);
00249
00250
void
00251 operator=(const _Impl&);
00252
00253 inline
bool
00254 _M_check_same_name()
00255 {
00256
bool __ret =
true;
00257
for (size_t __i = 0;
00258 __ret && __i < _S_categories_size + _S_extra_categories_size - 1;
00259 ++__i)
00260 __ret &= (strcmp(_M_names[__i], _M_names[__i + 1]) == 0);
00261
return __ret;
00262 }
00263
00264
void
00265 _M_replace_categories(
const _Impl*, category);
00266
00267
void
00268 _M_replace_category(
const _Impl*,
const locale::id*
const*);
00269
00270
void
00271 _M_replace_facet(
const _Impl*,
const locale::id*);
00272
00273
void
00274 _M_install_facet(
const locale::id*, facet*);
00275
00276
template<
typename _Facet>
00277
inline void
00278 _M_init_facet(_Facet* __facet)
00279 { _M_install_facet(&_Facet::id, __facet); }
00280
00281
00282
00283
00284
inline __locale_cache_base*
00285 _M_get_cache(size_t __index)
00286 {
00287
return (__locale_cache_base*)_M_facets[__index + _M_facets_size];
00288 }
00289
00290
00291
00292
void
00293 _M_install_cache(__locale_cache_base* __cache,
int __id)
00294 {
00295 _M_facets[__id + _M_facets_size] =
00296 reinterpret_cast<locale::facet*>(__cache);
00297 }
00298
00299 };
00300
00301
template<
typename _Facet>
00302 locale::locale(
const locale& __other, _Facet* __f)
00303 {
00304 _M_impl =
new _Impl(*__other._M_impl, 1);
00305
00306
char* _M_tmp_names[_S_categories_size + _S_extra_categories_size];
00307 size_t __i = 0;
00308
try
00309 {
00310
for (; __i < _S_categories_size
00311 + _S_extra_categories_size; ++__i)
00312 {
00313 _M_tmp_names[__i] =
new char[2];
00314 strcpy(_M_tmp_names[__i],
"*");
00315 }
00316 _M_impl->_M_install_facet(&_Facet::id, __f);
00317 }
00318
catch(...)
00319 {
00320 _M_impl->_M_remove_reference();
00321
for (size_t __j = 0; __j < __i; ++__j)
00322
delete [] _M_tmp_names[__j];
00323 __throw_exception_again;
00324 }
00325
00326
for (size_t __k = 0; __k < _S_categories_size
00327 + _S_extra_categories_size; ++__k)
00328 {
00329
delete [] _M_impl->_M_names[__k];
00330 _M_impl->_M_names[__k] = _M_tmp_names[__k];
00331 }
00332 }
00333
00334
00335
00336
class locale::facet
00337 {
00338
private:
00339
friend class locale;
00340
friend class locale::_Impl;
00341
00342 _Atomic_word _M_references;
00343
00344
protected:
00345
00346
static __c_locale _S_c_locale;
00347
00348
00349
static char _S_c_name[2];
00350
00351
explicit
00352 facet(size_t __refs = 0)
throw();
00353
00354
virtual
00355 ~facet();
00356
00357
static void
00358 _S_create_c_locale(__c_locale& __cloc,
const char* __s,
00359 __c_locale __old = 0);
00360
00361
static __c_locale
00362 _S_clone_c_locale(__c_locale& __cloc);
00363
00364
static void
00365 _S_destroy_c_locale(__c_locale& __cloc);
00366
00367
private:
00368
void
00369 _M_add_reference() throw();
00370
00371
void
00372 _M_remove_reference() throw();
00373
00374 facet(const facet&);
00375
00376
void
00377 operator=(const facet&);
00378 };
00379
00380
00381
00382 class locale::
id
00383 {
00384
private:
00385
friend class locale;
00386
friend class locale::_Impl;
00387
template<
typename _Facet>
00388
friend const _Facet&
00389 use_facet(
const locale&);
00390
template<
typename _Facet>
00391
friend bool
00392 has_facet(
const locale&) throw ();
00393
00394
00395
00396
00397 mutable size_t _M_index;
00398
00399
00400 static _Atomic_word _S_highwater;
00401
00402
void
00403 operator=(const
id&);
00404
00405
id(const
id&);
00406
00407 public:
00408
00409
00410
id();
00411
00412 inline size_t
00413 _M_id()
const
00414
{
00415
if (!_M_index)
00416 _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
00417
return _M_index - 1;
00418 }
00419 };
00420 }
00421
00422
#endif