locale_classes.h

00001 // Locale support -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 // 00032 // ISO C++ 14882: 22.1 Locales 00033 // 00034 00035 /** @file localefwd.h 00036 * This is an internal header file, included by other library headers. 00037 * You should not attempt to use it directly. 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> // For strcmp. 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 // 22.1.1 Class locale 00056 class locale 00057 { 00058 public: 00059 // Types: 00060 typedef unsigned int category; 00061 00062 // Forward decls and friends: 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 // Category values: 00083 // NB: Order must match _S_facet_categories definition in locale.cc 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 // Construct/copy/destroy: 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 // Locale operations: 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 // Global locale objects: 00135 static locale 00136 global(const locale&); 00137 00138 static const locale& 00139 classic(); 00140 00141 private: 00142 // The (shared) implementation 00143 _Impl* _M_impl; 00144 00145 // The "C" reference locale 00146 static _Impl* _S_classic; 00147 00148 // Current global locale 00149 static _Impl* _S_global; 00150 00151 // Number of standard categories. For C++, these categories are 00152 // collate, ctype, monetary, numeric, time, and messages. These 00153 // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE, 00154 // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE 00155 // 1003.1-2001) specifies LC_MESSAGES. 00156 static const size_t _S_categories_size = 6; 00157 00158 // In addition to the standard categories, the underlying 00159 // operating system is allowed to define extra LC_* 00160 // macros. For GNU systems, the following are also valid: 00161 // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, 00162 // and LC_IDENTIFICATION. 00163 static const size_t _S_extra_categories_size = _GLIBCPP_NUM_CATEGORIES; 00164 00165 // Names of underlying locale categories. 00166 // NB: locale::global() has to know how to modify all the 00167 // underlying categories, not just the ones required by the C++ 00168 // standard. 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 // Implementation object for locale 00191 class locale::_Impl 00192 { 00193 public: 00194 // Friends. 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 // Data Members. 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&); // Not defined. 00249 00250 void 00251 operator=(const _Impl&); // Not defined. 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 // Retrieve the cache at __index. 0 is returned if the cache is 00282 // missing. Cache is actually located at __index + 00283 // _M_facets_size. __index must be < _M_facets_size. 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 // Save the supplied cache at __id. Assumes _M_get_cache has been 00291 // called. 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 // 22.1.1.1.2 Class locale::facet 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 // Contains data from the underlying "C" library for the classic locale. 00346 static __c_locale _S_c_locale; 00347 00348 // String literal for the name of the classic locale. 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&); // Not defined. 00375 00376 void 00377 operator=(const facet&); // Not defined. 00378 }; 00379 00380 00381 // 22.1.1.1.3 Class locale::id 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 // NB: There is no accessor for _M_index because it may be used 00395 // before the constructor is run; the effect of calling a member 00396 // function (even an inline) would be undefined. 00397 mutable size_t _M_index; 00398 00399 // Last id number assigned. 00400 static _Atomic_word _S_highwater; 00401 00402 void 00403 operator=(const id&); // Not defined. 00404 00405 id(const id&); // Not defined. 00406 00407 public: 00408 // NB: This class is always a static data member, and thus can be 00409 // counted on to be zero-initialized. 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 } // namespace std 00421 00422 #endif

Generated on Sun Sep 19 16:33:51 2004 for libstdc++-v3 Source by doxygen 1.3.8