localefwd.h revision 110614
1// Locale support -*- C++ -*- 2 3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 2, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING. If not, write to the Free 19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20// USA. 21 22// As a special exception, you may use this file as part of a free software 23// library without restriction. Specifically, if other files instantiate 24// templates or use macros or inline functions from this file, or you compile 25// this file and link it with other files to produce an executable, this 26// file does not by itself cause the resulting executable to be covered by 27// the GNU General Public License. This exception does not however 28// invalidate any other reasons why the executable file might be covered by 29// the GNU General Public License. 30 31// 32// ISO C++ 14882: 22.1 Locales 33// 34 35/** @file localefwd.h 36 * This is an internal header file, included by other library headers. 37 * You should not attempt to use it directly. 38 */ 39 40#ifndef _CPP_BITS_LOCCORE_H 41#define _CPP_BITS_LOCCORE_H 1 42 43#pragma GCC system_header 44 45#include <bits/c++config.h> 46#include <bits/c++locale.h> // Defines __c_locale, config-specific includes 47#include <climits> // For CHAR_BIT 48#include <cctype> // For isspace, etc. 49#include <string> // For string. 50#include <bits/functexcept.h> 51#include <bits/atomicity.h> 52 53namespace std 54{ 55 // 22.1.1 Locale 56 class locale; 57 58 // 22.1.3 Convenience interfaces 59 template<typename _CharT> 60 inline bool 61 isspace(_CharT, const locale&); 62 63 template<typename _CharT> 64 inline bool 65 isprint(_CharT, const locale&); 66 67 template<typename _CharT> 68 inline bool 69 iscntrl(_CharT, const locale&); 70 71 template<typename _CharT> 72 inline bool 73 isupper(_CharT, const locale&); 74 75 template<typename _CharT> 76 inline bool 77 islower(_CharT, const locale&); 78 79 template<typename _CharT> 80 inline bool 81 isalpha(_CharT, const locale&); 82 83 template<typename _CharT> 84 inline bool 85 isdigit(_CharT, const locale&); 86 87 template<typename _CharT> 88 inline bool 89 ispunct(_CharT, const locale&); 90 91 template<typename _CharT> 92 inline bool 93 isxdigit(_CharT, const locale&); 94 95 template<typename _CharT> 96 inline bool 97 isalnum(_CharT, const locale&); 98 99 template<typename _CharT> 100 inline bool 101 isgraph(_CharT, const locale&); 102 103 template<typename _CharT> 104 inline _CharT 105 toupper(_CharT, const locale&); 106 107 template<typename _CharT> 108 inline _CharT 109 tolower(_CharT, const locale&); 110 111 112 // 22.2.1 and 22.2.1.3 ctype 113 class ctype_base; 114 template<typename _CharT> 115 class ctype; 116 template<> class ctype<char>; 117#ifdef _GLIBCPP_USE_WCHAR_T 118 template<> class ctype<wchar_t>; 119#endif 120 template<typename _CharT> 121 class ctype_byname; 122 // NB: Specialized for char and wchar_t in locale_facets.h. 123 124 class codecvt_base; 125 class __enc_traits; 126 template<typename _InternT, typename _ExternT, typename _StateT> 127 class codecvt; 128 template<> class codecvt<char, char, mbstate_t>; 129#ifdef _GLIBCPP_USE_WCHAR_T 130 template<> class codecvt<wchar_t, char, mbstate_t>; 131#endif 132 template<typename _InternT, typename _ExternT, typename _StateT> 133 class codecvt_byname; 134 135 // 22.2.2 and 22.2.3 numeric 136 template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > 137 class num_get; 138 template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > 139 class num_put; 140 template<typename _CharT> class numpunct; 141 template<typename _CharT> class numpunct_byname; 142 143 // 22.2.4 collation 144 template<typename _CharT> 145 class collate; 146 template<typename _CharT> class 147 collate_byname; 148 149 // 22.2.5 date and time 150 class time_base; 151 template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > 152 class time_get; 153 template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > 154 class time_get_byname; 155 template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > 156 class time_put; 157 template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > 158 class time_put_byname; 159 160 // 22.2.6 money 161 class money_base; 162 template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > 163 class money_get; 164 template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > 165 class money_put; 166 template<typename _CharT, bool _Intl = false> 167 class moneypunct; 168 template<typename _CharT, bool _Intl = false> 169 class moneypunct_byname; 170 171 // 22.2.7 message retrieval 172 class messages_base; 173 template<typename _CharT> 174 class messages; 175 template<typename _CharT> 176 class messages_byname; 177 178 // 22.1.1 Class locale 179 class locale 180 { 181 public: 182 // Types: 183 typedef unsigned int category; 184 185 // Forward decls and friends: 186 class facet; 187 class id; 188 class _Impl; 189 190 friend class facet; 191 friend class _Impl; 192 193 template<typename _Facet> 194 friend const _Facet& 195 use_facet(const locale&); 196 197 template<typename _Facet> 198 friend bool 199 has_facet(const locale&) throw(); 200 201 // Category values: 202 // NB: Order must match _S_facet_categories definition in locale.cc 203 static const category none = 0; 204 static const category ctype = 1L << 0; 205 static const category numeric = 1L << 1; 206 static const category collate = 1L << 2; 207 static const category time = 1L << 3; 208 static const category monetary = 1L << 4; 209 static const category messages = 1L << 5; 210 static const category all = (ctype | numeric | collate | 211 time | monetary | messages); 212 213 // Construct/copy/destroy: 214 locale() throw(); 215 216 locale(const locale& __other) throw(); 217 218 explicit 219 locale(const char* __s); 220 221 locale(const locale& __base, const char* __s, category __cat); 222 223 locale(const locale& __base, const locale& __add, category __cat); 224 225 template<typename _Facet> 226 locale(const locale& __other, _Facet* __f); 227 228 ~locale() throw(); 229 230 const locale& 231 operator=(const locale& __other) throw(); 232 233 template<typename _Facet> 234 locale 235 combine(const locale& __other) const; 236 237 // Locale operations: 238 string 239 name() const; 240 241 bool 242 operator==(const locale& __other) const throw (); 243 244 inline bool 245 operator!=(const locale& __other) const throw () 246 { return !(this->operator==(__other)); } 247 248 template<typename _Char, typename _Traits, typename _Alloc> 249 bool 250 operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, 251 const basic_string<_Char, _Traits, _Alloc>& __s2) const; 252 253 // Global locale objects: 254 static locale 255 global(const locale&); 256 257 static const locale& 258 classic(); 259 260 private: 261 // The (shared) implementation 262 _Impl* _M_impl; 263 264 // The "C" reference locale 265 static _Impl* _S_classic; 266 267 // Current global locale 268 static _Impl* _S_global; 269 270 // Number of standard categories. For C++, these categories are 271 // collate, ctype, monetary, numeric, time, and messages. These 272 // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE, 273 // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE 274 // 1003.1-2001) specifies LC_MESSAGES. 275 static const size_t _S_categories_size = 6; 276 277 // In addition to the standard categories, the underlying 278 // operating system is allowed to define extra LC_* 279 // macros. For GNU systems, the following are also valid: 280 // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, 281 // and LC_IDENTIFICATION. 282 static const size_t _S_extra_categories_size = _GLIBCPP_NUM_CATEGORIES; 283 284 // Names of underlying locale categories. 285 // NB: locale::global() has to know how to modify all the 286 // underlying categories, not just the ones required by the C++ 287 // standard. 288 static const char* _S_categories[_S_categories_size 289 + _S_extra_categories_size]; 290 291 explicit 292 locale(_Impl*) throw(); 293 294 static inline void 295 _S_initialize() 296 { 297 if (!_S_classic) 298 classic(); 299 } 300 301 static category 302 _S_normalize_category(category); 303 304 void 305 _M_coalesce(const locale& __base, const locale& __add, category __cat); 306 }; 307 308 309 // Implementation object for locale 310 class locale::_Impl 311 { 312 public: 313 // Friends. 314 friend class locale; 315 friend class locale::facet; 316 317 template<typename _Facet> 318 friend const _Facet& 319 use_facet(const locale&); 320 321 template<typename _Facet> 322 friend bool 323 has_facet(const locale&) throw(); 324 325 private: 326 // Data Members. 327 _Atomic_word _M_references; 328 facet** _M_facets; 329 size_t _M_facets_size; 330 331 char* _M_names[_S_categories_size 332 + _S_extra_categories_size]; 333 static const locale::id* const _S_id_ctype[]; 334 static const locale::id* const _S_id_numeric[]; 335 static const locale::id* const _S_id_collate[]; 336 static const locale::id* const _S_id_time[]; 337 static const locale::id* const _S_id_monetary[]; 338 static const locale::id* const _S_id_messages[]; 339 static const locale::id* const* const _S_facet_categories[]; 340 341 inline void 342 _M_add_reference() throw() 343 { __atomic_add(&_M_references, 1); } 344 345 inline void 346 _M_remove_reference() throw() 347 { 348 if (__exchange_and_add(&_M_references, -1) == 1) 349 { 350 try 351 { delete this; } 352 catch(...) 353 { } 354 } 355 } 356 357 _Impl(const _Impl&, size_t); 358 _Impl(const char*, size_t); 359 _Impl(facet**, size_t, bool); 360 361 ~_Impl() throw(); 362 363 _Impl(const _Impl&); // Not defined. 364 365 void 366 operator=(const _Impl&); // Not defined. 367 368 inline bool 369 _M_check_same_name() 370 { 371 bool __ret = true; 372 for (size_t __i = 0; 373 __ret && __i < _S_categories_size + _S_extra_categories_size - 1; 374 ++__i) 375 __ret &= (strcmp(_M_names[__i], _M_names[__i + 1]) == 0); 376 return __ret; 377 } 378 379 void 380 _M_replace_categories(const _Impl*, category); 381 382 void 383 _M_replace_category(const _Impl*, const locale::id* const*); 384 385 void 386 _M_replace_facet(const _Impl*, const locale::id*); 387 388 void 389 _M_install_facet(const locale::id*, facet*); 390 391 template<typename _Facet> 392 inline void 393 _M_init_facet(_Facet* __facet) 394 { _M_install_facet(&_Facet::id, __facet); } 395 }; 396 397 template<typename _Facet> 398 locale::locale(const locale& __other, _Facet* __f) 399 { 400 _M_impl = new _Impl(*__other._M_impl, 1); 401 _M_impl->_M_install_facet(&_Facet::id, __f); 402 for (size_t __i = 0; 403 __i < _S_categories_size + _S_extra_categories_size; ++__i) 404 { 405 delete [] _M_impl->_M_names[__i]; 406 char* __new = new char[2]; 407 strcpy(__new, "*"); 408 _M_impl->_M_names[__i] = __new; 409 } 410 } 411 412 // 22.1.1.1.2 Class locale::facet 413 class locale::facet 414 { 415 private: 416 friend class locale; 417 friend class locale::_Impl; 418 419 _Atomic_word _M_references; 420 421 protected: 422 // Contains data from the underlying "C" library for for the 423 // classic locale. 424 static __c_locale _S_c_locale; 425 426 // String literal for the name of the classic locale. 427 static char _S_c_name[2]; 428 429 explicit 430 facet(size_t __refs = 0) throw(); 431 432 virtual 433 ~facet(); 434 435 static void 436 _S_create_c_locale(__c_locale& __cloc, const char* __s, 437 __c_locale __old = 0); 438 439 static __c_locale 440 _S_clone_c_locale(__c_locale& __cloc); 441 442 static void 443 _S_destroy_c_locale(__c_locale& __cloc); 444 445 private: 446 void 447 _M_add_reference() throw(); 448 449 void 450 _M_remove_reference() throw(); 451 452 facet(const facet&); // Not defined. 453 454 void 455 operator=(const facet&); // Not defined. 456 }; 457 458 459 // 22.1.1.1.3 Class locale::id 460 class locale::id 461 { 462 private: 463 friend class locale; 464 friend class locale::_Impl; 465 template<typename _Facet> 466 friend const _Facet& 467 use_facet(const locale&); 468 template<typename _Facet> 469 friend bool 470 has_facet(const locale&) throw (); 471 472 // NB: There is no accessor for _M_index because it may be used 473 // before the constructor is run; the effect of calling a member 474 // function (even an inline) would be undefined. 475 mutable size_t _M_index; 476 477 // Last id number assigned. 478 static _Atomic_word _S_highwater; 479 480 void 481 operator=(const id&); // Not defined. 482 483 id(const id&); // Not defined. 484 485 public: 486 // NB: This class is always a static data member, and thus can be 487 // counted on to be zero-initialized. 488 id(); 489 490 inline size_t 491 _M_id() const 492 { 493 if (!_M_index) 494 _M_index = 1 + __exchange_and_add(&_S_highwater, 1); 495 return _M_index - 1; 496 } 497 }; 498 499 template<typename _Facet> 500 const _Facet& 501 use_facet(const locale& __loc); 502 503 template<typename _Facet> 504 bool 505 has_facet(const locale& __loc) throw(); 506} // namespace std 507 508#endif 509