localefwd.h revision 97403
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 = (collate | ctype | monetary | 211 numeric | time | 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 reference locale 268 static _Impl* _S_global; 269 270 static const size_t _S_num_categories = 6; 271 272 explicit 273 locale(_Impl*) throw(); 274 275 static inline void 276 _S_initialize() 277 { 278 if (!_S_classic) 279 classic(); 280 } 281 282 static category 283 _S_normalize_category(category); 284 285 void 286 _M_coalesce(const locale& __base, const locale& __add, category __cat); 287 }; 288 289 290 // Implementation object for locale 291 class locale::_Impl 292 { 293 public: 294 // Friends. 295 friend class locale; 296 friend class locale::facet; 297 298 template<typename _Facet> 299 friend const _Facet& 300 use_facet(const locale&); 301 302 template<typename _Facet> 303 friend bool 304 has_facet(const locale&) throw(); 305 306 private: 307 // Data Members. 308 _Atomic_word _M_references; 309 facet** _M_facets; 310 size_t _M_facets_size; 311 const char* _M_names[_S_num_categories]; 312 static const locale::id* const _S_id_ctype[]; 313 static const locale::id* const _S_id_numeric[]; 314 static const locale::id* const _S_id_collate[]; 315 static const locale::id* const _S_id_time[]; 316 static const locale::id* const _S_id_monetary[]; 317 static const locale::id* const _S_id_messages[]; 318 static const locale::id* const* const _S_facet_categories[]; 319 320 inline void 321 _M_add_reference() throw() 322 { __atomic_add(&_M_references, 1); } 323 324 inline void 325 _M_remove_reference() throw() 326 { 327 if (__exchange_and_add(&_M_references, -1) == 1) 328 { 329 try 330 { delete this; } 331 catch(...) 332 { } 333 } 334 } 335 336 _Impl(const _Impl&, size_t); 337 _Impl(const char*, size_t); 338 _Impl(facet**, size_t, bool); 339 340 ~_Impl() throw(); 341 342 _Impl(const _Impl&); // Not defined. 343 344 void 345 operator=(const _Impl&); // Not defined. 346 347 inline bool 348 _M_check_same_name() 349 { 350 bool __ret = true; 351 for (size_t i = 0; __ret && i < _S_num_categories - 1; ++i) 352 __ret &= (strcmp(_M_names[i], _M_names[i + 1]) == 0); 353 return __ret; 354 } 355 356 void 357 _M_replace_categories(const _Impl*, category); 358 359 void 360 _M_replace_category(const _Impl*, const locale::id* const*); 361 362 void 363 _M_replace_facet(const _Impl*, const locale::id*); 364 365 void 366 _M_install_facet(const locale::id*, facet*); 367 368 template<typename _Facet> 369 inline void 370 _M_init_facet(_Facet* __facet) 371 { _M_install_facet(&_Facet::id, __facet); } 372 }; 373 374 template<typename _Facet> 375 locale::locale(const locale& __other, _Facet* __f) 376 { 377 _M_impl = new _Impl(*__other._M_impl, 1); 378 _M_impl->_M_install_facet(&_Facet::id, __f); 379 for (size_t __i = 0; __i < _S_num_categories; ++__i) 380 _M_impl->_M_names[__i] = "*"; 381 } 382 383 // 22.1.1.1.2 Class locale::facet 384 class locale::facet 385 { 386 private: 387 friend class locale; 388 friend class locale::_Impl; 389 390 _Atomic_word _M_references; 391 392 protected: 393 // Contains data from the underlying "C" library for default "C" 394 // or "POSIX" locale. 395 static __c_locale _S_c_locale; 396 397 explicit 398 facet(size_t __refs = 0) throw(); 399 400 virtual 401 ~facet(); 402 403 static void 404 _S_create_c_locale(__c_locale& __cloc, const char* __s, 405 __c_locale __old = 0); 406 407 static __c_locale 408 _S_clone_c_locale(__c_locale& __cloc); 409 410 static void 411 _S_destroy_c_locale(__c_locale& __cloc); 412 413 private: 414 void 415 _M_add_reference() throw(); 416 417 void 418 _M_remove_reference() throw(); 419 420 facet(const facet&); // Not defined. 421 422 void 423 operator=(const facet&); // Not defined. 424 }; 425 426 427 // 22.1.1.1.3 Class locale::id 428 class locale::id 429 { 430 private: 431 friend class locale; 432 friend class locale::_Impl; 433 template<typename _Facet> 434 friend const _Facet& 435 use_facet(const locale&); 436 template<typename _Facet> 437 friend bool 438 has_facet(const locale&) throw (); 439 440 // NB: There is no accessor for _M_index because it may be used 441 // before the constructor is run; the effect of calling a member 442 // function (even an inline) would be undefined. 443 mutable size_t _M_index; 444 445 // Last id number assigned. 446 static _Atomic_word _S_highwater; 447 448 void 449 operator=(const id&); // Not defined. 450 451 id(const id&); // Not defined. 452 453 public: 454 // NB: This class is always a static data member, and thus can be 455 // counted on to be zero-initialized. 456 id(); 457 458 inline size_t 459 _M_id() const 460 { 461 if (!_M_index) 462 _M_index = 1 + __exchange_and_add(&_S_highwater, 1); 463 return _M_index - 1; 464 } 465 }; 466 467 template<typename _Facet> 468 const _Facet& 469 use_facet(const locale& __loc); 470 471 template<typename _Facet> 472 bool 473 has_facet(const locale& __loc) throw(); 474} // namespace std 475 476#endif 477