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