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 _M_impl->_M_install_facet(&_Facet::id, __f);
00306 for (size_t __i = 0;
00307 __i < _S_categories_size + _S_extra_categories_size; ++__i)
00308 {
00309 delete [] _M_impl->_M_names[__i];
00310 char* __new = new char[2];
00311 strcpy(__new, "*");
00312 _M_impl->_M_names[__i] = __new;
00313 }
00314 }
00315
00316
00317
00318 class locale::facet
00319 {
00320 private:
00321 friend class locale;
00322 friend class locale::_Impl;
00323
00324 _Atomic_word _M_references;
00325
00326 protected:
00327
00328 static __c_locale _S_c_locale;
00329
00330
00331 static char _S_c_name[2];
00332
00333 explicit
00334 facet(size_t __refs = 0) throw();
00335
00336 virtual
00337 ~facet();
00338
00339 static void
00340 _S_create_c_locale(__c_locale& __cloc, const char* __s,
00341 __c_locale __old = 0);
00342
00343 static __c_locale
00344 _S_clone_c_locale(__c_locale& __cloc);
00345
00346 static void
00347 _S_destroy_c_locale(__c_locale& __cloc);
00348
00349 private:
00350 void
00351 _M_add_reference() throw();
00352
00353 void
00354 _M_remove_reference() throw();
00355
00356 facet(const facet&);
00357
00358 void
00359 operator=(const facet&);
00360 };
00361
00362
00363
00364 class locale::id
00365 {
00366 private:
00367 friend class locale;
00368 friend class locale::_Impl;
00369 template<typename _Facet>
00370 friend const _Facet&
00371 use_facet(const locale&);
00372 template<typename _Facet>
00373 friend bool
00374 has_facet(const locale&) throw ();
00375
00376
00377
00378
00379 mutable size_t _M_index;
00380
00381
00382 static _Atomic_word _S_highwater;
00383
00384 void
00385 operator=(const id&);
00386
00387 id(const id&);
00388
00389 public:
00390
00391
00392 id();
00393
00394 inline size_t
00395 _M_id() const
00396 {
00397 if (!_M_index)
00398 _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
00399 return _M_index - 1;
00400 }
00401 };
00402 }
00403
00404 #endif