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
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
00053 class locale
00054 {
00055 public:
00056
00057 typedef unsigned int category;
00058
00059
00060 class facet;
00061 class id;
00062 class _Impl;
00063
00064 friend class facet;
00065 friend class _Impl;
00066
00067 template<typename _Facet>
00068 friend const _Facet&
00069 use_facet(const locale&);
00070
00071 template<typename _Facet>
00072 friend bool
00073 has_facet(const locale&) throw();
00074
00075
00076
00077 static const category none = 0;
00078 static const category ctype = 1L << 0;
00079 static const category numeric = 1L << 1;
00080 static const category collate = 1L << 2;
00081 static const category time = 1L << 3;
00082 static const category monetary = 1L << 4;
00083 static const category messages = 1L << 5;
00084 static const category all = (ctype | numeric | collate |
00085 time | monetary | messages);
00086
00087
00088 locale() throw();
00089
00090 locale(const locale& __other) throw();
00091
00092 explicit
00093 locale(const char* __s);
00094
00095 locale(const locale& __base, const char* __s, category __cat);
00096
00097 locale(const locale& __base, const locale& __add, category __cat);
00098
00099 template<typename _Facet>
00100 locale(const locale& __other, _Facet* __f);
00101
00102 ~locale() throw();
00103
00104 const locale&
00105 operator=(const locale& __other) throw();
00106
00107 template<typename _Facet>
00108 locale
00109 combine(const locale& __other) const;
00110
00111
00112 string
00113 name() const;
00114
00115 bool
00116 operator==(const locale& __other) const throw ();
00117
00118 inline bool
00119 operator!=(const locale& __other) const throw ()
00120 { return !(this->operator==(__other)); }
00121
00122 template<typename _Char, typename _Traits, typename _Alloc>
00123 bool
00124 operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
00125 const basic_string<_Char, _Traits, _Alloc>& __s2) const;
00126
00127
00128 static locale
00129 global(const locale&);
00130
00131 static const locale&
00132 classic();
00133
00134 private:
00135
00136 _Impl* _M_impl;
00137
00138
00139 static _Impl* _S_classic;
00140
00141
00142 static _Impl* _S_global;
00143
00144
00145
00146
00147
00148
00149 static const size_t _S_categories_size = 6;
00150
00151
00152
00153
00154
00155
00156 static const size_t _S_extra_categories_size = _GLIBCPP_NUM_CATEGORIES;
00157
00158
00159
00160
00161
00162 static const char* _S_categories[_S_categories_size
00163 + _S_extra_categories_size];
00164
00165 explicit
00166 locale(_Impl*) throw();
00167
00168 static inline void
00169 _S_initialize()
00170 {
00171 if (!_S_classic)
00172 classic();
00173 }
00174
00175 static category
00176 _S_normalize_category(category);
00177
00178 void
00179 _M_coalesce(const locale& __base, const locale& __add, category __cat);
00180 };
00181
00182
00183
00184 class locale::_Impl
00185 {
00186 public:
00187
00188 friend class locale;
00189 friend class locale::facet;
00190
00191 template<typename _Facet>
00192 friend const _Facet&
00193 use_facet(const locale&);
00194
00195 template<typename _Facet>
00196 friend bool
00197 has_facet(const locale&) throw();
00198
00199 private:
00200
00201 _Atomic_word _M_references;
00202 facet** _M_facets;
00203 size_t _M_facets_size;
00204
00205 char* _M_names[_S_categories_size
00206 + _S_extra_categories_size];
00207 static const locale::id* const _S_id_ctype[];
00208 static const locale::id* const _S_id_numeric[];
00209 static const locale::id* const _S_id_collate[];
00210 static const locale::id* const _S_id_time[];
00211 static const locale::id* const _S_id_monetary[];
00212 static const locale::id* const _S_id_messages[];
00213 static const locale::id* const* const _S_facet_categories[];
00214
00215 inline void
00216 _M_add_reference() throw()
00217 { __atomic_add(&_M_references, 1); }
00218
00219 inline void
00220 _M_remove_reference() throw()
00221 {
00222 if (__exchange_and_add(&_M_references, -1) == 1)
00223 {
00224 try
00225 { delete this; }
00226 catch(...)
00227 { }
00228 }
00229 }
00230
00231 _Impl(const _Impl&, size_t);
00232 _Impl(const char*, size_t);
00233 _Impl(facet**, size_t, bool);
00234
00235 ~_Impl() throw();
00236
00237 _Impl(const _Impl&);
00238
00239 void
00240 operator=(const _Impl&);
00241
00242 inline bool
00243 _M_check_same_name()
00244 {
00245 bool __ret = true;
00246 for (size_t __i = 0;
00247 __ret && __i < _S_categories_size + _S_extra_categories_size - 1;
00248 ++__i)
00249 __ret &= (strcmp(_M_names[__i], _M_names[__i + 1]) == 0);
00250 return __ret;
00251 }
00252
00253 void
00254 _M_replace_categories(const _Impl*, category);
00255
00256 void
00257 _M_replace_category(const _Impl*, const locale::id* const*);
00258
00259 void
00260 _M_replace_facet(const _Impl*, const locale::id*);
00261
00262 void
00263 _M_install_facet(const locale::id*, facet*);
00264
00265 template<typename _Facet>
00266 inline void
00267 _M_init_facet(_Facet* __facet)
00268 { _M_install_facet(&_Facet::id, __facet); }
00269 };
00270
00271 template<typename _Facet>
00272 locale::locale(const locale& __other, _Facet* __f)
00273 {
00274 _M_impl = new _Impl(*__other._M_impl, 1);
00275 _M_impl->_M_install_facet(&_Facet::id, __f);
00276 for (size_t __i = 0;
00277 __i < _S_categories_size + _S_extra_categories_size; ++__i)
00278 {
00279 delete [] _M_impl->_M_names[__i];
00280 char* __new = new char[2];
00281 strcpy(__new, "*");
00282 _M_impl->_M_names[__i] = __new;
00283 }
00284 }
00285
00286
00287
00288 class locale::facet
00289 {
00290 private:
00291 friend class locale;
00292 friend class locale::_Impl;
00293
00294 _Atomic_word _M_references;
00295
00296 protected:
00297
00298 static __c_locale _S_c_locale;
00299
00300
00301 static char _S_c_name[2];
00302
00303 explicit
00304 facet(size_t __refs = 0) throw();
00305
00306 virtual
00307 ~facet();
00308
00309 static void
00310 _S_create_c_locale(__c_locale& __cloc, const char* __s,
00311 __c_locale __old = 0);
00312
00313 static __c_locale
00314 _S_clone_c_locale(__c_locale& __cloc);
00315
00316 static void
00317 _S_destroy_c_locale(__c_locale& __cloc);
00318
00319 private:
00320 void
00321 _M_add_reference() throw();
00322
00323 void
00324 _M_remove_reference() throw();
00325
00326 facet(const facet&);
00327
00328 void
00329 operator=(const facet&);
00330 };
00331
00332
00333
00334 class locale::id
00335 {
00336 private:
00337 friend class locale;
00338 friend class locale::_Impl;
00339 template<typename _Facet>
00340 friend const _Facet&
00341 use_facet(const locale&);
00342 template<typename _Facet>
00343 friend bool
00344 has_facet(const locale&) throw ();
00345
00346
00347
00348
00349 mutable size_t _M_index;
00350
00351
00352 static _Atomic_word _S_highwater;
00353
00354 void
00355 operator=(const id&);
00356
00357 id(const id&);
00358
00359 public:
00360
00361
00362 id();
00363
00364 inline size_t
00365 _M_id() const
00366 {
00367 if (!_M_index)
00368 _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
00369 return _M_index - 1;
00370 }
00371 };
00372 }
00373
00374 #endif