00001 // Locale support -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 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 locale_facets.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 _LOCALE_FACETS_H 00041 #define _LOCALE_FACETS_H 1 00042 00043 #pragma GCC system_header 00044 00045 #include <ctime> // For struct tm 00046 #include <cwctype> // For wctype_t 00047 #include <iosfwd> 00048 #include <bits/ios_base.h> // For ios_base, ios_base::iostate 00049 #include <streambuf> 00050 00051 namespace std 00052 { 00053 // NB: Don't instantiate required wchar_t facets if no wchar_t support. 00054 #ifdef _GLIBCXX_USE_WCHAR_T 00055 # define _GLIBCXX_NUM_FACETS 28 00056 #else 00057 # define _GLIBCXX_NUM_FACETS 14 00058 #endif 00059 00060 // Convert string to numeric value of type _Tv and store results. 00061 // NB: This is specialized for all required types, there is no 00062 // generic definition. 00063 template<typename _Tv> 00064 void 00065 __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, 00066 const __c_locale& __cloc); 00067 00068 // Explicit specializations for required types. 00069 template<> 00070 void 00071 __convert_to_v(const char*, float&, ios_base::iostate&, 00072 const __c_locale&); 00073 00074 template<> 00075 void 00076 __convert_to_v(const char*, double&, ios_base::iostate&, 00077 const __c_locale&); 00078 00079 template<> 00080 void 00081 __convert_to_v(const char*, long double&, ios_base::iostate&, 00082 const __c_locale&); 00083 00084 // NB: __pad is a struct, rather than a function, so it can be 00085 // partially-specialized. 00086 template<typename _CharT, typename _Traits> 00087 struct __pad 00088 { 00089 static void 00090 _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, 00091 const _CharT* __olds, const streamsize __newlen, 00092 const streamsize __oldlen, const bool __num); 00093 }; 00094 00095 // Used by both numeric and monetary facets. 00096 // Inserts "group separator" characters into an array of characters. 00097 // It's recursive, one iteration per group. It moves the characters 00098 // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this 00099 // only with __glen != 0. 00100 template<typename _CharT> 00101 _CharT* 00102 __add_grouping(_CharT* __s, _CharT __sep, 00103 const char* __gbeg, size_t __gsize, 00104 const _CharT* __first, const _CharT* __last); 00105 00106 // This template permits specializing facet output code for 00107 // ostreambuf_iterator. For ostreambuf_iterator, sputn is 00108 // significantly more efficient than incrementing iterators. 00109 template<typename _CharT> 00110 inline 00111 ostreambuf_iterator<_CharT> 00112 __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) 00113 { 00114 __s._M_put(__ws, __len); 00115 return __s; 00116 } 00117 00118 // This is the unspecialized form of the template. 00119 template<typename _CharT, typename _OutIter> 00120 inline 00121 _OutIter 00122 __write(_OutIter __s, const _CharT* __ws, int __len) 00123 { 00124 for (int __j = 0; __j < __len; __j++, ++__s) 00125 *__s = __ws[__j]; 00126 return __s; 00127 } 00128 00129 00130 // 22.2.1.1 Template class ctype 00131 // Include host and configuration specific ctype enums for ctype_base. 00132 #include <bits/ctype_base.h> 00133 00134 // Common base for ctype<_CharT>. 00135 /** 00136 * @brief Common base for ctype facet 00137 * 00138 * This template class provides implementations of the public functions 00139 * that forward to the protected virtual functions. 00140 * 00141 * This template also provides abtract stubs for the protected virtual 00142 * functions. 00143 */ 00144 template<typename _CharT> 00145 class __ctype_abstract_base : public locale::facet, public ctype_base 00146 { 00147 public: 00148 // Types: 00149 /// Typedef for the template parameter 00150 typedef _CharT char_type; 00151 00152 /** 00153 * @brief Test char_type classification. 00154 * 00155 * This function finds a mask M for @a c and compares it to mask @a m. 00156 * It does so by returning the value of ctype<char_type>::do_is(). 00157 * 00158 * @param c The char_type to compare the mask of. 00159 * @param m The mask to compare against. 00160 * @return (M & m) != 0. 00161 */ 00162 bool 00163 is(mask __m, char_type __c) const 00164 { return this->do_is(__m, __c); } 00165 00166 /** 00167 * @brief Return a mask array. 00168 * 00169 * This function finds the mask for each char_type in the range [lo,hi) 00170 * and successively writes it to vec. vec must have as many elements 00171 * as the char array. It does so by returning the value of 00172 * ctype<char_type>::do_is(). 00173 * 00174 * @param lo Pointer to start of range. 00175 * @param hi Pointer to end of range. 00176 * @param vec Pointer to an array of mask storage. 00177 * @return @a hi. 00178 */ 00179 const char_type* 00180 is(const char_type *__lo, const char_type *__hi, mask *__vec) const 00181 { return this->do_is(__lo, __hi, __vec); } 00182 00183 /** 00184 * @brief Find char_type matching a mask 00185 * 00186 * This function searches for and returns the first char_type c in 00187 * [lo,hi) for which is(m,c) is true. It does so by returning 00188 * ctype<char_type>::do_scan_is(). 00189 * 00190 * @param m The mask to compare against. 00191 * @param lo Pointer to start of range. 00192 * @param hi Pointer to end of range. 00193 * @return Pointer to matching char_type if found, else @a hi. 00194 */ 00195 const char_type* 00196 scan_is(mask __m, const char_type* __lo, const char_type* __hi) const 00197 { return this->do_scan_is(__m, __lo, __hi); } 00198 00199 /** 00200 * @brief Find char_type not matching a mask 00201 * 00202 * This function searches for and returns the first char_type c in 00203 * [lo,hi) for which is(m,c) is false. It does so by returning 00204 * ctype<char_type>::do_scan_not(). 00205 * 00206 * @param m The mask to compare against. 00207 * @param lo Pointer to first char in range. 00208 * @param hi Pointer to end of range. 00209 * @return Pointer to non-matching char if found, else @a hi. 00210 */ 00211 const char_type* 00212 scan_not(mask __m, const char_type* __lo, const char_type* __hi) const 00213 { return this->do_scan_not(__m, __lo, __hi); } 00214 00215 /** 00216 * @brief Convert to uppercase. 00217 * 00218 * This function converts the argument to uppercase if possible. 00219 * If not possible (for example, '2'), returns the argument. It does 00220 * so by returning ctype<char_type>::do_toupper(). 00221 * 00222 * @param c The char_type to convert. 00223 * @return The uppercase char_type if convertible, else @a c. 00224 */ 00225 char_type 00226 toupper(char_type __c) const 00227 { return this->do_toupper(__c); } 00228 00229 /** 00230 * @brief Convert array to uppercase. 00231 * 00232 * This function converts each char_type in the range [lo,hi) to 00233 * uppercase if possible. Other elements remain untouched. It does so 00234 * by returning ctype<char_type>:: do_toupper(lo, hi). 00235 * 00236 * @param lo Pointer to start of range. 00237 * @param hi Pointer to end of range. 00238 * @return @a hi. 00239 */ 00240 const char_type* 00241 toupper(char_type *__lo, const char_type* __hi) const 00242 { return this->do_toupper(__lo, __hi); } 00243 00244 /** 00245 * @brief Convert to lowercase. 00246 * 00247 * This function converts the argument to lowercase if possible. If 00248 * not possible (for example, '2'), returns the argument. It does so 00249 * by returning ctype<char_type>::do_tolower(c). 00250 * 00251 * @param c The char_type to convert. 00252 * @return The lowercase char_type if convertible, else @a c. 00253 */ 00254 char_type 00255 tolower(char_type __c) const 00256 { return this->do_tolower(__c); } 00257 00258 /** 00259 * @brief Convert array to lowercase. 00260 * 00261 * This function converts each char_type in the range [lo,hi) to 00262 * lowercase if possible. Other elements remain untouched. It does so 00263 * by returning ctype<char_type>:: do_tolower(lo, hi). 00264 * 00265 * @param lo Pointer to start of range. 00266 * @param hi Pointer to end of range. 00267 * @return @a hi. 00268 */ 00269 const char_type* 00270 tolower(char_type* __lo, const char_type* __hi) const 00271 { return this->do_tolower(__lo, __hi); } 00272 00273 /** 00274 * @brief Widen char to char_type 00275 * 00276 * This function converts the char argument to char_type using the 00277 * simplest reasonable transformation. It does so by returning 00278 * ctype<char_type>::do_widen(c). 00279 * 00280 * Note: this is not what you want for codepage conversions. See 00281 * codecvt for that. 00282 * 00283 * @param c The char to convert. 00284 * @return The converted char_type. 00285 */ 00286 char_type 00287 widen(char __c) const 00288 { return this->do_widen(__c); } 00289 00290 /** 00291 * @brief Widen array to char_type 00292 * 00293 * This function converts each char in the input to char_type using the 00294 * simplest reasonable transformation. It does so by returning 00295 * ctype<char_type>::do_widen(c). 00296 * 00297 * Note: this is not what you want for codepage conversions. See 00298 * codecvt for that. 00299 * 00300 * @param lo Pointer to start of range. 00301 * @param hi Pointer to end of range. 00302 * @param to Pointer to the destination array. 00303 * @return @a hi. 00304 */ 00305 const char* 00306 widen(const char* __lo, const char* __hi, char_type* __to) const 00307 { return this->do_widen(__lo, __hi, __to); } 00308 00309 /** 00310 * @brief Narrow char_type to char 00311 * 00312 * This function converts the char_type to char using the simplest 00313 * reasonable transformation. If the conversion fails, dfault is 00314 * returned instead. It does so by returning 00315 * ctype<char_type>::do_narrow(c). 00316 * 00317 * Note: this is not what you want for codepage conversions. See 00318 * codecvt for that. 00319 * 00320 * @param c The char_type to convert. 00321 * @param dfault Char to return if conversion fails. 00322 * @return The converted char. 00323 */ 00324 char 00325 narrow(char_type __c, char __dfault) const 00326 { return this->do_narrow(__c, __dfault); } 00327 00328 /** 00329 * @brief Narrow array to char array 00330 * 00331 * This function converts each char_type in the input to char using the 00332 * simplest reasonable transformation and writes the results to the 00333 * destination array. For any char_type in the input that cannot be 00334 * converted, @a dfault is used instead. It does so by returning 00335 * ctype<char_type>::do_narrow(lo, hi, dfault, to). 00336 * 00337 * Note: this is not what you want for codepage conversions. See 00338 * codecvt for that. 00339 * 00340 * @param lo Pointer to start of range. 00341 * @param hi Pointer to end of range. 00342 * @param dfault Char to use if conversion fails. 00343 * @param to Pointer to the destination array. 00344 * @return @a hi. 00345 */ 00346 const char_type* 00347 narrow(const char_type* __lo, const char_type* __hi, 00348 char __dfault, char *__to) const 00349 { return this->do_narrow(__lo, __hi, __dfault, __to); } 00350 00351 protected: 00352 explicit 00353 __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } 00354 00355 virtual 00356 ~__ctype_abstract_base() { } 00357 00358 /** 00359 * @brief Test char_type classification. 00360 * 00361 * This function finds a mask M for @a c and compares it to mask @a m. 00362 * 00363 * do_is() is a hook for a derived facet to change the behavior of 00364 * classifying. do_is() must always return the same result for the 00365 * same input. 00366 * 00367 * @param c The char_type to find the mask of. 00368 * @param m The mask to compare against. 00369 * @return (M & m) != 0. 00370 */ 00371 virtual bool 00372 do_is(mask __m, char_type __c) const = 0; 00373 00374 /** 00375 * @brief Return a mask array. 00376 * 00377 * This function finds the mask for each char_type in the range [lo,hi) 00378 * and successively writes it to vec. vec must have as many elements 00379 * as the input. 00380 * 00381 * do_is() is a hook for a derived facet to change the behavior of 00382 * classifying. do_is() must always return the same result for the 00383 * same input. 00384 * 00385 * @param lo Pointer to start of range. 00386 * @param hi Pointer to end of range. 00387 * @param vec Pointer to an array of mask storage. 00388 * @return @a hi. 00389 */ 00390 virtual const char_type* 00391 do_is(const char_type* __lo, const char_type* __hi, 00392 mask* __vec) const = 0; 00393 00394 /** 00395 * @brief Find char_type matching mask 00396 * 00397 * This function searches for and returns the first char_type c in 00398 * [lo,hi) for which is(m,c) is true. 00399 * 00400 * do_scan_is() is a hook for a derived facet to change the behavior of 00401 * match searching. do_is() must always return the same result for the 00402 * same input. 00403 * 00404 * @param m The mask to compare against. 00405 * @param lo Pointer to start of range. 00406 * @param hi Pointer to end of range. 00407 * @return Pointer to a matching char_type if found, else @a hi. 00408 */ 00409 virtual const char_type* 00410 do_scan_is(mask __m, const char_type* __lo, 00411 const char_type* __hi) const = 0; 00412 00413 /** 00414 * @brief Find char_type not matching mask 00415 * 00416 * This function searches for and returns a pointer to the first 00417 * char_type c of [lo,hi) for which is(m,c) is false. 00418 * 00419 * do_scan_is() is a hook for a derived facet to change the behavior of 00420 * match searching. do_is() must always return the same result for the 00421 * same input. 00422 * 00423 * @param m The mask to compare against. 00424 * @param lo Pointer to start of range. 00425 * @param hi Pointer to end of range. 00426 * @return Pointer to a non-matching char_type if found, else @a hi. 00427 */ 00428 virtual const char_type* 00429 do_scan_not(mask __m, const char_type* __lo, 00430 const char_type* __hi) const = 0; 00431 00432 /** 00433 * @brief Convert to uppercase. 00434 * 00435 * This virtual function converts the char_type argument to uppercase 00436 * if possible. If not possible (for example, '2'), returns the 00437 * argument. 00438 * 00439 * do_toupper() is a hook for a derived facet to change the behavior of 00440 * uppercasing. do_toupper() must always return the same result for 00441 * the same input. 00442 * 00443 * @param c The char_type to convert. 00444 * @return The uppercase char_type if convertible, else @a c. 00445 */ 00446 virtual char_type 00447 do_toupper(char_type) const = 0; 00448 00449 /** 00450 * @brief Convert array to uppercase. 00451 * 00452 * This virtual function converts each char_type in the range [lo,hi) 00453 * to uppercase if possible. Other elements remain untouched. 00454 * 00455 * do_toupper() is a hook for a derived facet to change the behavior of 00456 * uppercasing. do_toupper() must always return the same result for 00457 * the same input. 00458 * 00459 * @param lo Pointer to start of range. 00460 * @param hi Pointer to end of range. 00461 * @return @a hi. 00462 */ 00463 virtual const char_type* 00464 do_toupper(char_type* __lo, const char_type* __hi) const = 0; 00465 00466 /** 00467 * @brief Convert to lowercase. 00468 * 00469 * This virtual function converts the argument to lowercase if 00470 * possible. If not possible (for example, '2'), returns the argument. 00471 * 00472 * do_tolower() is a hook for a derived facet to change the behavior of 00473 * lowercasing. do_tolower() must always return the same result for 00474 * the same input. 00475 * 00476 * @param c The char_type to convert. 00477 * @return The lowercase char_type if convertible, else @a c. 00478 */ 00479 virtual char_type 00480 do_tolower(char_type) const = 0; 00481 00482 /** 00483 * @brief Convert array to lowercase. 00484 * 00485 * This virtual function converts each char_type in the range [lo,hi) 00486 * to lowercase if possible. Other elements remain untouched. 00487 * 00488 * do_tolower() is a hook for a derived facet to change the behavior of 00489 * lowercasing. do_tolower() must always return the same result for 00490 * the same input. 00491 * 00492 * @param lo Pointer to start of range. 00493 * @param hi Pointer to end of range. 00494 * @return @a hi. 00495 */ 00496 virtual const char_type* 00497 do_tolower(char_type* __lo, const char_type* __hi) const = 0; 00498 00499 /** 00500 * @brief Widen char 00501 * 00502 * This virtual function converts the char to char_type using the 00503 * simplest reasonable transformation. 00504 * 00505 * do_widen() is a hook for a derived facet to change the behavior of 00506 * widening. do_widen() must always return the same result for the 00507 * same input. 00508 * 00509 * Note: this is not what you want for codepage conversions. See 00510 * codecvt for that. 00511 * 00512 * @param c The char to convert. 00513 * @return The converted char_type 00514 */ 00515 virtual char_type 00516 do_widen(char) const = 0; 00517 00518 /** 00519 * @brief Widen char array 00520 * 00521 * This function converts each char in the input to char_type using the 00522 * simplest reasonable transformation. 00523 * 00524 * do_widen() is a hook for a derived facet to change the behavior of 00525 * widening. do_widen() must always return the same result for the 00526 * same input. 00527 * 00528 * Note: this is not what you want for codepage conversions. See 00529 * codecvt for that. 00530 * 00531 * @param lo Pointer to start range. 00532 * @param hi Pointer to end of range. 00533 * @param to Pointer to the destination array. 00534 * @return @a hi. 00535 */ 00536 virtual const char* 00537 do_widen(const char* __lo, const char* __hi, 00538 char_type* __dest) const = 0; 00539 00540 /** 00541 * @brief Narrow char_type to char 00542 * 00543 * This virtual function converts the argument to char using the 00544 * simplest reasonable transformation. If the conversion fails, dfault 00545 * is returned instead. 00546 * 00547 * do_narrow() is a hook for a derived facet to change the behavior of 00548 * narrowing. do_narrow() must always return the same result for the 00549 * same input. 00550 * 00551 * Note: this is not what you want for codepage conversions. See 00552 * codecvt for that. 00553 * 00554 * @param c The char_type to convert. 00555 * @param dfault Char to return if conversion fails. 00556 * @return The converted char. 00557 */ 00558 virtual char 00559 do_narrow(char_type, char __dfault) const = 0; 00560 00561 /** 00562 * @brief Narrow char_type array to char 00563 * 00564 * This virtual function converts each char_type in the range [lo,hi) to 00565 * char using the simplest reasonable transformation and writes the 00566 * results to the destination array. For any element in the input that 00567 * cannot be converted, @a dfault is used instead. 00568 * 00569 * do_narrow() is a hook for a derived facet to change the behavior of 00570 * narrowing. do_narrow() must always return the same result for the 00571 * same input. 00572 * 00573 * Note: this is not what you want for codepage conversions. See 00574 * codecvt for that. 00575 * 00576 * @param lo Pointer to start of range. 00577 * @param hi Pointer to end of range. 00578 * @param dfault Char to use if conversion fails. 00579 * @param to Pointer to the destination array. 00580 * @return @a hi. 00581 */ 00582 virtual const char_type* 00583 do_narrow(const char_type* __lo, const char_type* __hi, 00584 char __dfault, char* __dest) const = 0; 00585 }; 00586 00587 // NB: Generic, mostly useless implementation. 00588 /** 00589 * @brief Template ctype facet 00590 * 00591 * This template class defines classification and conversion functions for 00592 * character sets. It wraps <cctype> functionality. Ctype gets used by 00593 * streams for many I/O operations. 00594 * 00595 * This template provides the protected virtual functions the developer 00596 * will have to replace in a derived class or specialization to make a 00597 * working facet. The public functions that access them are defined in 00598 * __ctype_abstract_base, to allow for implementation flexibility. See 00599 * ctype<wchar_t> for an example. The functions are documented in 00600 * __ctype_abstract_base. 00601 * 00602 * Note: implementations are provided for all the protected virtual 00603 * functions, but will likely not be useful. 00604 */ 00605 template<typename _CharT> 00606 class ctype : public __ctype_abstract_base<_CharT> 00607 { 00608 public: 00609 // Types: 00610 typedef _CharT char_type; 00611 typedef typename __ctype_abstract_base<_CharT>::mask mask; 00612 00613 /// The facet id for ctype<char_type> 00614 static locale::id id; 00615 00616 explicit 00617 ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } 00618 00619 protected: 00620 virtual 00621 ~ctype(); 00622 00623 virtual bool 00624 do_is(mask __m, char_type __c) const; 00625 00626 virtual const char_type* 00627 do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; 00628 00629 virtual const char_type* 00630 do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; 00631 00632 virtual const char_type* 00633 do_scan_not(mask __m, const char_type* __lo, 00634 const char_type* __hi) const; 00635 00636 virtual char_type 00637 do_toupper(char_type __c) const; 00638 00639 virtual const char_type* 00640 do_toupper(char_type* __lo, const char_type* __hi) const; 00641 00642 virtual char_type 00643 do_tolower(char_type __c) const; 00644 00645 virtual const char_type* 00646 do_tolower(char_type* __lo, const char_type* __hi) const; 00647 00648 virtual char_type 00649 do_widen(char __c) const; 00650 00651 virtual const char* 00652 do_widen(const char* __lo, const char* __hi, char_type* __dest) const; 00653 00654 virtual char 00655 do_narrow(char_type, char __dfault) const; 00656 00657 virtual const char_type* 00658 do_narrow(const char_type* __lo, const char_type* __hi, 00659 char __dfault, char* __dest) const; 00660 }; 00661 00662 template<typename _CharT> 00663 locale::id ctype<_CharT>::id; 00664 00665 // 22.2.1.3 ctype<char> specialization. 00666 /** 00667 * @brief The ctype<char> specialization. 00668 * 00669 * This class defines classification and conversion functions for 00670 * the char type. It gets used by char streams for many I/O 00671 * operations. The char specialization provides a number of 00672 * optimizations as well. 00673 */ 00674 template<> 00675 class ctype<char> : public locale::facet, public ctype_base 00676 { 00677 public: 00678 // Types: 00679 /// Typedef for the template parameter char. 00680 typedef char char_type; 00681 00682 protected: 00683 // Data Members: 00684 __c_locale _M_c_locale_ctype; 00685 bool _M_del; 00686 __to_type _M_toupper; 00687 __to_type _M_tolower; 00688 const mask* _M_table; 00689 mutable char _M_widen_ok; 00690 mutable char _M_widen[1 + static_cast<unsigned char>(-1)]; 00691 mutable char _M_narrow[1 + static_cast<unsigned char>(-1)]; 00692 mutable char _M_narrow_ok; // 0 uninitialized, 1 init, 00693 // 2 memcpy can't be used 00694 00695 public: 00696 /// The facet id for ctype<char> 00697 static locale::id id; 00698 /// The size of the mask table. It is SCHAR_MAX + 1. 00699 static const size_t table_size = 1 + static_cast<unsigned char>(-1); 00700 00701 /** 00702 * @brief Constructor performs initialization. 00703 * 00704 * This is the constructor provided by the standard. 00705 * 00706 * @param table If non-zero, table is used as the per-char mask. 00707 * Else classic_table() is used. 00708 * @param del If true, passes ownership of table to this facet. 00709 * @param refs Passed to the base facet class. 00710 */ 00711 explicit 00712 ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); 00713 00714 /** 00715 * @brief Constructor performs static initialization. 00716 * 00717 * This constructor is used to construct the initial C locale facet. 00718 * 00719 * @param cloc Handle to C locale data. 00720 * @param table If non-zero, table is used as the per-char mask. 00721 * @param del If true, passes ownership of table to this facet. 00722 * @param refs Passed to the base facet class. 00723 */ 00724 explicit 00725 ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, 00726 size_t __refs = 0); 00727 00728 /** 00729 * @brief Test char classification. 00730 * 00731 * This function compares the mask table[c] to @a m. 00732 * 00733 * @param c The char to compare the mask of. 00734 * @param m The mask to compare against. 00735 * @return True if m & table[c] is true, false otherwise. 00736 */ 00737 inline bool 00738 is(mask __m, char __c) const; 00739 00740 /** 00741 * @brief Return a mask array. 00742 * 00743 * This function finds the mask for each char in the range [lo, hi) and 00744 * successively writes it to vec. vec must have as many elements as 00745 * the char array. 00746 * 00747 * @param lo Pointer to start of range. 00748 * @param hi Pointer to end of range. 00749 * @param vec Pointer to an array of mask storage. 00750 * @return @a hi. 00751 */ 00752 inline const char* 00753 is(const char* __lo, const char* __hi, mask* __vec) const; 00754 00755 /** 00756 * @brief Find char matching a mask 00757 * 00758 * This function searches for and returns the first char in [lo,hi) for 00759 * which is(m,char) is true. 00760 * 00761 * @param m The mask to compare against. 00762 * @param lo Pointer to start of range. 00763 * @param hi Pointer to end of range. 00764 * @return Pointer to a matching char if found, else @a hi. 00765 */ 00766 inline const char* 00767 scan_is(mask __m, const char* __lo, const char* __hi) const; 00768 00769 /** 00770 * @brief Find char not matching a mask 00771 * 00772 * This function searches for and returns a pointer to the first char 00773 * in [lo,hi) for which is(m,char) is false. 00774 * 00775 * @param m The mask to compare against. 00776 * @param lo Pointer to start of range. 00777 * @param hi Pointer to end of range. 00778 * @return Pointer to a non-matching char if found, else @a hi. 00779 */ 00780 inline const char* 00781 scan_not(mask __m, const char* __lo, const char* __hi) const; 00782 00783 /** 00784 * @brief Convert to uppercase. 00785 * 00786 * This function converts the char argument to uppercase if possible. 00787 * If not possible (for example, '2'), returns the argument. 00788 * 00789 * toupper() acts as if it returns ctype<char>::do_toupper(c). 00790 * do_toupper() must always return the same result for the same input. 00791 * 00792 * @param c The char to convert. 00793 * @return The uppercase char if convertible, else @a c. 00794 */ 00795 char_type 00796 toupper(char_type __c) const 00797 { return this->do_toupper(__c); } 00798 00799 /** 00800 * @brief Convert array to uppercase. 00801 * 00802 * This function converts each char in the range [lo,hi) to uppercase 00803 * if possible. Other chars remain untouched. 00804 * 00805 * toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi). 00806 * do_toupper() must always return the same result for the same input. 00807 * 00808 * @param lo Pointer to first char in range. 00809 * @param hi Pointer to end of range. 00810 * @return @a hi. 00811 */ 00812 const char_type* 00813 toupper(char_type *__lo, const char_type* __hi) const 00814 { return this->do_toupper(__lo, __hi); } 00815 00816 /** 00817 * @brief Convert to lowercase. 00818 * 00819 * This function converts the char argument to lowercase if possible. 00820 * If not possible (for example, '2'), returns the argument. 00821 * 00822 * tolower() acts as if it returns ctype<char>::do_tolower(c). 00823 * do_tolower() must always return the same result for the same input. 00824 * 00825 * @param c The char to convert. 00826 * @return The lowercase char if convertible, else @a c. 00827 */ 00828 char_type 00829 tolower(char_type __c) const 00830 { return this->do_tolower(__c); } 00831 00832 /** 00833 * @brief Convert array to lowercase. 00834 * 00835 * This function converts each char in the range [lo,hi) to lowercase 00836 * if possible. Other chars remain untouched. 00837 * 00838 * tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi). 00839 * do_tolower() must always return the same result for the same input. 00840 * 00841 * @param lo Pointer to first char in range. 00842 * @param hi Pointer to end of range. 00843 * @return @a hi. 00844 */ 00845 const char_type* 00846 tolower(char_type* __lo, const char_type* __hi) const 00847 { return this->do_tolower(__lo, __hi); } 00848 00849 /** 00850 * @brief Widen char 00851 * 00852 * This function converts the char to char_type using the simplest 00853 * reasonable transformation. For an underived ctype<char> facet, the 00854 * argument will be returned unchanged. 00855 * 00856 * This function works as if it returns ctype<char>::do_widen(c). 00857 * do_widen() must always return the same result for the same input. 00858 * 00859 * Note: this is not what you want for codepage conversions. See 00860 * codecvt for that. 00861 * 00862 * @param c The char to convert. 00863 * @return The converted character. 00864 */ 00865 char_type 00866 widen(char __c) const 00867 { 00868 if (_M_widen_ok) 00869 return _M_widen[static_cast<unsigned char>(__c)]; 00870 this->_M_widen_init(); 00871 return this->do_widen(__c); 00872 } 00873 00874 /** 00875 * @brief Widen char array 00876 * 00877 * This function converts each char in the input to char using the 00878 * simplest reasonable transformation. For an underived ctype<char> 00879 * facet, the argument will be copied unchanged. 00880 * 00881 * This function works as if it returns ctype<char>::do_widen(c). 00882 * do_widen() must always return the same result for the same input. 00883 * 00884 * Note: this is not what you want for codepage conversions. See 00885 * codecvt for that. 00886 * 00887 * @param lo Pointer to first char in range. 00888 * @param hi Pointer to end of range. 00889 * @param to Pointer to the destination array. 00890 * @return @a hi. 00891 */ 00892 const char* 00893 widen(const char* __lo, const char* __hi, char_type* __to) const 00894 { 00895 if (_M_widen_ok == 1) 00896 { 00897 memcpy(__to, __lo, __hi - __lo); 00898 return __hi; 00899 } 00900 if (!_M_widen_ok) 00901 _M_widen_init(); 00902 return this->do_widen(__lo, __hi, __to); 00903 } 00904 00905 /** 00906 * @brief Narrow char 00907 * 00908 * This function converts the char to char using the simplest 00909 * reasonable transformation. If the conversion fails, dfault is 00910 * returned instead. For an underived ctype<char> facet, @a c 00911 * will be returned unchanged. 00912 * 00913 * This function works as if it returns ctype<char>::do_narrow(c). 00914 * do_narrow() must always return the same result for the same input. 00915 * 00916 * Note: this is not what you want for codepage conversions. See 00917 * codecvt for that. 00918 * 00919 * @param c The char to convert. 00920 * @param dfault Char to return if conversion fails. 00921 * @return The converted character. 00922 */ 00923 char 00924 narrow(char_type __c, char __dfault) const 00925 { 00926 if (_M_narrow[static_cast<unsigned char>(__c)]) 00927 return _M_narrow[static_cast<unsigned char>(__c)]; 00928 const char __t = do_narrow(__c, __dfault); 00929 if (__t != __dfault) 00930 _M_narrow[static_cast<unsigned char>(__c)] = __t; 00931 return __t; 00932 } 00933 00934 /** 00935 * @brief Narrow char array 00936 * 00937 * This function converts each char in the input to char using the 00938 * simplest reasonable transformation and writes the results to the 00939 * destination array. For any char in the input that cannot be 00940 * converted, @a dfault is used instead. For an underived ctype<char> 00941 * facet, the argument will be copied unchanged. 00942 * 00943 * This function works as if it returns ctype<char>::do_narrow(lo, hi, 00944 * dfault, to). do_narrow() must always return the same result for the 00945 * same input. 00946 * 00947 * Note: this is not what you want for codepage conversions. See 00948 * codecvt for that. 00949 * 00950 * @param lo Pointer to start of range. 00951 * @param hi Pointer to end of range. 00952 * @param dfault Char to use if conversion fails. 00953 * @param to Pointer to the destination array. 00954 * @return @a hi. 00955 */ 00956 const char_type* 00957 narrow(const char_type* __lo, const char_type* __hi, 00958 char __dfault, char *__to) const 00959 { 00960 if (__builtin_expect(_M_narrow_ok == 1, true)) 00961 { 00962 memcpy(__to, __lo, __hi - __lo); 00963 return __hi; 00964 } 00965 if (!_M_narrow_ok) 00966 _M_narrow_init(); 00967 return this->do_narrow(__lo, __hi, __dfault, __to); 00968 } 00969 00970 protected: 00971 /// Returns a pointer to the mask table provided to the constructor, or 00972 /// the default from classic_table() if none was provided. 00973 const mask* 00974 table() const throw() 00975 { return _M_table; } 00976 00977 /// Returns a pointer to the C locale mask table. 00978 static const mask* 00979 classic_table() throw(); 00980 00981 /** 00982 * @brief Destructor. 00983 * 00984 * This function deletes table() if @a del was true in the 00985 * constructor. 00986 */ 00987 virtual 00988 ~ctype(); 00989 00990 /** 00991 * @brief Convert to uppercase. 00992 * 00993 * This virtual function converts the char argument to uppercase if 00994 * possible. If not possible (for example, '2'), returns the argument. 00995 * 00996 * do_toupper() is a hook for a derived facet to change the behavior of 00997 * uppercasing. do_toupper() must always return the same result for 00998 * the same input. 00999 * 01000 * @param c The char to convert. 01001 * @return The uppercase char if convertible, else @a c. 01002 */ 01003 virtual char_type 01004 do_toupper(char_type) const; 01005 01006 /** 01007 * @brief Convert array to uppercase. 01008 * 01009 * This virtual function converts each char in the range [lo,hi) to 01010 * uppercase if possible. Other chars remain untouched. 01011 * 01012 * do_toupper() is a hook for a derived facet to change the behavior of 01013 * uppercasing. do_toupper() must always return the same result for 01014 * the same input. 01015 * 01016 * @param lo Pointer to start of range. 01017 * @param hi Pointer to end of range. 01018 * @return @a hi. 01019 */ 01020 virtual const char_type* 01021 do_toupper(char_type* __lo, const char_type* __hi) const; 01022 01023 /** 01024 * @brief Convert to lowercase. 01025 * 01026 * This virtual function converts the char argument to lowercase if 01027 * possible. If not possible (for example, '2'), returns the argument. 01028 * 01029 * do_tolower() is a hook for a derived facet to change the behavior of 01030 * lowercasing. do_tolower() must always return the same result for 01031 * the same input. 01032 * 01033 * @param c The char to convert. 01034 * @return The lowercase char if convertible, else @a c. 01035 */ 01036 virtual char_type 01037 do_tolower(char_type) const; 01038 01039 /** 01040 * @brief Convert array to lowercase. 01041 * 01042 * This virtual function converts each char in the range [lo,hi) to 01043 * lowercase if possible. Other chars remain untouched. 01044 * 01045 * do_tolower() is a hook for a derived facet to change the behavior of 01046 * lowercasing. do_tolower() must always return the same result for 01047 * the same input. 01048 * 01049 * @param lo Pointer to first char in range. 01050 * @param hi Pointer to end of range. 01051 * @return @a hi. 01052 */ 01053 virtual const char_type* 01054 do_tolower(char_type* __lo, const char_type* __hi) const; 01055 01056 /** 01057 * @brief Widen char 01058 * 01059 * This virtual function converts the char to char using the simplest 01060 * reasonable transformation. For an underived ctype<char> facet, the 01061 * argument will be returned unchanged. 01062 * 01063 * do_widen() is a hook for a derived facet to change the behavior of 01064 * widening. do_widen() must always return the same result for the 01065 * same input. 01066 * 01067 * Note: this is not what you want for codepage conversions. See 01068 * codecvt for that. 01069 * 01070 * @param c The char to convert. 01071 * @return The converted character. 01072 */ 01073 virtual char_type 01074 do_widen(char __c) const 01075 { return __c; } 01076 01077 /** 01078 * @brief Widen char array 01079 * 01080 * This function converts each char in the range [lo,hi) to char using 01081 * the simplest reasonable transformation. For an underived 01082 * ctype<char> facet, the argument will be copied unchanged. 01083 * 01084 * do_widen() is a hook for a derived facet to change the behavior of 01085 * widening. do_widen() must always return the same result for the 01086 * same input. 01087 * 01088 * Note: this is not what you want for codepage conversions. See 01089 * codecvt for that. 01090 * 01091 * @param lo Pointer to start of range. 01092 * @param hi Pointer to end of range. 01093 * @param to Pointer to the destination array. 01094 * @return @a hi. 01095 */ 01096 virtual const char* 01097 do_widen(const char* __lo, const char* __hi, char_type* __dest) const 01098 { 01099 memcpy(__dest, __lo, __hi - __lo); 01100 return __hi; 01101 } 01102 01103 /** 01104 * @brief Narrow char 01105 * 01106 * This virtual function converts the char to char using the simplest 01107 * reasonable transformation. If the conversion fails, dfault is 01108 * returned instead. For an underived ctype<char> facet, @a c will be 01109 * returned unchanged. 01110 * 01111 * do_narrow() is a hook for a derived facet to change the behavior of 01112 * narrowing. do_narrow() must always return the same result for the 01113 * same input. 01114 * 01115 * Note: this is not what you want for codepage conversions. See 01116 * codecvt for that. 01117 * 01118 * @param c The char to convert. 01119 * @param dfault Char to return if conversion fails. 01120 * @return The converted char. 01121 */ 01122 virtual char 01123 do_narrow(char_type __c, char) const 01124 { return __c; } 01125 01126 /** 01127 * @brief Narrow char array to char array 01128 * 01129 * This virtual function converts each char in the range [lo,hi) to 01130 * char using the simplest reasonable transformation and writes the 01131 * results to the destination array. For any char in the input that 01132 * cannot be converted, @a dfault is used instead. For an underived 01133 * ctype<char> facet, the argument will be copied unchanged. 01134 * 01135 * do_narrow() is a hook for a derived facet to change the behavior of 01136 * narrowing. do_narrow() must always return the same result for the 01137 * same input. 01138 * 01139 * Note: this is not what you want for codepage conversions. See 01140 * codecvt for that. 01141 * 01142 * @param lo Pointer to start of range. 01143 * @param hi Pointer to end of range. 01144 * @param dfault Char to use if conversion fails. 01145 * @param to Pointer to the destination array. 01146 * @return @a hi. 01147 */ 01148 virtual const char_type* 01149 do_narrow(const char_type* __lo, const char_type* __hi, 01150 char, char* __dest) const 01151 { 01152 memcpy(__dest, __lo, __hi - __lo); 01153 return __hi; 01154 } 01155 01156 private: 01157 01158 void _M_widen_init() const 01159 { 01160 char __tmp[sizeof(_M_widen)]; 01161 for (size_t __i = 0; __i < sizeof(_M_widen); ++__i) 01162 __tmp[__i] = __i; 01163 do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); 01164 01165 _M_widen_ok = 1; 01166 // Set _M_widen_ok to 2 if memcpy can't be used. 01167 if (memcmp(__tmp, _M_widen, sizeof(_M_widen))) 01168 _M_widen_ok = 2; 01169 } 01170 01171 // Fill in the narrowing cache and flag whether all values are 01172 // valid or not. _M_narrow_ok is set to 2 if memcpy can't 01173 // be used. 01174 void _M_narrow_init() const 01175 { 01176 char __tmp[sizeof(_M_narrow)]; 01177 for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i) 01178 __tmp[__i] = __i; 01179 do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); 01180 01181 _M_narrow_ok = 1; 01182 if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow))) 01183 _M_narrow_ok = 2; 01184 else 01185 { 01186 // Deal with the special case of zero: renarrow with a 01187 // different default and compare. 01188 char __c; 01189 do_narrow(__tmp, __tmp + 1, 1, &__c); 01190 if (__c == 1) 01191 _M_narrow_ok = 2; 01192 } 01193 } 01194 }; 01195 01196 template<> 01197 const ctype<char>& 01198 use_facet<ctype<char> >(const locale& __loc); 01199 01200 #ifdef _GLIBCXX_USE_WCHAR_T 01201 // 22.2.1.3 ctype<wchar_t> specialization 01202 /** 01203 * @brief The ctype<wchar_t> specialization. 01204 * 01205 * This class defines classification and conversion functions for the 01206 * wchar_t type. It gets used by wchar_t streams for many I/O operations. 01207 * The wchar_t specialization provides a number of optimizations as well. 01208 * 01209 * ctype<wchar_t> inherits its public methods from 01210 * __ctype_abstract_base<wchar_t>. 01211 */ 01212 template<> 01213 class ctype<wchar_t> : public __ctype_abstract_base<wchar_t> 01214 { 01215 public: 01216 // Types: 01217 /// Typedef for the template parameter wchar_t. 01218 typedef wchar_t char_type; 01219 typedef wctype_t __wmask_type; 01220 01221 protected: 01222 __c_locale _M_c_locale_ctype; 01223 01224 // Pre-computed narrowed and widened chars. 01225 bool _M_narrow_ok; 01226 char _M_narrow[128]; 01227 wint_t _M_widen[1 + static_cast<unsigned char>(-1)]; 01228 01229 // Pre-computed elements for do_is. 01230 mask _M_bit[16]; 01231 __wmask_type _M_wmask[16]; 01232 01233 public: 01234 // Data Members: 01235 /// The facet id for ctype<wchar_t> 01236 static locale::id id; 01237 01238 /** 01239 * @brief Constructor performs initialization. 01240 * 01241 * This is the constructor provided by the standard. 01242 * 01243 * @param refs Passed to the base facet class. 01244 */ 01245 explicit 01246 ctype(size_t __refs = 0); 01247 01248 /** 01249 * @brief Constructor performs static initialization. 01250 * 01251 * This constructor is used to construct the initial C locale facet. 01252 * 01253 * @param cloc Handle to C locale data. 01254 * @param refs Passed to the base facet class. 01255 */ 01256 explicit 01257 ctype(__c_locale __cloc, size_t __refs = 0); 01258 01259 protected: 01260 __wmask_type 01261 _M_convert_to_wmask(const mask __m) const; 01262 01263 /// Destructor 01264 virtual 01265 ~ctype(); 01266 01267 /** 01268 * @brief Test wchar_t classification. 01269 * 01270 * This function finds a mask M for @a c and compares it to mask @a m. 01271 * 01272 * do_is() is a hook for a derived facet to change the behavior of 01273 * classifying. do_is() must always return the same result for the 01274 * same input. 01275 * 01276 * @param c The wchar_t to find the mask of. 01277 * @param m The mask to compare against. 01278 * @return (M & m) != 0. 01279 */ 01280 virtual bool 01281 do_is(mask __m, char_type __c) const; 01282 01283 /** 01284 * @brief Return a mask array. 01285 * 01286 * This function finds the mask for each wchar_t in the range [lo,hi) 01287 * and successively writes it to vec. vec must have as many elements 01288 * as the input. 01289 * 01290 * do_is() is a hook for a derived facet to change the behavior of 01291 * classifying. do_is() must always return the same result for the 01292 * same input. 01293 * 01294 * @param lo Pointer to start of range. 01295 * @param hi Pointer to end of range. 01296 * @param vec Pointer to an array of mask storage. 01297 * @return @a hi. 01298 */ 01299 virtual const char_type* 01300 do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; 01301 01302 /** 01303 * @brief Find wchar_t matching mask 01304 * 01305 * This function searches for and returns the first wchar_t c in 01306 * [lo,hi) for which is(m,c) is true. 01307 * 01308 * do_scan_is() is a hook for a derived facet to change the behavior of 01309 * match searching. do_is() must always return the same result for the 01310 * same input. 01311 * 01312 * @param m The mask to compare against. 01313 * @param lo Pointer to start of range. 01314 * @param hi Pointer to end of range. 01315 * @return Pointer to a matching wchar_t if found, else @a hi. 01316 */ 01317 virtual const char_type* 01318 do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; 01319 01320 /** 01321 * @brief Find wchar_t not matching mask 01322 * 01323 * This function searches for and returns a pointer to the first 01324 * wchar_t c of [lo,hi) for which is(m,c) is false. 01325 * 01326 * do_scan_is() is a hook for a derived facet to change the behavior of 01327 * match searching. do_is() must always return the same result for the 01328 * same input. 01329 * 01330 * @param m The mask to compare against. 01331 * @param lo Pointer to start of range. 01332 * @param hi Pointer to end of range. 01333 * @return Pointer to a non-matching wchar_t if found, else @a hi. 01334 */ 01335 virtual const char_type* 01336 do_scan_not(mask __m, const char_type* __lo, 01337 const char_type* __hi) const; 01338 01339 /** 01340 * @brief Convert to uppercase. 01341 * 01342 * This virtual function converts the wchar_t argument to uppercase if 01343 * possible. If not possible (for example, '2'), returns the argument. 01344 * 01345 * do_toupper() is a hook for a derived facet to change the behavior of 01346 * uppercasing. do_toupper() must always return the same result for 01347 * the same input. 01348 * 01349 * @param c The wchar_t to convert. 01350 * @return The uppercase wchar_t if convertible, else @a c. 01351 */ 01352 virtual char_type 01353 do_toupper(char_type) const; 01354 01355 /** 01356 * @brief Convert array to uppercase. 01357 * 01358 * This virtual function converts each wchar_t in the range [lo,hi) to 01359 * uppercase if possible. Other elements remain untouched. 01360 * 01361 * do_toupper() is a hook for a derived facet to change the behavior of 01362 * uppercasing. do_toupper() must always return the same result for 01363 * the same input. 01364 * 01365 * @param lo Pointer to start of range. 01366 * @param hi Pointer to end of range. 01367 * @return @a hi. 01368 */ 01369 virtual const char_type* 01370 do_toupper(char_type* __lo, const char_type* __hi) const; 01371 01372 /** 01373 * @brief Convert to lowercase. 01374 * 01375 * This virtual function converts the argument to lowercase if 01376 * possible. If not possible (for example, '2'), returns the argument. 01377 * 01378 * do_tolower() is a hook for a derived facet to change the behavior of 01379 * lowercasing. do_tolower() must always return the same result for 01380 * the same input. 01381 * 01382 * @param c The wchar_t to convert. 01383 * @return The lowercase wchar_t if convertible, else @a c. 01384 */ 01385 virtual char_type 01386 do_tolower(char_type) const; 01387 01388 /** 01389 * @brief Convert array to lowercase. 01390 * 01391 * This virtual function converts each wchar_t in the range [lo,hi) to 01392 * lowercase if possible. Other elements remain untouched. 01393 * 01394 * do_tolower() is a hook for a derived facet to change the behavior of 01395 * lowercasing. do_tolower() must always return the same result for 01396 * the same input. 01397 * 01398 * @param lo Pointer to start of range. 01399 * @param hi Pointer to end of range. 01400 * @return @a hi. 01401 */ 01402 virtual const char_type* 01403 do_tolower(char_type* __lo, const char_type* __hi) const; 01404 01405 /** 01406 * @brief Widen char to wchar_t 01407 * 01408 * This virtual function converts the char to wchar_t using the 01409 * simplest reasonable transformation. For an underived ctype<wchar_t> 01410 * facet, the argument will be cast to wchar_t. 01411 * 01412 * do_widen() is a hook for a derived facet to change the behavior of 01413 * widening. do_widen() must always return the same result for the 01414 * same input. 01415 * 01416 * Note: this is not what you want for codepage conversions. See 01417 * codecvt for that. 01418 * 01419 * @param c The char to convert. 01420 * @return The converted wchar_t. 01421 */ 01422 virtual char_type 01423 do_widen(char) const; 01424 01425 /** 01426 * @brief Widen char array to wchar_t array 01427 * 01428 * This function converts each char in the input to wchar_t using the 01429 * simplest reasonable transformation. For an underived ctype<wchar_t> 01430 * facet, the argument will be copied, casting each element to wchar_t. 01431 * 01432 * do_widen() is a hook for a derived facet to change the behavior of 01433 * widening. do_widen() must always return the same result for the 01434 * same input. 01435 * 01436 * Note: this is not what you want for codepage conversions. See 01437 * codecvt for that. 01438 * 01439 * @param lo Pointer to start range. 01440 * @param hi Pointer to end of range. 01441 * @param to Pointer to the destination array. 01442 * @return @a hi. 01443 */ 01444 virtual const char* 01445 do_widen(const char* __lo, const char* __hi, char_type* __dest) const; 01446 01447 /** 01448 * @brief Narrow wchar_t to char 01449 * 01450 * This virtual function converts the argument to char using 01451 * the simplest reasonable transformation. If the conversion 01452 * fails, dfault is returned instead. For an underived 01453 * ctype<wchar_t> facet, @a c will be cast to char and 01454 * returned. 01455 * 01456 * do_narrow() is a hook for a derived facet to change the 01457 * behavior of narrowing. do_narrow() must always return the 01458 * same result for the same input. 01459 * 01460 * Note: this is not what you want for codepage conversions. See 01461 * codecvt for that. 01462 * 01463 * @param c The wchar_t to convert. 01464 * @param dfault Char to return if conversion fails. 01465 * @return The converted char. 01466 */ 01467 virtual char 01468 do_narrow(char_type, char __dfault) const; 01469 01470 /** 01471 * @brief Narrow wchar_t array to char array 01472 * 01473 * This virtual function converts each wchar_t in the range [lo,hi) to 01474 * char using the simplest reasonable transformation and writes the 01475 * results to the destination array. For any wchar_t in the input that 01476 * cannot be converted, @a dfault is used instead. For an underived 01477 * ctype<wchar_t> facet, the argument will be copied, casting each 01478 * element to char. 01479 * 01480 * do_narrow() is a hook for a derived facet to change the behavior of 01481 * narrowing. do_narrow() must always return the same result for the 01482 * same input. 01483 * 01484 * Note: this is not what you want for codepage conversions. See 01485 * codecvt for that. 01486 * 01487 * @param lo Pointer to start of range. 01488 * @param hi Pointer to end of range. 01489 * @param dfault Char to use if conversion fails. 01490 * @param to Pointer to the destination array. 01491 * @return @a hi. 01492 */ 01493 virtual const char_type* 01494 do_narrow(const char_type* __lo, const char_type* __hi, 01495 char __dfault, char* __dest) const; 01496 01497 // For use at construction time only. 01498 void 01499 _M_initialize_ctype(); 01500 }; 01501 01502 template<> 01503 const ctype<wchar_t>& 01504 use_facet<ctype<wchar_t> >(const locale& __loc); 01505 #endif //_GLIBCXX_USE_WCHAR_T 01506 01507 // Include host and configuration specific ctype inlines. 01508 #include <bits/ctype_inline.h> 01509 01510 // 22.2.1.2 Template class ctype_byname 01511 template<typename _CharT> 01512 class ctype_byname : public ctype<_CharT> 01513 { 01514 public: 01515 typedef _CharT char_type; 01516 01517 explicit 01518 ctype_byname(const char* __s, size_t __refs = 0); 01519 01520 protected: 01521 virtual 01522 ~ctype_byname() { }; 01523 }; 01524 01525 // 22.2.1.4 Class ctype_byname specializations. 01526 template<> 01527 ctype_byname<char>::ctype_byname(const char*, size_t refs); 01528 01529 template<> 01530 ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs); 01531 01532 // 22.2.1.5 Template class codecvt 01533 #include <bits/codecvt.h> 01534 01535 // 22.2.2 The numeric category. 01536 class __num_base 01537 { 01538 public: 01539 // NB: Code depends on the order of _S_atoms_out elements. 01540 // Below are the indices into _S_atoms_out. 01541 enum 01542 { 01543 _S_ominus, 01544 _S_oplus, 01545 _S_ox, 01546 _S_oX, 01547 _S_odigits, 01548 _S_odigits_end = _S_odigits + 16, 01549 _S_oudigits = _S_odigits_end, 01550 _S_oudigits_end = _S_oudigits + 16, 01551 _S_oe = _S_odigits + 14, // For scientific notation, 'e' 01552 _S_oE = _S_oudigits + 14, // For scientific notation, 'E' 01553 _S_oend = _S_oudigits_end 01554 }; 01555 01556 // A list of valid numeric literals for output. This array 01557 // contains chars that will be passed through the current locale's 01558 // ctype<_CharT>.widen() and then used to render numbers. 01559 // For the standard "C" locale, this is 01560 // "-+xX0123456789abcdef0123456789ABCDEF". 01561 static const char* _S_atoms_out; 01562 01563 // String literal of acceptable (narrow) input, for num_get. 01564 // "-+xX0123456789abcdefABCDEF" 01565 static const char* _S_atoms_in; 01566 01567 enum 01568 { 01569 _S_iminus, 01570 _S_iplus, 01571 _S_ix, 01572 _S_iX, 01573 _S_izero, 01574 _S_ie = _S_izero + 14, 01575 _S_iE = _S_izero + 20, 01576 _S_iend = 26 01577 }; 01578 01579 // num_put 01580 // Construct and return valid scanf format for floating point types. 01581 static void 01582 _S_format_float(const ios_base& __io, char* __fptr, char __mod); 01583 }; 01584 01585 template<typename _CharT> 01586 struct __numpunct_cache : public locale::facet 01587 { 01588 const char* _M_grouping; 01589 size_t _M_grouping_size; 01590 bool _M_use_grouping; 01591 const _CharT* _M_truename; 01592 size_t _M_truename_size; 01593 const _CharT* _M_falsename; 01594 size_t _M_falsename_size; 01595 _CharT _M_decimal_point; 01596 _CharT _M_thousands_sep; 01597 01598 // A list of valid numeric literals for output: in the standard 01599 // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". 01600 // This array contains the chars after having been passed 01601 // through the current locale's ctype<_CharT>.widen(). 01602 _CharT _M_atoms_out[__num_base::_S_oend]; 01603 01604 // A list of valid numeric literals for input: in the standard 01605 // "C" locale, this is "-+xX0123456789abcdefABCDEF" 01606 // This array contains the chars after having been passed 01607 // through the current locale's ctype<_CharT>.widen(). 01608 _CharT _M_atoms_in[__num_base::_S_iend]; 01609 01610 bool _M_allocated; 01611 01612 __numpunct_cache(size_t __refs = 0) : facet(__refs), 01613 _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), 01614 _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL), 01615 _M_falsename_size(0), _M_decimal_point(_CharT()), 01616 _M_thousands_sep(_CharT()), _M_allocated(false) 01617 { } 01618 01619 ~__numpunct_cache(); 01620 01621 void 01622 _M_cache(const locale& __loc); 01623 01624 private: 01625 __numpunct_cache& 01626 operator=(const __numpunct_cache&); 01627 01628 explicit 01629 __numpunct_cache(const __numpunct_cache&); 01630 }; 01631 01632 template<typename _CharT> 01633 __numpunct_cache<_CharT>::~__numpunct_cache() 01634 { 01635 if (_M_allocated) 01636 { 01637 delete [] _M_grouping; 01638 delete [] _M_truename; 01639 delete [] _M_falsename; 01640 } 01641 } 01642 01643 /** 01644 * @brief Numpunct facet. 01645 * 01646 * This facet stores several pieces of information related to printing and 01647 * scanning numbers, such as the decimal point character. It takes a 01648 * template parameter specifying the char type. The numpunct facet is 01649 * used by streams for many I/O operations involving numbers. 01650 * 01651 * The numpunct template uses protected virtual functions to provide the 01652 * actual results. The public accessors forward the call to the virtual 01653 * functions. These virtual functions are hooks for developers to 01654 * implement the behavior they require from a numpunct facet. 01655 */ 01656 template<typename _CharT> 01657 class numpunct : public locale::facet 01658 { 01659 public: 01660 // Types: 01661 //@{ 01662 /// Public typedefs 01663 typedef _CharT char_type; 01664 typedef basic_string<_CharT> string_type; 01665 //@} 01666 typedef __numpunct_cache<_CharT> __cache_type; 01667 01668 protected: 01669 __cache_type* _M_data; 01670 01671 public: 01672 /// Numpunct facet id. 01673 static locale::id id; 01674 01675 /** 01676 * @brief Numpunct constructor. 01677 * 01678 * @param refs Refcount to pass to the base class. 01679 */ 01680 explicit 01681 numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) 01682 { _M_initialize_numpunct(); } 01683 01684 /** 01685 * @brief Internal constructor. Not for general use. 01686 * 01687 * This is a constructor for use by the library itself to set up the 01688 * predefined locale facets. 01689 * 01690 * @param cache __numpunct_cache object. 01691 * @param refs Refcount to pass to the base class. 01692 */ 01693 explicit 01694 numpunct(__cache_type* __cache, size_t __refs = 0) 01695 : facet(__refs), _M_data(__cache) 01696 { _M_initialize_numpunct(); } 01697 01698 /** 01699 * @brief Internal constructor. Not for general use. 01700 * 01701 * This is a constructor for use by the library itself to set up new 01702 * locales. 01703 * 01704 * @param cloc The "C" locale. 01705 * @param refs Refcount to pass to the base class. 01706 */ 01707 explicit 01708 numpunct(__c_locale __cloc, size_t __refs = 0) 01709 : facet(__refs), _M_data(NULL) 01710 { _M_initialize_numpunct(__cloc); } 01711 01712 /** 01713 * @brief Return decimal point character. 01714 * 01715 * This function returns a char_type to use as a decimal point. It 01716 * does so by returning returning 01717 * numpunct<char_type>::do_decimal_point(). 01718 * 01719 * @return @a char_type representing a decimal point. 01720 */ 01721 char_type 01722 decimal_point() const 01723 { return this->do_decimal_point(); } 01724 01725 /** 01726 * @brief Return thousands separator character. 01727 * 01728 * This function returns a char_type to use as a thousands 01729 * separator. It does so by returning returning 01730 * numpunct<char_type>::do_thousands_sep(). 01731 * 01732 * @return char_type representing a thousands separator. 01733 */ 01734 char_type 01735 thousands_sep() const 01736 { return this->do_thousands_sep(); } 01737 01738 /** 01739 * @brief Return grouping specification. 01740 * 01741 * This function returns a string representing groupings for the 01742 * integer part of a number. Groupings indicate where thousands 01743 * separators should be inserted in the integer part of a number. 01744 * 01745 * Each char in the return string is interpret as an integer 01746 * rather than a character. These numbers represent the number 01747 * of digits in a group. The first char in the string 01748 * represents the number of digits in the least significant 01749 * group. If a char is negative, it indicates an unlimited 01750 * number of digits for the group. If more chars from the 01751 * string are required to group a number, the last char is used 01752 * repeatedly. 01753 * 01754 * For example, if the grouping() returns "\003\002" and is 01755 * applied to the number 123456789, this corresponds to 01756 * 12,34,56,789. Note that if the string was "32", this would 01757 * put more than 50 digits into the least significant group if 01758 * the character set is ASCII. 01759 * 01760 * The string is returned by calling 01761 * numpunct<char_type>::do_grouping(). 01762 * 01763 * @return string representing grouping specification. 01764 */ 01765 string 01766 grouping() const 01767 { return this->do_grouping(); } 01768 01769 /** 01770 * @brief Return string representation of bool true. 01771 * 01772 * This function returns a string_type containing the text 01773 * representation for true bool variables. It does so by calling 01774 * numpunct<char_type>::do_truename(). 01775 * 01776 * @return string_type representing printed form of true. 01777 */ 01778 string_type 01779 truename() const 01780 { return this->do_truename(); } 01781 01782 /** 01783 * @brief Return string representation of bool false. 01784 * 01785 * This function returns a string_type containing the text 01786 * representation for false bool variables. It does so by calling 01787 * numpunct<char_type>::do_falsename(). 01788 * 01789 * @return string_type representing printed form of false. 01790 */ 01791 string_type 01792 falsename() const 01793 { return this->do_falsename(); } 01794 01795 protected: 01796 /// Destructor. 01797 virtual 01798 ~numpunct(); 01799 01800 /** 01801 * @brief Return decimal point character. 01802 * 01803 * Returns a char_type to use as a decimal point. This function is a 01804 * hook for derived classes to change the value returned. 01805 * 01806 * @return @a char_type representing a decimal point. 01807 */ 01808 virtual char_type 01809 do_decimal_point() const 01810 { return _M_data->_M_decimal_point; } 01811 01812 /** 01813 * @brief Return thousands separator character. 01814 * 01815 * Returns a char_type to use as a thousands separator. This function 01816 * is a hook for derived classes to change the value returned. 01817 * 01818 * @return @a char_type representing a thousands separator. 01819 */ 01820 virtual char_type 01821 do_thousands_sep() const 01822 { return _M_data->_M_thousands_sep; } 01823 01824 /** 01825 * @brief Return grouping specification. 01826 * 01827 * Returns a string representing groupings for the integer part of a 01828 * number. This function is a hook for derived classes to change the 01829 * value returned. @see grouping() for details. 01830 * 01831 * @return String representing grouping specification. 01832 */ 01833 virtual string 01834 do_grouping() const 01835 { return _M_data->_M_grouping; } 01836 01837 /** 01838 * @brief Return string representation of bool true. 01839 * 01840 * Returns a string_type containing the text representation for true 01841 * bool variables. This function is a hook for derived classes to 01842 * change the value returned. 01843 * 01844 * @return string_type representing printed form of true. 01845 */ 01846 virtual string_type 01847 do_truename() const 01848 { return _M_data->_M_truename; } 01849 01850 /** 01851 * @brief Return string representation of bool false. 01852 * 01853 * Returns a string_type containing the text representation for false 01854 * bool variables. This function is a hook for derived classes to 01855 * change the value returned. 01856 * 01857 * @return string_type representing printed form of false. 01858 */ 01859 virtual string_type 01860 do_falsename() const 01861 { return _M_data->_M_falsename; } 01862 01863 // For use at construction time only. 01864 void 01865 _M_initialize_numpunct(__c_locale __cloc = NULL); 01866 }; 01867 01868 template<typename _CharT> 01869 locale::id numpunct<_CharT>::id; 01870 01871 template<> 01872 numpunct<char>::~numpunct(); 01873 01874 template<> 01875 void 01876 numpunct<char>::_M_initialize_numpunct(__c_locale __cloc); 01877 01878 #ifdef _GLIBCXX_USE_WCHAR_T 01879 template<> 01880 numpunct<wchar_t>::~numpunct(); 01881 01882 template<> 01883 void 01884 numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc); 01885 #endif 01886 01887 template<typename _CharT> 01888 class numpunct_byname : public numpunct<_CharT> 01889 { 01890 public: 01891 typedef _CharT char_type; 01892 typedef basic_string<_CharT> string_type; 01893 01894 explicit 01895 numpunct_byname(const char* __s, size_t __refs = 0) 01896 : numpunct<_CharT>(__refs) 01897 { 01898 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 01899 { 01900 __c_locale __tmp; 01901 this->_S_create_c_locale(__tmp, __s); 01902 this->_M_initialize_numpunct(__tmp); 01903 this->_S_destroy_c_locale(__tmp); 01904 } 01905 } 01906 01907 protected: 01908 virtual 01909 ~numpunct_byname() { } 01910 }; 01911 01912 /** 01913 * @brief Facet for parsing number strings. 01914 * 01915 * This facet encapsulates the code to parse and return a number 01916 * from a string. It is used by the istream numeric extraction 01917 * operators. 01918 * 01919 * The num_get template uses protected virtual functions to provide the 01920 * actual results. The public accessors forward the call to the virtual 01921 * functions. These virtual functions are hooks for developers to 01922 * implement the behavior they require from the num_get facet. 01923 */ 01924 template<typename _CharT, typename _InIter> 01925 class num_get : public locale::facet 01926 { 01927 public: 01928 // Types: 01929 //@{ 01930 /// Public typedefs 01931 typedef _CharT char_type; 01932 typedef _InIter iter_type; 01933 //@} 01934 01935 /// Numpunct facet id. 01936 static locale::id id; 01937 01938 /** 01939 * @brief Constructor performs initialization. 01940 * 01941 * This is the constructor provided by the standard. 01942 * 01943 * @param refs Passed to the base facet class. 01944 */ 01945 explicit 01946 num_get(size_t __refs = 0) : facet(__refs) { } 01947 01948 /** 01949 * @brief Numeric parsing. 01950 * 01951 * Parses the input stream into the bool @a v. It does so by calling 01952 * num_put::do_put(). 01953 * 01954 * If ios_base::boolalpha is set, attempts to read 01955 * ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets 01956 * @a v to true or false if successful. Sets err to 01957 * ios_base::failbit if reading the string fails. Sets err to 01958 * ios_base::eofbit if the stream is emptied. 01959 * 01960 * If ios_base::boolalpha is not set, proceeds as with reading a long, 01961 * except if the value is 1, sets @a v to true, if the value is 0, sets 01962 * @a v to false, and otherwise set err to ios_base::failbit. 01963 * 01964 * @param in Start of input stream. 01965 * @param end End of input stream. 01966 * @param io Source of locale and flags. 01967 * @param err Error flags to set. 01968 * @param v Value to format and insert. 01969 * @return Iterator after reading. 01970 */ 01971 iter_type 01972 get(iter_type __in, iter_type __end, ios_base& __io, 01973 ios_base::iostate& __err, bool& __v) const 01974 { return this->do_get(__in, __end, __io, __err, __v); } 01975 01976 //@{ 01977 /** 01978 * @brief Numeric parsing. 01979 * 01980 * Parses the input stream into the integral variable @a v. It does so 01981 * by calling num_put::do_put(). 01982 * 01983 * Parsing is affected by the flag settings in @a io. 01984 * 01985 * The basic parse is affected by the value of io.flags() & 01986 * ios_base::basefield. If equal to ios_base::oct, parses like the 01987 * scanf %o specifier. Else if equal to ios_base::hex, parses like %X 01988 * specifier. Else if basefield equal to 0, parses like the %i 01989 * specifier. Otherwise, parses like %d for signed and %u for unsigned 01990 * types. The matching type length modifier is also used. 01991 * 01992 * Digit grouping is intrepreted according to numpunct::grouping() and 01993 * numpunct::thousands_sep(). If the pattern of digit groups isn't 01994 * consistent, sets err to ios_base::failbit. 01995 * 01996 * If parsing the string yields a valid value for @a v, @a v is set. 01997 * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 01998 * Sets err to ios_base::eofbit if the stream is emptied. 01999 * 02000 * @param in Start of input stream. 02001 * @param end End of input stream. 02002 * @param io Source of locale and flags. 02003 * @param err Error flags to set. 02004 * @param v Value to format and insert. 02005 * @return Iterator after reading. 02006 */ 02007 iter_type 02008 get(iter_type __in, iter_type __end, ios_base& __io, 02009 ios_base::iostate& __err, long& __v) const 02010 { return this->do_get(__in, __end, __io, __err, __v); } 02011 02012 iter_type 02013 get(iter_type __in, iter_type __end, ios_base& __io, 02014 ios_base::iostate& __err, unsigned short& __v) const 02015 { return this->do_get(__in, __end, __io, __err, __v); } 02016 02017 iter_type 02018 get(iter_type __in, iter_type __end, ios_base& __io, 02019 ios_base::iostate& __err, unsigned int& __v) const 02020 { return this->do_get(__in, __end, __io, __err, __v); } 02021 02022 iter_type 02023 get(iter_type __in, iter_type __end, ios_base& __io, 02024 ios_base::iostate& __err, unsigned long& __v) const 02025 { return this->do_get(__in, __end, __io, __err, __v); } 02026 02027 #ifdef _GLIBCXX_USE_LONG_LONG 02028 iter_type 02029 get(iter_type __in, iter_type __end, ios_base& __io, 02030 ios_base::iostate& __err, long long& __v) const 02031 { return this->do_get(__in, __end, __io, __err, __v); } 02032 02033 iter_type 02034 get(iter_type __in, iter_type __end, ios_base& __io, 02035 ios_base::iostate& __err, unsigned long long& __v) const 02036 { return this->do_get(__in, __end, __io, __err, __v); } 02037 #endif 02038 //@} 02039 02040 //@{ 02041 /** 02042 * @brief Numeric parsing. 02043 * 02044 * Parses the input stream into the integral variable @a v. It does so 02045 * by calling num_put::do_put(). 02046 * 02047 * The input characters are parsed like the scanf %g specifier. The 02048 * matching type length modifier is also used. 02049 * 02050 * The decimal point character used is numpunct::decimal_point(). 02051 * Digit grouping is intrepreted according to numpunct::grouping() and 02052 * numpunct::thousands_sep(). If the pattern of digit groups isn't 02053 * consistent, sets err to ios_base::failbit. 02054 * 02055 * If parsing the string yields a valid value for @a v, @a v is set. 02056 * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 02057 * Sets err to ios_base::eofbit if the stream is emptied. 02058 * 02059 * @param in Start of input stream. 02060 * @param end End of input stream. 02061 * @param io Source of locale and flags. 02062 * @param err Error flags to set. 02063 * @param v Value to format and insert. 02064 * @return Iterator after reading. 02065 */ 02066 iter_type 02067 get(iter_type __in, iter_type __end, ios_base& __io, 02068 ios_base::iostate& __err, float& __v) const 02069 { return this->do_get(__in, __end, __io, __err, __v); } 02070 02071 iter_type 02072 get(iter_type __in, iter_type __end, ios_base& __io, 02073 ios_base::iostate& __err, double& __v) const 02074 { return this->do_get(__in, __end, __io, __err, __v); } 02075 02076 iter_type 02077 get(iter_type __in, iter_type __end, ios_base& __io, 02078 ios_base::iostate& __err, long double& __v) const 02079 { return this->do_get(__in, __end, __io, __err, __v); } 02080 //@} 02081 02082 /** 02083 * @brief Numeric parsing. 02084 * 02085 * Parses the input stream into the pointer variable @a v. It does so 02086 * by calling num_put::do_put(). 02087 * 02088 * The input characters are parsed like the scanf %p specifier. 02089 * 02090 * Digit grouping is intrepreted according to numpunct::grouping() and 02091 * numpunct::thousands_sep(). If the pattern of digit groups isn't 02092 * consistent, sets err to ios_base::failbit. 02093 * 02094 * Note that the digit grouping effect for pointers is a bit ambiguous 02095 * in the standard and shouldn't be relied on. See DR 344. 02096 * 02097 * If parsing the string yields a valid value for @a v, @a v is set. 02098 * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 02099 * Sets err to ios_base::eofbit if the stream is emptied. 02100 * 02101 * @param in Start of input stream. 02102 * @param end End of input stream. 02103 * @param io Source of locale and flags. 02104 * @param err Error flags to set. 02105 * @param v Value to format and insert. 02106 * @return Iterator after reading. 02107 */ 02108 iter_type 02109 get(iter_type __in, iter_type __end, ios_base& __io, 02110 ios_base::iostate& __err, void*& __v) const 02111 { return this->do_get(__in, __end, __io, __err, __v); } 02112 02113 protected: 02114 /// Destructor. 02115 virtual ~num_get() { } 02116 02117 iter_type 02118 _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, 02119 string& __xtrc) const; 02120 02121 template<typename _ValueT> 02122 iter_type 02123 _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, 02124 _ValueT& __v) const; 02125 02126 //@{ 02127 /** 02128 * @brief Numeric parsing. 02129 * 02130 * Parses the input stream into the variable @a v. This function is a 02131 * hook for derived classes to change the value returned. @see get() 02132 * for more details. 02133 * 02134 * @param in Start of input stream. 02135 * @param end End of input stream. 02136 * @param io Source of locale and flags. 02137 * @param err Error flags to set. 02138 * @param v Value to format and insert. 02139 * @return Iterator after reading. 02140 */ 02141 virtual iter_type 02142 do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; 02143 02144 02145 virtual iter_type 02146 do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; 02147 02148 virtual iter_type 02149 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02150 unsigned short&) const; 02151 02152 virtual iter_type 02153 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02154 unsigned int&) const; 02155 02156 virtual iter_type 02157 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02158 unsigned long&) const; 02159 02160 #ifdef _GLIBCXX_USE_LONG_LONG 02161 virtual iter_type 02162 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02163 long long&) const; 02164 02165 virtual iter_type 02166 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02167 unsigned long long&) const; 02168 #endif 02169 02170 virtual iter_type 02171 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02172 float&) const; 02173 02174 virtual iter_type 02175 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02176 double&) const; 02177 02178 virtual iter_type 02179 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02180 long double&) const; 02181 02182 virtual iter_type 02183 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02184 void*&) const; 02185 //@} 02186 }; 02187 02188 template<typename _CharT, typename _InIter> 02189 locale::id num_get<_CharT, _InIter>::id; 02190 02191 02192 /** 02193 * @brief Facet for converting numbers to strings. 02194 * 02195 * This facet encapsulates the code to convert a number to a string. It is 02196 * used by the ostream numeric insertion operators. 02197 * 02198 * The num_put template uses protected virtual functions to provide the 02199 * actual results. The public accessors forward the call to the virtual 02200 * functions. These virtual functions are hooks for developers to 02201 * implement the behavior they require from the num_put facet. 02202 */ 02203 template<typename _CharT, typename _OutIter> 02204 class num_put : public locale::facet 02205 { 02206 public: 02207 // Types: 02208 //@{ 02209 /// Public typedefs 02210 typedef _CharT char_type; 02211 typedef _OutIter iter_type; 02212 //@} 02213 02214 /// Numpunct facet id. 02215 static locale::id id; 02216 02217 /** 02218 * @brief Constructor performs initialization. 02219 * 02220 * This is the constructor provided by the standard. 02221 * 02222 * @param refs Passed to the base facet class. 02223 */ 02224 explicit 02225 num_put(size_t __refs = 0) : facet(__refs) { } 02226 02227 /** 02228 * @brief Numeric formatting. 02229 * 02230 * Formats the boolean @a v and inserts it into a stream. It does so 02231 * by calling num_put::do_put(). 02232 * 02233 * If ios_base::boolalpha is set, writes ctype<CharT>::truename() or 02234 * ctype<CharT>::falsename(). Otherwise formats @a v as an int. 02235 * 02236 * @param s Stream to write to. 02237 * @param io Source of locale and flags. 02238 * @param fill Char_type to use for filling. 02239 * @param v Value to format and insert. 02240 * @return Iterator after writing. 02241 */ 02242 iter_type 02243 put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const 02244 { return this->do_put(__s, __f, __fill, __v); } 02245 02246 //@{ 02247 /** 02248 * @brief Numeric formatting. 02249 * 02250 * Formats the integral value @a v and inserts it into a 02251 * stream. It does so by calling num_put::do_put(). 02252 * 02253 * Formatting is affected by the flag settings in @a io. 02254 * 02255 * The basic format is affected by the value of io.flags() & 02256 * ios_base::basefield. If equal to ios_base::oct, formats like the 02257 * printf %o specifier. Else if equal to ios_base::hex, formats like 02258 * %x or %X with ios_base::uppercase unset or set respectively. 02259 * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu 02260 * for unsigned values. Note that if both oct and hex are set, neither 02261 * will take effect. 02262 * 02263 * If ios_base::showpos is set, '+' is output before positive values. 02264 * If ios_base::showbase is set, '0' precedes octal values (except 0) 02265 * and '0[xX]' precedes hex values. 02266 * 02267 * Thousands separators are inserted according to numpunct::grouping() 02268 * and numpunct::thousands_sep(). The decimal point character used is 02269 * numpunct::decimal_point(). 02270 * 02271 * If io.width() is non-zero, enough @a fill characters are inserted to 02272 * make the result at least that wide. If 02273 * (io.flags() & ios_base::adjustfield) == ios_base::left, result is 02274 * padded at the end. If ios_base::internal, then padding occurs 02275 * immediately after either a '+' or '-' or after '0x' or '0X'. 02276 * Otherwise, padding occurs at the beginning. 02277 * 02278 * @param s Stream to write to. 02279 * @param io Source of locale and flags. 02280 * @param fill Char_type to use for filling. 02281 * @param v Value to format and insert. 02282 * @return Iterator after writing. 02283 */ 02284 iter_type 02285 put(iter_type __s, ios_base& __f, char_type __fill, long __v) const 02286 { return this->do_put(__s, __f, __fill, __v); } 02287 02288 iter_type 02289 put(iter_type __s, ios_base& __f, char_type __fill, 02290 unsigned long __v) const 02291 { return this->do_put(__s, __f, __fill, __v); } 02292 02293 #ifdef _GLIBCXX_USE_LONG_LONG 02294 iter_type 02295 put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const 02296 { return this->do_put(__s, __f, __fill, __v); } 02297 02298 iter_type 02299 put(iter_type __s, ios_base& __f, char_type __fill, 02300 unsigned long long __v) const 02301 { return this->do_put(__s, __f, __fill, __v); } 02302 #endif 02303 //@} 02304 02305 //@{ 02306 /** 02307 * @brief Numeric formatting. 02308 * 02309 * Formats the floating point value @a v and inserts it into a stream. 02310 * It does so by calling num_put::do_put(). 02311 * 02312 * Formatting is affected by the flag settings in @a io. 02313 * 02314 * The basic format is affected by the value of io.flags() & 02315 * ios_base::floatfield. If equal to ios_base::fixed, formats like the 02316 * printf %f specifier. Else if equal to ios_base::scientific, formats 02317 * like %e or %E with ios_base::uppercase unset or set respectively. 02318 * Otherwise, formats like %g or %G depending on uppercase. Note that 02319 * if both fixed and scientific are set, the effect will also be like 02320 * %g or %G. 02321 * 02322 * The output precision is given by io.precision(). This precision is 02323 * capped at numeric_limits::digits10 + 2 (different for double and 02324 * long double). The default precision is 6. 02325 * 02326 * If ios_base::showpos is set, '+' is output before positive values. 02327 * If ios_base::showpoint is set, a decimal point will always be 02328 * output. 02329 * 02330 * Thousands separators are inserted according to numpunct::grouping() 02331 * and numpunct::thousands_sep(). The decimal point character used is 02332 * numpunct::decimal_point(). 02333 * 02334 * If io.width() is non-zero, enough @a fill characters are inserted to 02335 * make the result at least that wide. If 02336 * (io.flags() & ios_base::adjustfield) == ios_base::left, result is 02337 * padded at the end. If ios_base::internal, then padding occurs 02338 * immediately after either a '+' or '-' or after '0x' or '0X'. 02339 * Otherwise, padding occurs at the beginning. 02340 * 02341 * @param s Stream to write to. 02342 * @param io Source of locale and flags. 02343 * @param fill Char_type to use for filling. 02344 * @param v Value to format and insert. 02345 * @return Iterator after writing. 02346 */ 02347 iter_type 02348 put(iter_type __s, ios_base& __f, char_type __fill, double __v) const 02349 { return this->do_put(__s, __f, __fill, __v); } 02350 02351 iter_type 02352 put(iter_type __s, ios_base& __f, char_type __fill, 02353 long double __v) const 02354 { return this->do_put(__s, __f, __fill, __v); } 02355 //@} 02356 02357 /** 02358 * @brief Numeric formatting. 02359 * 02360 * Formats the pointer value @a v and inserts it into a stream. It 02361 * does so by calling num_put::do_put(). 02362 * 02363 * This function formats @a v as an unsigned long with ios_base::hex 02364 * and ios_base::showbase set. 02365 * 02366 * @param s Stream to write to. 02367 * @param io Source of locale and flags. 02368 * @param fill Char_type to use for filling. 02369 * @param v Value to format and insert. 02370 * @return Iterator after writing. 02371 */ 02372 iter_type 02373 put(iter_type __s, ios_base& __f, char_type __fill, 02374 const void* __v) const 02375 { return this->do_put(__s, __f, __fill, __v); } 02376 02377 protected: 02378 template<typename _ValueT> 02379 iter_type 02380 _M_insert_float(iter_type, ios_base& __io, char_type __fill, 02381 char __mod, _ValueT __v) const; 02382 02383 void 02384 _M_group_float(const char* __grouping, size_t __grouping_size, 02385 char_type __sep, const char_type* __p, char_type* __new, 02386 char_type* __cs, int& __len) const; 02387 02388 template<typename _ValueT> 02389 iter_type 02390 _M_insert_int(iter_type, ios_base& __io, char_type __fill, 02391 _ValueT __v) const; 02392 02393 void 02394 _M_group_int(const char* __grouping, size_t __grouping_size, 02395 char_type __sep, ios_base& __io, char_type* __new, 02396 char_type* __cs, int& __len) const; 02397 02398 void 02399 _M_pad(char_type __fill, streamsize __w, ios_base& __io, 02400 char_type* __new, const char_type* __cs, int& __len) const; 02401 02402 /// Destructor. 02403 virtual 02404 ~num_put() { }; 02405 02406 //@{ 02407 /** 02408 * @brief Numeric formatting. 02409 * 02410 * These functions do the work of formatting numeric values and 02411 * inserting them into a stream. This function is a hook for derived 02412 * classes to change the value returned. 02413 * 02414 * @param s Stream to write to. 02415 * @param io Source of locale and flags. 02416 * @param fill Char_type to use for filling. 02417 * @param v Value to format and insert. 02418 * @return Iterator after writing. 02419 */ 02420 virtual iter_type 02421 do_put(iter_type, ios_base&, char_type __fill, bool __v) const; 02422 02423 virtual iter_type 02424 do_put(iter_type, ios_base&, char_type __fill, long __v) const; 02425 02426 virtual iter_type 02427 do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; 02428 02429 #ifdef _GLIBCXX_USE_LONG_LONG 02430 virtual iter_type 02431 do_put(iter_type, ios_base&, char_type __fill, long long __v) const; 02432 02433 virtual iter_type 02434 do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; 02435 #endif 02436 02437 virtual iter_type 02438 do_put(iter_type, ios_base&, char_type __fill, double __v) const; 02439 02440 virtual iter_type 02441 do_put(iter_type, ios_base&, char_type __fill, long double __v) const; 02442 02443 virtual iter_type 02444 do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; 02445 //@} 02446 }; 02447 02448 template <typename _CharT, typename _OutIter> 02449 locale::id num_put<_CharT, _OutIter>::id; 02450 02451 02452 /** 02453 * @brief Facet for localized string comparison. 02454 * 02455 * This facet encapsulates the code to compare strings in a localized 02456 * manner. 02457 * 02458 * The collate template uses protected virtual functions to provide 02459 * the actual results. The public accessors forward the call to 02460 * the virtual functions. These virtual functions are hooks for 02461 * developers to implement the behavior they require from the 02462 * collate facet. 02463 */ 02464 template<typename _CharT> 02465 class collate : public locale::facet 02466 { 02467 public: 02468 // Types: 02469 //@{ 02470 /// Public typedefs 02471 typedef _CharT char_type; 02472 typedef basic_string<_CharT> string_type; 02473 //@} 02474 02475 protected: 02476 // Underlying "C" library locale information saved from 02477 // initialization, needed by collate_byname as well. 02478 __c_locale _M_c_locale_collate; 02479 02480 public: 02481 /// Numpunct facet id. 02482 static locale::id id; 02483 02484 /** 02485 * @brief Constructor performs initialization. 02486 * 02487 * This is the constructor provided by the standard. 02488 * 02489 * @param refs Passed to the base facet class. 02490 */ 02491 explicit 02492 collate(size_t __refs = 0) 02493 : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) 02494 { } 02495 02496 /** 02497 * @brief Internal constructor. Not for general use. 02498 * 02499 * This is a constructor for use by the library itself to set up new 02500 * locales. 02501 * 02502 * @param cloc The "C" locale. 02503 * @param refs Passed to the base facet class. 02504 */ 02505 explicit 02506 collate(__c_locale __cloc, size_t __refs = 0) 02507 : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) 02508 { } 02509 02510 /** 02511 * @brief Compare two strings. 02512 * 02513 * This function compares two strings and returns the result by calling 02514 * collate::do_compare(). 02515 * 02516 * @param lo1 Start of string 1. 02517 * @param hi1 End of string 1. 02518 * @param lo2 Start of string 2. 02519 * @param hi2 End of string 2. 02520 * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 02521 */ 02522 int 02523 compare(const _CharT* __lo1, const _CharT* __hi1, 02524 const _CharT* __lo2, const _CharT* __hi2) const 02525 { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } 02526 02527 /** 02528 * @brief Transform string to comparable form. 02529 * 02530 * This function is a wrapper for strxfrm functionality. It takes the 02531 * input string and returns a modified string that can be directly 02532 * compared to other transformed strings. In the "C" locale, this 02533 * function just returns a copy of the input string. In some other 02534 * locales, it may replace two chars with one, change a char for 02535 * another, etc. It does so by returning collate::do_transform(). 02536 * 02537 * @param lo Start of string. 02538 * @param hi End of string. 02539 * @return Transformed string_type. 02540 */ 02541 string_type 02542 transform(const _CharT* __lo, const _CharT* __hi) const 02543 { return this->do_transform(__lo, __hi); } 02544 02545 /** 02546 * @brief Return hash of a string. 02547 * 02548 * This function computes and returns a hash on the input string. It 02549 * does so by returning collate::do_hash(). 02550 * 02551 * @param lo Start of string. 02552 * @param hi End of string. 02553 * @return Hash value. 02554 */ 02555 long 02556 hash(const _CharT* __lo, const _CharT* __hi) const 02557 { return this->do_hash(__lo, __hi); } 02558 02559 // Used to abstract out _CharT bits in virtual member functions, below. 02560 int 02561 _M_compare(const _CharT*, const _CharT*) const; 02562 02563 size_t 02564 _M_transform(_CharT*, const _CharT*, size_t) const; 02565 02566 protected: 02567 /// Destructor. 02568 virtual 02569 ~collate() 02570 { _S_destroy_c_locale(_M_c_locale_collate); } 02571 02572 /** 02573 * @brief Compare two strings. 02574 * 02575 * This function is a hook for derived classes to change the value 02576 * returned. @see compare(). 02577 * 02578 * @param lo1 Start of string 1. 02579 * @param hi1 End of string 1. 02580 * @param lo2 Start of string 2. 02581 * @param hi2 End of string 2. 02582 * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 02583 */ 02584 virtual int 02585 do_compare(const _CharT* __lo1, const _CharT* __hi1, 02586 const _CharT* __lo2, const _CharT* __hi2) const; 02587 02588 /** 02589 * @brief Transform string to comparable form. 02590 * 02591 * This function is a hook for derived classes to change the value 02592 * returned. 02593 * 02594 * @param lo1 Start of string 1. 02595 * @param hi1 End of string 1. 02596 * @param lo2 Start of string 2. 02597 * @param hi2 End of string 2. 02598 * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 02599 */ 02600 virtual string_type 02601 do_transform(const _CharT* __lo, const _CharT* __hi) const; 02602 02603 /** 02604 * @brief Return hash of a string. 02605 * 02606 * This function computes and returns a hash on the input string. This 02607 * function is a hook for derived classes to change the value returned. 02608 * 02609 * @param lo Start of string. 02610 * @param hi End of string. 02611 * @return Hash value. 02612 */ 02613 virtual long 02614 do_hash(const _CharT* __lo, const _CharT* __hi) const; 02615 }; 02616 02617 template<typename _CharT> 02618 locale::id collate<_CharT>::id; 02619 02620 // Specializations. 02621 template<> 02622 int 02623 collate<char>::_M_compare(const char*, const char*) const; 02624 02625 template<> 02626 size_t 02627 collate<char>::_M_transform(char*, const char*, size_t) const; 02628 02629 #ifdef _GLIBCXX_USE_WCHAR_T 02630 template<> 02631 int 02632 collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const; 02633 02634 template<> 02635 size_t 02636 collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const; 02637 #endif 02638 02639 template<typename _CharT> 02640 class collate_byname : public collate<_CharT> 02641 { 02642 public: 02643 //@{ 02644 /// Public typedefs 02645 typedef _CharT char_type; 02646 typedef basic_string<_CharT> string_type; 02647 //@} 02648 02649 explicit 02650 collate_byname(const char* __s, size_t __refs = 0) 02651 : collate<_CharT>(__refs) 02652 { 02653 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 02654 { 02655 this->_S_destroy_c_locale(this->_M_c_locale_collate); 02656 this->_S_create_c_locale(this->_M_c_locale_collate, __s); 02657 } 02658 } 02659 02660 protected: 02661 virtual 02662 ~collate_byname() { } 02663 }; 02664 02665 02666 /** 02667 * @brief Time format ordering data. 02668 * 02669 * This class provides an enum representing different orderings of day, 02670 * month, and year. 02671 */ 02672 class time_base 02673 { 02674 public: 02675 enum dateorder { no_order, dmy, mdy, ymd, ydm }; 02676 }; 02677 02678 template<typename _CharT> 02679 struct __timepunct_cache : public locale::facet 02680 { 02681 // List of all known timezones, with GMT first. 02682 static const _CharT* _S_timezones[14]; 02683 02684 const _CharT* _M_date_format; 02685 const _CharT* _M_date_era_format; 02686 const _CharT* _M_time_format; 02687 const _CharT* _M_time_era_format; 02688 const _CharT* _M_date_time_format; 02689 const _CharT* _M_date_time_era_format; 02690 const _CharT* _M_am; 02691 const _CharT* _M_pm; 02692 const _CharT* _M_am_pm_format; 02693 02694 // Day names, starting with "C"'s Sunday. 02695 const _CharT* _M_day1; 02696 const _CharT* _M_day2; 02697 const _CharT* _M_day3; 02698 const _CharT* _M_day4; 02699 const _CharT* _M_day5; 02700 const _CharT* _M_day6; 02701 const _CharT* _M_day7; 02702 02703 // Abbreviated day names, starting with "C"'s Sun. 02704 const _CharT* _M_aday1; 02705 const _CharT* _M_aday2; 02706 const _CharT* _M_aday3; 02707 const _CharT* _M_aday4; 02708 const _CharT* _M_aday5; 02709 const _CharT* _M_aday6; 02710 const _CharT* _M_aday7; 02711 02712 // Month names, starting with "C"'s January. 02713 const _CharT* _M_month01; 02714 const _CharT* _M_month02; 02715 const _CharT* _M_month03; 02716 const _CharT* _M_month04; 02717 const _CharT* _M_month05; 02718 const _CharT* _M_month06; 02719 const _CharT* _M_month07; 02720 const _CharT* _M_month08; 02721 const _CharT* _M_month09; 02722 const _CharT* _M_month10; 02723 const _CharT* _M_month11; 02724 const _CharT* _M_month12; 02725 02726 // Abbreviated month names, starting with "C"'s Jan. 02727 const _CharT* _M_amonth01; 02728 const _CharT* _M_amonth02; 02729 const _CharT* _M_amonth03; 02730 const _CharT* _M_amonth04; 02731 const _CharT* _M_amonth05; 02732 const _CharT* _M_amonth06; 02733 const _CharT* _M_amonth07; 02734 const _CharT* _M_amonth08; 02735 const _CharT* _M_amonth09; 02736 const _CharT* _M_amonth10; 02737 const _CharT* _M_amonth11; 02738 const _CharT* _M_amonth12; 02739 02740 bool _M_allocated; 02741 02742 __timepunct_cache(size_t __refs = 0) : facet(__refs), 02743 _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), 02744 _M_time_era_format(NULL), _M_date_time_format(NULL), 02745 _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), 02746 _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), 02747 _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), 02748 _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), 02749 _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), 02750 _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), 02751 _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), 02752 _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), 02753 _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), 02754 _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), 02755 _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), 02756 _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) 02757 { } 02758 02759 ~__timepunct_cache(); 02760 02761 void 02762 _M_cache(const locale& __loc); 02763 02764 private: 02765 __timepunct_cache& 02766 operator=(const __timepunct_cache&); 02767 02768 explicit 02769 __timepunct_cache(const __timepunct_cache&); 02770 }; 02771 02772 template<typename _CharT> 02773 __timepunct_cache<_CharT>::~__timepunct_cache() 02774 { 02775 if (_M_allocated) 02776 { 02777 // Unused. 02778 } 02779 } 02780 02781 // Specializations. 02782 template<> 02783 const char* 02784 __timepunct_cache<char>::_S_timezones[14]; 02785 02786 #ifdef _GLIBCXX_USE_WCHAR_T 02787 template<> 02788 const wchar_t* 02789 __timepunct_cache<wchar_t>::_S_timezones[14]; 02790 #endif 02791 02792 // Generic. 02793 template<typename _CharT> 02794 const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; 02795 02796 template<typename _CharT> 02797 class __timepunct : public locale::facet 02798 { 02799 public: 02800 // Types: 02801 typedef _CharT __char_type; 02802 typedef basic_string<_CharT> __string_type; 02803 typedef __timepunct_cache<_CharT> __cache_type; 02804 02805 protected: 02806 __cache_type* _M_data; 02807 __c_locale _M_c_locale_timepunct; 02808 const char* _M_name_timepunct; 02809 02810 public: 02811 /// Numpunct facet id. 02812 static locale::id id; 02813 02814 explicit 02815 __timepunct(size_t __refs = 0); 02816 02817 explicit 02818 __timepunct(__cache_type* __cache, size_t __refs = 0); 02819 02820 /** 02821 * @brief Internal constructor. Not for general use. 02822 * 02823 * This is a constructor for use by the library itself to set up new 02824 * locales. 02825 * 02826 * @param cloc The "C" locale. 02827 * @param s The name of a locale. 02828 * @param refs Passed to the base facet class. 02829 */ 02830 explicit 02831 __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); 02832 02833 void 02834 _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, 02835 const tm* __tm) const; 02836 02837 void 02838 _M_date_formats(const _CharT** __date) const 02839 { 02840 // Always have default first. 02841 __date[0] = _M_data->_M_date_format; 02842 __date[1] = _M_data->_M_date_era_format; 02843 } 02844 02845 void 02846 _M_time_formats(const _CharT** __time) const 02847 { 02848 // Always have default first. 02849 __time[0] = _M_data->_M_time_format; 02850 __time[1] = _M_data->_M_time_era_format; 02851 } 02852 02853 void 02854 _M_date_time_formats(const _CharT** __dt) const 02855 { 02856 // Always have default first. 02857 __dt[0] = _M_data->_M_date_time_format; 02858 __dt[1] = _M_data->_M_date_time_era_format; 02859 } 02860 02861 void 02862 _M_am_pm_format(const _CharT* __ampm) const 02863 { __ampm = _M_data->_M_am_pm_format; } 02864 02865 void 02866 _M_am_pm(const _CharT** __ampm) const 02867 { 02868 __ampm[0] = _M_data->_M_am; 02869 __ampm[1] = _M_data->_M_pm; 02870 } 02871 02872 void 02873 _M_days(const _CharT** __days) const 02874 { 02875 __days[0] = _M_data->_M_day1; 02876 __days[1] = _M_data->_M_day2; 02877 __days[2] = _M_data->_M_day3; 02878 __days[3] = _M_data->_M_day4; 02879 __days[4] = _M_data->_M_day5; 02880 __days[5] = _M_data->_M_day6; 02881 __days[6] = _M_data->_M_day7; 02882 } 02883 02884 void 02885 _M_days_abbreviated(const _CharT** __days) const 02886 { 02887 __days[0] = _M_data->_M_aday1; 02888 __days[1] = _M_data->_M_aday2; 02889 __days[2] = _M_data->_M_aday3; 02890 __days[3] = _M_data->_M_aday4; 02891 __days[4] = _M_data->_M_aday5; 02892 __days[5] = _M_data->_M_aday6; 02893 __days[6] = _M_data->_M_aday7; 02894 } 02895 02896 void 02897 _M_months(const _CharT** __months) const 02898 { 02899 __months[0] = _M_data->_M_month01; 02900 __months[1] = _M_data->_M_month02; 02901 __months[2] = _M_data->_M_month03; 02902 __months[3] = _M_data->_M_month04; 02903 __months[4] = _M_data->_M_month05; 02904 __months[5] = _M_data->_M_month06; 02905 __months[6] = _M_data->_M_month07; 02906 __months[7] = _M_data->_M_month08; 02907 __months[8] = _M_data->_M_month09; 02908 __months[9] = _M_data->_M_month10; 02909 __months[10] = _M_data->_M_month11; 02910 __months[11] = _M_data->_M_month12; 02911 } 02912 02913 void 02914 _M_months_abbreviated(const _CharT** __months) const 02915 { 02916 __months[0] = _M_data->_M_amonth01; 02917 __months[1] = _M_data->_M_amonth02; 02918 __months[2] = _M_data->_M_amonth03; 02919 __months[3] = _M_data->_M_amonth04; 02920 __months[4] = _M_data->_M_amonth05; 02921 __months[5] = _M_data->_M_amonth06; 02922 __months[6] = _M_data->_M_amonth07; 02923 __months[7] = _M_data->_M_amonth08; 02924 __months[8] = _M_data->_M_amonth09; 02925 __months[9] = _M_data->_M_amonth10; 02926 __months[10] = _M_data->_M_amonth11; 02927 __months[11] = _M_data->_M_amonth12; 02928 } 02929 02930 protected: 02931 virtual 02932 ~__timepunct(); 02933 02934 // For use at construction time only. 02935 void 02936 _M_initialize_timepunct(__c_locale __cloc = NULL); 02937 }; 02938 02939 template<typename _CharT> 02940 locale::id __timepunct<_CharT>::id; 02941 02942 // Specializations. 02943 template<> 02944 void 02945 __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc); 02946 02947 template<> 02948 void 02949 __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const; 02950 02951 #ifdef _GLIBCXX_USE_WCHAR_T 02952 template<> 02953 void 02954 __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc); 02955 02956 template<> 02957 void 02958 __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*, 02959 const tm*) const; 02960 #endif 02961 02962 // Include host and configuration specific timepunct functions. 02963 #include <bits/time_members.h> 02964 02965 /** 02966 * @brief Facet for parsing dates and times. 02967 * 02968 * This facet encapsulates the code to parse and return a date or 02969 * time from a string. It is used by the istream numeric 02970 * extraction operators. 02971 * 02972 * The time_get template uses protected virtual functions to provide the 02973 * actual results. The public accessors forward the call to the virtual 02974 * functions. These virtual functions are hooks for developers to 02975 * implement the behavior they require from the time_get facet. 02976 */ 02977 template<typename _CharT, typename _InIter> 02978 class time_get : public locale::facet, public time_base 02979 { 02980 public: 02981 // Types: 02982 //@{ 02983 /// Public typedefs 02984 typedef _CharT char_type; 02985 typedef _InIter iter_type; 02986 //@} 02987 typedef basic_string<_CharT> __string_type; 02988 02989 /// Numpunct facet id. 02990 static locale::id id; 02991 02992 /** 02993 * @brief Constructor performs initialization. 02994 * 02995 * This is the constructor provided by the standard. 02996 * 02997 * @param refs Passed to the base facet class. 02998 */ 02999 explicit 03000 time_get(size_t __refs = 0) 03001 : facet (__refs) { } 03002 03003 /** 03004 * @brief Return preferred order of month, day, and year. 03005 * 03006 * This function returns an enum from timebase::dateorder giving the 03007 * preferred ordering if the format "x" given to time_put::put() only 03008 * uses month, day, and year. If the format "x" for the associated 03009 * locale uses other fields, this function returns 03010 * timebase::dateorder::noorder. 03011 * 03012 * NOTE: The library always returns noorder at the moment. 03013 * 03014 * @return A member of timebase::dateorder. 03015 */ 03016 dateorder 03017 date_order() const 03018 { return this->do_date_order(); } 03019 03020 /** 03021 * @brief Parse input time string. 03022 * 03023 * This function parses a time according to the format "x" and puts the 03024 * results into a user-supplied struct tm. The result is returned by 03025 * calling time_get::do_get_time(). 03026 * 03027 * If there is a valid time string according to format "x", @a tm will 03028 * be filled in accordingly and the returned iterator will point to the 03029 * first character beyond the time string. If an error occurs before 03030 * the end, err |= ios_base::failbit. If parsing reads all the 03031 * characters, err |= ios_base::eofbit. 03032 * 03033 * @param beg Start of string to parse. 03034 * @param end End of string to parse. 03035 * @param io Source of the locale. 03036 * @param err Error flags to set. 03037 * @param tm Pointer to struct tm to fill in. 03038 * @return Iterator to first char beyond time string. 03039 */ 03040 iter_type 03041 get_time(iter_type __beg, iter_type __end, ios_base& __io, 03042 ios_base::iostate& __err, tm* __tm) const 03043 { return this->do_get_time(__beg, __end, __io, __err, __tm); } 03044 03045 /** 03046 * @brief Parse input date string. 03047 * 03048 * This function parses a date according to the format "X" and puts the 03049 * results into a user-supplied struct tm. The result is returned by 03050 * calling time_get::do_get_date(). 03051 * 03052 * If there is a valid date string according to format "X", @a tm will 03053 * be filled in accordingly and the returned iterator will point to the 03054 * first character beyond the date string. If an error occurs before 03055 * the end, err |= ios_base::failbit. If parsing reads all the 03056 * characters, err |= ios_base::eofbit. 03057 * 03058 * @param beg Start of string to parse. 03059 * @param end End of string to parse. 03060 * @param io Source of the locale. 03061 * @param err Error flags to set. 03062 * @param tm Pointer to struct tm to fill in. 03063 * @return Iterator to first char beyond date string. 03064 */ 03065 iter_type 03066 get_date(iter_type __beg, iter_type __end, ios_base& __io, 03067 ios_base::iostate& __err, tm* __tm) const 03068 { return this->do_get_date(__beg, __end, __io, __err, __tm); } 03069 03070 /** 03071 * @brief Parse input weekday string. 03072 * 03073 * This function parses a weekday name and puts the results into a 03074 * user-supplied struct tm. The result is returned by calling 03075 * time_get::do_get_weekday(). 03076 * 03077 * Parsing starts by parsing an abbreviated weekday name. If a valid 03078 * abbreviation is followed by a character that would lead to the full 03079 * weekday name, parsing continues until the full name is found or an 03080 * error occurs. Otherwise parsing finishes at the end of the 03081 * abbreviated name. 03082 * 03083 * If an error occurs before the end, err |= ios_base::failbit. If 03084 * parsing reads all the characters, err |= ios_base::eofbit. 03085 * 03086 * @param beg Start of string to parse. 03087 * @param end End of string to parse. 03088 * @param io Source of the locale. 03089 * @param err Error flags to set. 03090 * @param tm Pointer to struct tm to fill in. 03091 * @return Iterator to first char beyond weekday name. 03092 */ 03093 iter_type 03094 get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 03095 ios_base::iostate& __err, tm* __tm) const 03096 { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } 03097 03098 /** 03099 * @brief Parse input month string. 03100 * 03101 * This function parses a month name and puts the results into a 03102 * user-supplied struct tm. The result is returned by calling 03103 * time_get::do_get_monthname(). 03104 * 03105 * Parsing starts by parsing an abbreviated month name. If a valid 03106 * abbreviation is followed by a character that would lead to the full 03107 * month name, parsing continues until the full name is found or an 03108 * error occurs. Otherwise parsing finishes at the end of the 03109 * abbreviated name. 03110 * 03111 * If an error occurs before the end, err |= ios_base::failbit. If 03112 * parsing reads all the characters, err |= 03113 * ios_base::eofbit. 03114 * 03115 * @param beg Start of string to parse. 03116 * @param end End of string to parse. 03117 * @param io Source of the locale. 03118 * @param err Error flags to set. 03119 * @param tm Pointer to struct tm to fill in. 03120 * @return Iterator to first char beyond month name. 03121 */ 03122 iter_type 03123 get_monthname(iter_type __beg, iter_type __end, ios_base& __io, 03124 ios_base::iostate& __err, tm* __tm) const 03125 { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } 03126 03127 /** 03128 * @brief Parse input year string. 03129 * 03130 * This function reads up to 4 characters to parse a year string and 03131 * puts the results into a user-supplied struct tm. The result is 03132 * returned by calling time_get::do_get_year(). 03133 * 03134 * 4 consecutive digits are interpreted as a full year. If there are 03135 * exactly 2 consecutive digits, the library interprets this as the 03136 * number of years since 1900. 03137 * 03138 * If an error occurs before the end, err |= ios_base::failbit. If 03139 * parsing reads all the characters, err |= ios_base::eofbit. 03140 * 03141 * @param beg Start of string to parse. 03142 * @param end End of string to parse. 03143 * @param io Source of the locale. 03144 * @param err Error flags to set. 03145 * @param tm Pointer to struct tm to fill in. 03146 * @return Iterator to first char beyond year. 03147 */ 03148 iter_type 03149 get_year(iter_type __beg, iter_type __end, ios_base& __io, 03150 ios_base::iostate& __err, tm* __tm) const 03151 { return this->do_get_year(__beg, __end, __io, __err, __tm); } 03152 03153 protected: 03154 /// Destructor. 03155 virtual 03156 ~time_get() { } 03157 03158 /** 03159 * @brief Return preferred order of month, day, and year. 03160 * 03161 * This function returns an enum from timebase::dateorder giving the 03162 * preferred ordering if the format "x" given to time_put::put() only 03163 * uses month, day, and year. This function is a hook for derived 03164 * classes to change the value returned. 03165 * 03166 * @return A member of timebase::dateorder. 03167 */ 03168 virtual dateorder 03169 do_date_order() const; 03170 03171 /** 03172 * @brief Parse input time string. 03173 * 03174 * This function parses a time according to the format "x" and puts the 03175 * results into a user-supplied struct tm. This function is a hook for 03176 * derived classes to change the value returned. @see get_time() for 03177 * details. 03178 * 03179 * @param beg Start of string to parse. 03180 * @param end End of string to parse. 03181 * @param io Source of the locale. 03182 * @param err Error flags to set. 03183 * @param tm Pointer to struct tm to fill in. 03184 * @return Iterator to first char beyond time string. 03185 */ 03186 virtual iter_type 03187 do_get_time(iter_type __beg, iter_type __end, ios_base& __io, 03188 ios_base::iostate& __err, tm* __tm) const; 03189 03190 /** 03191 * @brief Parse input date string. 03192 * 03193 * This function parses a date according to the format "X" and puts the 03194 * results into a user-supplied struct tm. This function is a hook for 03195 * derived classes to change the value returned. @see get_date() for 03196 * details. 03197 * 03198 * @param beg Start of string to parse. 03199 * @param end End of string to parse. 03200 * @param io Source of the locale. 03201 * @param err Error flags to set. 03202 * @param tm Pointer to struct tm to fill in. 03203 * @return Iterator to first char beyond date string. 03204 */ 03205 virtual iter_type 03206 do_get_date(iter_type __beg, iter_type __end, ios_base& __io, 03207 ios_base::iostate& __err, tm* __tm) const; 03208 03209 /** 03210 * @brief Parse input weekday string. 03211 * 03212 * This function parses a weekday name and puts the results into a 03213 * user-supplied struct tm. This function is a hook for derived 03214 * classes to change the value returned. @see get_weekday() for 03215 * details. 03216 * 03217 * @param beg Start of string to parse. 03218 * @param end End of string to parse. 03219 * @param io Source of the locale. 03220 * @param err Error flags to set. 03221 * @param tm Pointer to struct tm to fill in. 03222 * @return Iterator to first char beyond weekday name. 03223 */ 03224 virtual iter_type 03225 do_get_weekday(iter_type __beg, iter_type __end, ios_base&, 03226 ios_base::iostate& __err, tm* __tm) const; 03227 03228 /** 03229 * @brief Parse input month string. 03230 * 03231 * This function parses a month name and puts the results into a 03232 * user-supplied struct tm. This function is a hook for derived 03233 * classes to change the value returned. @see get_monthname() for 03234 * details. 03235 * 03236 * @param beg Start of string to parse. 03237 * @param end End of string to parse. 03238 * @param io Source of the locale. 03239 * @param err Error flags to set. 03240 * @param tm Pointer to struct tm to fill in. 03241 * @return Iterator to first char beyond month name. 03242 */ 03243 virtual iter_type 03244 do_get_monthname(iter_type __beg, iter_type __end, ios_base&, 03245 ios_base::iostate& __err, tm* __tm) const; 03246 03247 /** 03248 * @brief Parse input year string. 03249 * 03250 * This function reads up to 4 characters to parse a year string and 03251 * puts the results into a user-supplied struct tm. This function is a 03252 * hook for derived classes to change the value returned. @see 03253 * get_year() for details. 03254 * 03255 * @param beg Start of string to parse. 03256 * @param end End of string to parse. 03257 * @param io Source of the locale. 03258 * @param err Error flags to set. 03259 * @param tm Pointer to struct tm to fill in. 03260 * @return Iterator to first char beyond year. 03261 */ 03262 virtual iter_type 03263 do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 03264 ios_base::iostate& __err, tm* __tm) const; 03265 03266 // Extract numeric component of length __len. 03267 iter_type 03268 _M_extract_num(iter_type __beg, iter_type __end, int& __member, 03269 int __min, int __max, size_t __len, 03270 ios_base& __io, ios_base::iostate& __err) const; 03271 03272 // Extract day or month name, or any unique array of string 03273 // literals in a const _CharT* array. 03274 iter_type 03275 _M_extract_name(iter_type __beg, iter_type __end, int& __member, 03276 const _CharT** __names, size_t __indexlen, 03277 ios_base& __io, ios_base::iostate& __err) const; 03278 03279 // Extract on a component-by-component basis, via __format argument. 03280 iter_type 03281 _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 03282 ios_base::iostate& __err, tm* __tm, 03283 const _CharT* __format) const; 03284 }; 03285 03286 template<typename _CharT, typename _InIter> 03287 locale::id time_get<_CharT, _InIter>::id; 03288 03289 template<typename _CharT, typename _InIter> 03290 class time_get_byname : public time_get<_CharT, _InIter> 03291 { 03292 public: 03293 // Types: 03294 typedef _CharT char_type; 03295 typedef _InIter iter_type; 03296 03297 explicit 03298 time_get_byname(const char*, size_t __refs = 0) 03299 : time_get<_CharT, _InIter>(__refs) { } 03300 03301 protected: 03302 virtual 03303 ~time_get_byname() { } 03304 }; 03305 03306 /** 03307 * @brief Facet for outputting dates and times. 03308 * 03309 * This facet encapsulates the code to format and output dates and times 03310 * according to formats used by strftime(). 03311 * 03312 * The time_put template uses protected virtual functions to provide the 03313 * actual results. The public accessors forward the call to the virtual 03314 * functions. These virtual functions are hooks for developers to 03315 * implement the behavior they require from the time_put facet. 03316 */ 03317 template<typename _CharT, typename _OutIter> 03318 class time_put : public locale::facet 03319 { 03320 public: 03321 // Types: 03322 //@{ 03323 /// Public typedefs 03324 typedef _CharT char_type; 03325 typedef _OutIter iter_type; 03326 //@} 03327 03328 /// Numpunct facet id. 03329 static locale::id id; 03330 03331 /** 03332 * @brief Constructor performs initialization. 03333 * 03334 * This is the constructor provided by the standard. 03335 * 03336 * @param refs Passed to the base facet class. 03337 */ 03338 explicit 03339 time_put(size_t __refs = 0) 03340 : facet(__refs) { } 03341 03342 /** 03343 * @brief Format and output a time or date. 03344 * 03345 * This function formats the data in struct tm according to the 03346 * provided format string. The format string is interpreted as by 03347 * strftime(). 03348 * 03349 * @param s The stream to write to. 03350 * @param io Source of locale. 03351 * @param fill char_type to use for padding. 03352 * @param tm Struct tm with date and time info to format. 03353 * @param beg Start of format string. 03354 * @param end End of format string. 03355 * @return Iterator after writing. 03356 */ 03357 iter_type 03358 put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 03359 const _CharT* __beg, const _CharT* __end) const; 03360 03361 /** 03362 * @brief Format and output a time or date. 03363 * 03364 * This function formats the data in struct tm according to the 03365 * provided format char and optional modifier. The format and modifier 03366 * are interpreted as by strftime(). It does so by returning 03367 * time_put::do_put(). 03368 * 03369 * @param s The stream to write to. 03370 * @param io Source of locale. 03371 * @param fill char_type to use for padding. 03372 * @param tm Struct tm with date and time info to format. 03373 * @param format Format char. 03374 * @param mod Optional modifier char. 03375 * @return Iterator after writing. 03376 */ 03377 iter_type 03378 put(iter_type __s, ios_base& __io, char_type __fill, 03379 const tm* __tm, char __format, char __mod = 0) const 03380 { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } 03381 03382 protected: 03383 /// Destructor. 03384 virtual 03385 ~time_put() 03386 { } 03387 03388 /** 03389 * @brief Format and output a time or date. 03390 * 03391 * This function formats the data in struct tm according to the 03392 * provided format char and optional modifier. This function is a hook 03393 * for derived classes to change the value returned. @see put() for 03394 * more details. 03395 * 03396 * @param s The stream to write to. 03397 * @param io Source of locale. 03398 * @param fill char_type to use for padding. 03399 * @param tm Struct tm with date and time info to format. 03400 * @param format Format char. 03401 * @param mod Optional modifier char. 03402 * @return Iterator after writing. 03403 */ 03404 virtual iter_type 03405 do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 03406 char __format, char __mod) const; 03407 }; 03408 03409 template<typename _CharT, typename _OutIter> 03410 locale::id time_put<_CharT, _OutIter>::id; 03411 03412 template<typename _CharT, typename _OutIter> 03413 class time_put_byname : public time_put<_CharT, _OutIter> 03414 { 03415 public: 03416 // Types: 03417 typedef _CharT char_type; 03418 typedef _OutIter iter_type; 03419 03420 explicit 03421 time_put_byname(const char*, size_t __refs = 0) 03422 : time_put<_CharT, _OutIter>(__refs) 03423 { }; 03424 03425 protected: 03426 virtual 03427 ~time_put_byname() { } 03428 }; 03429 03430 03431 /** 03432 * @brief Money format ordering data. 03433 * 03434 * This class contains an ordered array of 4 fields to represent the 03435 * pattern for formatting a money amount. Each field may contain one entry 03436 * from the part enum. symbol, sign, and value must be present and the 03437 * remaining field must contain either none or space. @see 03438 * moneypunct::pos_format() and moneypunct::neg_format() for details of how 03439 * these fields are interpreted. 03440 */ 03441 class money_base 03442 { 03443 public: 03444 enum part { none, space, symbol, sign, value }; 03445 struct pattern { char field[4]; }; 03446 03447 static const pattern _S_default_pattern; 03448 03449 enum 03450 { 03451 _S_minus, 03452 _S_zero, 03453 _S_end = 11 03454 }; 03455 03456 // String literal of acceptable (narrow) input/output, for 03457 // money_get/money_put. "-0123456789" 03458 static const char* _S_atoms; 03459 03460 // Construct and return valid pattern consisting of some combination of: 03461 // space none symbol sign value 03462 static pattern 03463 _S_construct_pattern(char __precedes, char __space, char __posn); 03464 }; 03465 03466 template<typename _CharT, bool _Intl> 03467 struct __moneypunct_cache : public locale::facet 03468 { 03469 const char* _M_grouping; 03470 size_t _M_grouping_size; 03471 bool _M_use_grouping; 03472 _CharT _M_decimal_point; 03473 _CharT _M_thousands_sep; 03474 const _CharT* _M_curr_symbol; 03475 size_t _M_curr_symbol_size; 03476 const _CharT* _M_positive_sign; 03477 size_t _M_positive_sign_size; 03478 const _CharT* _M_negative_sign; 03479 size_t _M_negative_sign_size; 03480 int _M_frac_digits; 03481 money_base::pattern _M_pos_format; 03482 money_base::pattern _M_neg_format; 03483 03484 // A list of valid numeric literals for input and output: in the standard 03485 // "C" locale, this is "-0123456789". This array contains the chars after 03486 // having been passed through the current locale's ctype<_CharT>.widen(). 03487 _CharT _M_atoms[money_base::_S_end]; 03488 03489 bool _M_allocated; 03490 03491 __moneypunct_cache(size_t __refs = 0) : facet(__refs), 03492 _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), 03493 _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), 03494 _M_curr_symbol(NULL), _M_curr_symbol_size(0), 03495 _M_positive_sign(NULL), _M_positive_sign_size(0), 03496 _M_negative_sign(NULL), _M_negative_sign_size(0), 03497 _M_frac_digits(0), 03498 _M_pos_format(money_base::pattern()), 03499 _M_neg_format(money_base::pattern()), _M_allocated(false) 03500 { } 03501 03502 ~__moneypunct_cache(); 03503 03504 void 03505 _M_cache(const locale& __loc); 03506 03507 private: 03508 __moneypunct_cache& 03509 operator=(const __moneypunct_cache&); 03510 03511 explicit 03512 __moneypunct_cache(const __moneypunct_cache&); 03513 }; 03514 03515 template<typename _CharT, bool _Intl> 03516 __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() 03517 { 03518 if (_M_allocated) 03519 { 03520 delete [] _M_grouping; 03521 delete [] _M_curr_symbol; 03522 delete [] _M_positive_sign; 03523 delete [] _M_negative_sign; 03524 } 03525 } 03526 03527 /** 03528 * @brief Facet for formatting data for money amounts. 03529 * 03530 * This facet encapsulates the punctuation, grouping and other formatting 03531 * features of money amount string representations. 03532 */ 03533 template<typename _CharT, bool _Intl> 03534 class moneypunct : public locale::facet, public money_base 03535 { 03536 public: 03537 // Types: 03538 //@{ 03539 /// Public typedefs 03540 typedef _CharT char_type; 03541 typedef basic_string<_CharT> string_type; 03542 //@} 03543 typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 03544 03545 private: 03546 __cache_type* _M_data; 03547 03548 public: 03549 /// This value is provided by the standard, but no reason for its 03550 /// existence. 03551 static const bool intl = _Intl; 03552 /// Numpunct facet id. 03553 static locale::id id; 03554 03555 /** 03556 * @brief Constructor performs initialization. 03557 * 03558 * This is the constructor provided by the standard. 03559 * 03560 * @param refs Passed to the base facet class. 03561 */ 03562 explicit 03563 moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) 03564 { _M_initialize_moneypunct(); } 03565 03566 /** 03567 * @brief Constructor performs initialization. 03568 * 03569 * This is an internal constructor. 03570 * 03571 * @param cache Cache for optimization. 03572 * @param refs Passed to the base facet class. 03573 */ 03574 explicit 03575 moneypunct(__cache_type* __cache, size_t __refs = 0) 03576 : facet(__refs), _M_data(__cache) 03577 { _M_initialize_moneypunct(); } 03578 03579 /** 03580 * @brief Internal constructor. Not for general use. 03581 * 03582 * This is a constructor for use by the library itself to set up new 03583 * locales. 03584 * 03585 * @param cloc The "C" locale. 03586 * @param s The name of a locale. 03587 * @param refs Passed to the base facet class. 03588 */ 03589 explicit 03590 moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) 03591 : facet(__refs), _M_data(NULL) 03592 { _M_initialize_moneypunct(__cloc, __s); } 03593 03594 /** 03595 * @brief Return decimal point character. 03596 * 03597 * This function returns a char_type to use as a decimal point. It 03598 * does so by returning returning 03599 * moneypunct<char_type>::do_decimal_point(). 03600 * 03601 * @return @a char_type representing a decimal point. 03602 */ 03603 char_type 03604 decimal_point() const 03605 { return this->do_decimal_point(); } 03606 03607 /** 03608 * @brief Return thousands separator character. 03609 * 03610 * This function returns a char_type to use as a thousands 03611 * separator. It does so by returning returning 03612 * moneypunct<char_type>::do_thousands_sep(). 03613 * 03614 * @return char_type representing a thousands separator. 03615 */ 03616 char_type 03617 thousands_sep() const 03618 { return this->do_thousands_sep(); } 03619 03620 /** 03621 * @brief Return grouping specification. 03622 * 03623 * This function returns a string representing groupings for the 03624 * integer part of an amount. Groupings indicate where thousands 03625 * separators should be inserted. 03626 * 03627 * Each char in the return string is interpret as an integer rather 03628 * than a character. These numbers represent the number of digits in a 03629 * group. The first char in the string represents the number of digits 03630 * in the least significant group. If a char is negative, it indicates 03631 * an unlimited number of digits for the group. If more chars from the 03632 * string are required to group a number, the last char is used 03633 * repeatedly. 03634 * 03635 * For example, if the grouping() returns "\003\002" and is applied to 03636 * the number 123456789, this corresponds to 12,34,56,789. Note that 03637 * if the string was "32", this would put more than 50 digits into the 03638 * least significant group if the character set is ASCII. 03639 * 03640 * The string is returned by calling 03641 * moneypunct<char_type>::do_grouping(). 03642 * 03643 * @return string representing grouping specification. 03644 */ 03645 string 03646 grouping() const 03647 { return this->do_grouping(); } 03648 03649 /** 03650 * @brief Return currency symbol string. 03651 * 03652 * This function returns a string_type to use as a currency symbol. It 03653 * does so by returning returning 03654 * moneypunct<char_type>::do_curr_symbol(). 03655 * 03656 * @return @a string_type representing a currency symbol. 03657 */ 03658 string_type 03659 curr_symbol() const 03660 { return this->do_curr_symbol(); } 03661 03662 /** 03663 * @brief Return positive sign string. 03664 * 03665 * This function returns a string_type to use as a sign for positive 03666 * amounts. It does so by returning returning 03667 * moneypunct<char_type>::do_positive_sign(). 03668 * 03669 * If the return value contains more than one character, the first 03670 * character appears in the position indicated by pos_format() and the 03671 * remainder appear at the end of the formatted string. 03672 * 03673 * @return @a string_type representing a positive sign. 03674 */ 03675 string_type 03676 positive_sign() const 03677 { return this->do_positive_sign(); } 03678 03679 /** 03680 * @brief Return negative sign string. 03681 * 03682 * This function returns a string_type to use as a sign for negative 03683 * amounts. It does so by returning returning 03684 * moneypunct<char_type>::do_negative_sign(). 03685 * 03686 * If the return value contains more than one character, the first 03687 * character appears in the position indicated by neg_format() and the 03688 * remainder appear at the end of the formatted string. 03689 * 03690 * @return @a string_type representing a negative sign. 03691 */ 03692 string_type 03693 negative_sign() const 03694 { return this->do_negative_sign(); } 03695 03696 /** 03697 * @brief Return number of digits in fraction. 03698 * 03699 * This function returns the exact number of digits that make up the 03700 * fractional part of a money amount. It does so by returning 03701 * returning moneypunct<char_type>::do_frac_digits(). 03702 * 03703 * The fractional part of a money amount is optional. But if it is 03704 * present, there must be frac_digits() digits. 03705 * 03706 * @return Number of digits in amount fraction. 03707 */ 03708 int 03709 frac_digits() const 03710 { return this->do_frac_digits(); } 03711 03712 //@{ 03713 /** 03714 * @brief Return pattern for money values. 03715 * 03716 * This function returns a pattern describing the formatting of a 03717 * positive or negative valued money amount. It does so by returning 03718 * returning moneypunct<char_type>::do_pos_format() or 03719 * moneypunct<char_type>::do_neg_format(). 03720 * 03721 * The pattern has 4 fields describing the ordering of symbol, sign, 03722 * value, and none or space. There must be one of each in the pattern. 03723 * The none and space enums may not appear in the first field and space 03724 * may not appear in the final field. 03725 * 03726 * The parts of a money string must appear in the order indicated by 03727 * the fields of the pattern. The symbol field indicates that the 03728 * value of curr_symbol() may be present. The sign field indicates 03729 * that the value of positive_sign() or negative_sign() must be 03730 * present. The value field indicates that the absolute value of the 03731 * money amount is present. none indicates 0 or more whitespace 03732 * characters, except at the end, where it permits no whitespace. 03733 * space indicates that 1 or more whitespace characters must be 03734 * present. 03735 * 03736 * For example, for the US locale and pos_format() pattern 03737 * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == 03738 * '+', and value 10.01, and options set to force the symbol, the 03739 * corresponding string is "$+10.01". 03740 * 03741 * @return Pattern for money values. 03742 */ 03743 pattern 03744 pos_format() const 03745 { return this->do_pos_format(); } 03746 03747 pattern 03748 neg_format() const 03749 { return this->do_neg_format(); } 03750 //@} 03751 03752 protected: 03753 /// Destructor. 03754 virtual 03755 ~moneypunct(); 03756 03757 /** 03758 * @brief Return decimal point character. 03759 * 03760 * Returns a char_type to use as a decimal point. This function is a 03761 * hook for derived classes to change the value returned. 03762 * 03763 * @return @a char_type representing a decimal point. 03764 */ 03765 virtual char_type 03766 do_decimal_point() const 03767 { return _M_data->_M_decimal_point; } 03768 03769 /** 03770 * @brief Return thousands separator character. 03771 * 03772 * Returns a char_type to use as a thousands separator. This function 03773 * is a hook for derived classes to change the value returned. 03774 * 03775 * @return @a char_type representing a thousands separator. 03776 */ 03777 virtual char_type 03778 do_thousands_sep() const 03779 { return _M_data->_M_thousands_sep; } 03780 03781 /** 03782 * @brief Return grouping specification. 03783 * 03784 * Returns a string representing groupings for the integer part of a 03785 * number. This function is a hook for derived classes to change the 03786 * value returned. @see grouping() for details. 03787 * 03788 * @return String representing grouping specification. 03789 */ 03790 virtual string 03791 do_grouping() const 03792 { return _M_data->_M_grouping; } 03793 03794 /** 03795 * @brief Return currency symbol string. 03796 * 03797 * This function returns a string_type to use as a currency symbol. 03798 * This function is a hook for derived classes to change the value 03799 * returned. @see curr_symbol() for details. 03800 * 03801 * @return @a string_type representing a currency symbol. 03802 */ 03803 virtual string_type 03804 do_curr_symbol() const 03805 { return _M_data->_M_curr_symbol; } 03806 03807 /** 03808 * @brief Return positive sign string. 03809 * 03810 * This function returns a string_type to use as a sign for positive 03811 * amounts. This function is a hook for derived classes to change the 03812 * value returned. @see positive_sign() for details. 03813 * 03814 * @return @a string_type representing a positive sign. 03815 */ 03816 virtual string_type 03817 do_positive_sign() const 03818 { return _M_data->_M_positive_sign; } 03819 03820 /** 03821 * @brief Return negative sign string. 03822 * 03823 * This function returns a string_type to use as a sign for negative 03824 * amounts. This function is a hook for derived classes to change the 03825 * value returned. @see negative_sign() for details. 03826 * 03827 * @return @a string_type representing a negative sign. 03828 */ 03829 virtual string_type 03830 do_negative_sign() const 03831 { return _M_data->_M_negative_sign; } 03832 03833 /** 03834 * @brief Return number of digits in fraction. 03835 * 03836 * This function returns the exact number of digits that make up the 03837 * fractional part of a money amount. This function is a hook for 03838 * derived classes to change the value returned. @see frac_digits() 03839 * for details. 03840 * 03841 * @return Number of digits in amount fraction. 03842 */ 03843 virtual int 03844 do_frac_digits() const 03845 { return _M_data->_M_frac_digits; } 03846 03847 /** 03848 * @brief Return pattern for money values. 03849 * 03850 * This function returns a pattern describing the formatting of a 03851 * positive valued money amount. This function is a hook for derived 03852 * classes to change the value returned. @see pos_format() for 03853 * details. 03854 * 03855 * @return Pattern for money values. 03856 */ 03857 virtual pattern 03858 do_pos_format() const 03859 { return _M_data->_M_pos_format; } 03860 03861 /** 03862 * @brief Return pattern for money values. 03863 * 03864 * This function returns a pattern describing the formatting of a 03865 * negative valued money amount. This function is a hook for derived 03866 * classes to change the value returned. @see neg_format() for 03867 * details. 03868 * 03869 * @return Pattern for money values. 03870 */ 03871 virtual pattern 03872 do_neg_format() const 03873 { return _M_data->_M_neg_format; } 03874 03875 // For use at construction time only. 03876 void 03877 _M_initialize_moneypunct(__c_locale __cloc = NULL, 03878 const char* __name = NULL); 03879 }; 03880 03881 template<typename _CharT, bool _Intl> 03882 locale::id moneypunct<_CharT, _Intl>::id; 03883 03884 template<typename _CharT, bool _Intl> 03885 const bool moneypunct<_CharT, _Intl>::intl; 03886 03887 template<> 03888 moneypunct<char, true>::~moneypunct(); 03889 03890 template<> 03891 moneypunct<char, false>::~moneypunct(); 03892 03893 template<> 03894 void 03895 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*); 03896 03897 template<> 03898 void 03899 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*); 03900 03901 #ifdef _GLIBCXX_USE_WCHAR_T 03902 template<> 03903 moneypunct<wchar_t, true>::~moneypunct(); 03904 03905 template<> 03906 moneypunct<wchar_t, false>::~moneypunct(); 03907 03908 template<> 03909 void 03910 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale, 03911 const char*); 03912 03913 template<> 03914 void 03915 moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale, 03916 const char*); 03917 #endif 03918 03919 template<typename _CharT, bool _Intl> 03920 class moneypunct_byname : public moneypunct<_CharT, _Intl> 03921 { 03922 public: 03923 typedef _CharT char_type; 03924 typedef basic_string<_CharT> string_type; 03925 03926 static const bool intl = _Intl; 03927 03928 explicit 03929 moneypunct_byname(const char* __s, size_t __refs = 0) 03930 : moneypunct<_CharT, _Intl>(__refs) 03931 { 03932 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 03933 { 03934 __c_locale __tmp; 03935 this->_S_create_c_locale(__tmp, __s); 03936 this->_M_initialize_moneypunct(__tmp); 03937 this->_S_destroy_c_locale(__tmp); 03938 } 03939 } 03940 03941 protected: 03942 virtual 03943 ~moneypunct_byname() { } 03944 }; 03945 03946 template<typename _CharT, bool _Intl> 03947 const bool moneypunct_byname<_CharT, _Intl>::intl; 03948 03949 /** 03950 * @brief Facet for parsing monetary amounts. 03951 * 03952 * This facet encapsulates the code to parse and return a monetary 03953 * amount from a string. 03954 * 03955 * The money_get template uses protected virtual functions to 03956 * provide the actual results. The public accessors forward the 03957 * call to the virtual functions. These virtual functions are 03958 * hooks for developers to implement the behavior they require from 03959 * the money_get facet. 03960 */ 03961 template<typename _CharT, typename _InIter> 03962 class money_get : public locale::facet 03963 { 03964 public: 03965 // Types: 03966 //@{ 03967 /// Public typedefs 03968 typedef _CharT char_type; 03969 typedef _InIter iter_type; 03970 typedef basic_string<_CharT> string_type; 03971 //@} 03972 03973 /// Numpunct facet id. 03974 static locale::id id; 03975 03976 /** 03977 * @brief Constructor performs initialization. 03978 * 03979 * This is the constructor provided by the standard. 03980 * 03981 * @param refs Passed to the base facet class. 03982 */ 03983 explicit 03984 money_get(size_t __refs = 0) : facet(__refs) { } 03985 03986 /** 03987 * @brief Read and parse a monetary value. 03988 * 03989 * This function reads characters from @a s, interprets them as a 03990 * monetary value according to moneypunct and ctype facets retrieved 03991 * from io.getloc(), and returns the result in @a units as an integral 03992 * value moneypunct::frac_digits() * the actual amount. For example, 03993 * the string $10.01 in a US locale would store 1001 in @a units. 03994 * 03995 * Any characters not part of a valid money amount are not consumed. 03996 * 03997 * If a money value cannot be parsed from the input stream, sets 03998 * err=(err|io.failbit). If the stream is consumed before finishing 03999 * parsing, sets err=(err|io.failbit|io.eofbit). @a units is 04000 * unchanged if parsing fails. 04001 * 04002 * This function works by returning the result of do_get(). 04003 * 04004 * @param s Start of characters to parse. 04005 * @param end End of characters to parse. 04006 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04007 * @param io Source of facets and io state. 04008 * @param err Error field to set if parsing fails. 04009 * @param units Place to store result of parsing. 04010 * @return Iterator referencing first character beyond valid money 04011 * amount. 04012 */ 04013 iter_type 04014 get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 04015 ios_base::iostate& __err, long double& __units) const 04016 { return this->do_get(__s, __end, __intl, __io, __err, __units); } 04017 04018 /** 04019 * @brief Read and parse a monetary value. 04020 * 04021 * This function reads characters from @a s, interprets them as a 04022 * monetary value according to moneypunct and ctype facets retrieved 04023 * from io.getloc(), and returns the result in @a digits. For example, 04024 * the string $10.01 in a US locale would store "1001" in @a digits. 04025 * 04026 * Any characters not part of a valid money amount are not consumed. 04027 * 04028 * If a money value cannot be parsed from the input stream, sets 04029 * err=(err|io.failbit). If the stream is consumed before finishing 04030 * parsing, sets err=(err|io.failbit|io.eofbit). 04031 * 04032 * This function works by returning the result of do_get(). 04033 * 04034 * @param s Start of characters to parse. 04035 * @param end End of characters to parse. 04036 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04037 * @param io Source of facets and io state. 04038 * @param err Error field to set if parsing fails. 04039 * @param digits Place to store result of parsing. 04040 * @return Iterator referencing first character beyond valid money 04041 * amount. 04042 */ 04043 iter_type 04044 get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 04045 ios_base::iostate& __err, string_type& __digits) const 04046 { return this->do_get(__s, __end, __intl, __io, __err, __digits); } 04047 04048 protected: 04049 /// Destructor. 04050 virtual 04051 ~money_get() { } 04052 04053 /** 04054 * @brief Read and parse a monetary value. 04055 * 04056 * This function reads and parses characters representing a monetary 04057 * value. This function is a hook for derived classes to change the 04058 * value returned. @see get() for details. 04059 */ 04060 virtual iter_type 04061 do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 04062 ios_base::iostate& __err, long double& __units) const; 04063 04064 /** 04065 * @brief Read and parse a monetary value. 04066 * 04067 * This function reads and parses characters representing a monetary 04068 * value. This function is a hook for derived classes to change the 04069 * value returned. @see get() for details. 04070 */ 04071 virtual iter_type 04072 do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 04073 ios_base::iostate& __err, string_type& __digits) const; 04074 04075 template<bool _Intl> 04076 iter_type 04077 _M_extract(iter_type __s, iter_type __end, ios_base& __io, 04078 ios_base::iostate& __err, string& __digits) const; 04079 }; 04080 04081 template<typename _CharT, typename _InIter> 04082 locale::id money_get<_CharT, _InIter>::id; 04083 04084 /** 04085 * @brief Facet for outputting monetary amounts. 04086 * 04087 * This facet encapsulates the code to format and output a monetary 04088 * amount. 04089 * 04090 * The money_put template uses protected virtual functions to 04091 * provide the actual results. The public accessors forward the 04092 * call to the virtual functions. These virtual functions are 04093 * hooks for developers to implement the behavior they require from 04094 * the money_put facet. 04095 */ 04096 template<typename _CharT, typename _OutIter> 04097 class money_put : public locale::facet 04098 { 04099 public: 04100 //@{ 04101 /// Public typedefs 04102 typedef _CharT char_type; 04103 typedef _OutIter iter_type; 04104 typedef basic_string<_CharT> string_type; 04105 //@} 04106 04107 /// Numpunct facet id. 04108 static locale::id id; 04109 04110 /** 04111 * @brief Constructor performs initialization. 04112 * 04113 * This is the constructor provided by the standard. 04114 * 04115 * @param refs Passed to the base facet class. 04116 */ 04117 explicit 04118 money_put(size_t __refs = 0) : facet(__refs) { } 04119 04120 /** 04121 * @brief Format and output a monetary value. 04122 * 04123 * This function formats @a units as a monetary value according to 04124 * moneypunct and ctype facets retrieved from io.getloc(), and writes 04125 * the resulting characters to @a s. For example, the value 1001 in a 04126 * US locale would write "$10.01" to @a s. 04127 * 04128 * This function works by returning the result of do_put(). 04129 * 04130 * @param s The stream to write to. 04131 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04132 * @param io Source of facets and io state. 04133 * @param fill char_type to use for padding. 04134 * @param units Place to store result of parsing. 04135 * @return Iterator after writing. 04136 */ 04137 iter_type 04138 put(iter_type __s, bool __intl, ios_base& __io, 04139 char_type __fill, long double __units) const 04140 { return this->do_put(__s, __intl, __io, __fill, __units); } 04141 04142 /** 04143 * @brief Format and output a monetary value. 04144 * 04145 * This function formats @a digits as a monetary value according to 04146 * moneypunct and ctype facets retrieved from io.getloc(), and writes 04147 * the resulting characters to @a s. For example, the string "1001" in 04148 * a US locale would write "$10.01" to @a s. 04149 * 04150 * This function works by returning the result of do_put(). 04151 * 04152 * @param s The stream to write to. 04153 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04154 * @param io Source of facets and io state. 04155 * @param fill char_type to use for padding. 04156 * @param units Place to store result of parsing. 04157 * @return Iterator after writing. 04158 */ 04159 iter_type 04160 put(iter_type __s, bool __intl, ios_base& __io, 04161 char_type __fill, const string_type& __digits) const 04162 { return this->do_put(__s, __intl, __io, __fill, __digits); } 04163 04164 protected: 04165 /// Destructor. 04166 virtual 04167 ~money_put() { } 04168 04169 /** 04170 * @brief Format and output a monetary value. 04171 * 04172 * This function formats @a units as a monetary value according to 04173 * moneypunct and ctype facets retrieved from io.getloc(), and writes 04174 * the resulting characters to @a s. For example, the value 1001 in a 04175 * US locale would write "$10.01" to @a s. 04176 * 04177 * This function is a hook for derived classes to change the value 04178 * returned. @see put(). 04179 * 04180 * @param s The stream to write to. 04181 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04182 * @param io Source of facets and io state. 04183 * @param fill char_type to use for padding. 04184 * @param units Place to store result of parsing. 04185 * @return Iterator after writing. 04186 */ 04187 virtual iter_type 04188 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 04189 long double __units) const; 04190 04191 /** 04192 * @brief Format and output a monetary value. 04193 * 04194 * This function formats @a digits as a monetary value according to 04195 * moneypunct and ctype facets retrieved from io.getloc(), and writes 04196 * the resulting characters to @a s. For example, the string "1001" in 04197 * a US locale would write "$10.01" to @a s. 04198 * 04199 * This function is a hook for derived classes to change the value 04200 * returned. @see put(). 04201 * 04202 * @param s The stream to write to. 04203 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04204 * @param io Source of facets and io state. 04205 * @param fill char_type to use for padding. 04206 * @param units Place to store result of parsing. 04207 * @return Iterator after writing. 04208 */ 04209 virtual iter_type 04210 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 04211 const string_type& __digits) const; 04212 04213 template<bool _Intl> 04214 iter_type 04215 _M_insert(iter_type __s, ios_base& __io, char_type __fill, 04216 const string_type& __digits) const; 04217 }; 04218 04219 template<typename _CharT, typename _OutIter> 04220 locale::id money_put<_CharT, _OutIter>::id; 04221 04222 /** 04223 * @brief Messages facet base class providing catalog typedef. 04224 */ 04225 struct messages_base 04226 { 04227 typedef int catalog; 04228 }; 04229 04230 /** 04231 * @brief Facet for handling message catalogs 04232 * 04233 * This facet encapsulates the code to retrieve messages from 04234 * message catalogs. The only thing defined by the standard for this facet 04235 * is the interface. All underlying functionality is 04236 * implementation-defined. 04237 * 04238 * This library currently implements 3 versions of the message facet. The 04239 * first version (gnu) is a wrapper around gettext, provided by libintl. 04240 * The second version (ieee) is a wrapper around catgets. The final 04241 * version (default) does no actual translation. These implementations are 04242 * only provided for char and wchar_t instantiations. 04243 * 04244 * The messages template uses protected virtual functions to 04245 * provide the actual results. The public accessors forward the 04246 * call to the virtual functions. These virtual functions are 04247 * hooks for developers to implement the behavior they require from 04248 * the messages facet. 04249 */ 04250 template<typename _CharT> 04251 class messages : public locale::facet, public messages_base 04252 { 04253 public: 04254 // Types: 04255 //@{ 04256 /// Public typedefs 04257 typedef _CharT char_type; 04258 typedef basic_string<_CharT> string_type; 04259 //@} 04260 04261 protected: 04262 // Underlying "C" library locale information saved from 04263 // initialization, needed by messages_byname as well. 04264 __c_locale _M_c_locale_messages; 04265 const char* _M_name_messages; 04266 04267 public: 04268 /// Numpunct facet id. 04269 static locale::id id; 04270 04271 /** 04272 * @brief Constructor performs initialization. 04273 * 04274 * This is the constructor provided by the standard. 04275 * 04276 * @param refs Passed to the base facet class. 04277 */ 04278 explicit 04279 messages(size_t __refs = 0); 04280 04281 // Non-standard. 04282 /** 04283 * @brief Internal constructor. Not for general use. 04284 * 04285 * This is a constructor for use by the library itself to set up new 04286 * locales. 04287 * 04288 * @param cloc The "C" locale. 04289 * @param s The name of a locale. 04290 * @param refs Refcount to pass to the base class. 04291 */ 04292 explicit 04293 messages(__c_locale __cloc, const char* __s, size_t __refs = 0); 04294 04295 /* 04296 * @brief Open a message catalog. 04297 * 04298 * This function opens and returns a handle to a message catalog by 04299 * returning do_open(s, loc). 04300 * 04301 * @param s The catalog to open. 04302 * @param loc Locale to use for character set conversions. 04303 * @return Handle to the catalog or value < 0 if open fails. 04304 */ 04305 catalog 04306 open(const basic_string<char>& __s, const locale& __loc) const 04307 { return this->do_open(__s, __loc); } 04308 04309 // Non-standard and unorthodox, yet effective. 04310 /* 04311 * @brief Open a message catalog. 04312 * 04313 * This non-standard function opens and returns a handle to a message 04314 * catalog by returning do_open(s, loc). The third argument provides a 04315 * message catalog root directory for gnu gettext and is ignored 04316 * otherwise. 04317 * 04318 * @param s The catalog to open. 04319 * @param loc Locale to use for character set conversions. 04320 * @param dir Message catalog root directory. 04321 * @return Handle to the catalog or value < 0 if open fails. 04322 */ 04323 catalog 04324 open(const basic_string<char>&, const locale&, const char*) const; 04325 04326 /* 04327 * @brief Look up a string in a message catalog. 04328 * 04329 * This function retrieves and returns a message from a catalog by 04330 * returning do_get(c, set, msgid, s). 04331 * 04332 * For gnu, @a set and @a msgid are ignored. Returns gettext(s). 04333 * For default, returns s. For ieee, returns catgets(c,set,msgid,s). 04334 * 04335 * @param c The catalog to access. 04336 * @param set Implementation-defined. 04337 * @param msgid Implementation-defined. 04338 * @param s Default return value if retrieval fails. 04339 * @return Retrieved message or @a s if get fails. 04340 */ 04341 string_type 04342 get(catalog __c, int __set, int __msgid, const string_type& __s) const 04343 { return this->do_get(__c, __set, __msgid, __s); } 04344 04345 /* 04346 * @brief Close a message catalog. 04347 * 04348 * Closes catalog @a c by calling do_close(c). 04349 * 04350 * @param c The catalog to close. 04351 */ 04352 void 04353 close(catalog __c) const 04354 { return this->do_close(__c); } 04355 04356 protected: 04357 /// Destructor. 04358 virtual 04359 ~messages(); 04360 04361 /* 04362 * @brief Open a message catalog. 04363 * 04364 * This function opens and returns a handle to a message catalog in an 04365 * implementation-defined manner. This function is a hook for derived 04366 * classes to change the value returned. 04367 * 04368 * @param s The catalog to open. 04369 * @param loc Locale to use for character set conversions. 04370 * @return Handle to the opened catalog, value < 0 if open failed. 04371 */ 04372 virtual catalog 04373 do_open(const basic_string<char>&, const locale&) const; 04374 04375 /* 04376 * @brief Look up a string in a message catalog. 04377 * 04378 * This function retrieves and returns a message from a catalog in an 04379 * implementation-defined manner. This function is a hook for derived 04380 * classes to change the value returned. 04381 * 04382 * For gnu, @a set and @a msgid are ignored. Returns gettext(s). 04383 * For default, returns s. For ieee, returns catgets(c,set,msgid,s). 04384 * 04385 * @param c The catalog to access. 04386 * @param set Implementation-defined. 04387 * @param msgid Implementation-defined. 04388 * @param s Default return value if retrieval fails. 04389 * @return Retrieved message or @a s if get fails. 04390 */ 04391 virtual string_type 04392 do_get(catalog, int, int, const string_type& __dfault) const; 04393 04394 /* 04395 * @brief Close a message catalog. 04396 * 04397 * @param c The catalog to close. 04398 */ 04399 virtual void 04400 do_close(catalog) const; 04401 04402 // Returns a locale and codeset-converted string, given a char* message. 04403 char* 04404 _M_convert_to_char(const string_type& __msg) const 04405 { 04406 // XXX 04407 return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str())); 04408 } 04409 04410 // Returns a locale and codeset-converted string, given a char* message. 04411 string_type 04412 _M_convert_from_char(char*) const 04413 { 04414 #if 0 04415 // Length of message string without terminating null. 04416 size_t __len = char_traits<char>::length(__msg) - 1; 04417 04418 // "everybody can easily convert the string using 04419 // mbsrtowcs/wcsrtombs or with iconv()" 04420 04421 // Convert char* to _CharT in locale used to open catalog. 04422 // XXX need additional template parameter on messages class for this.. 04423 // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type; 04424 typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type; 04425 04426 __codecvt_type::state_type __state; 04427 // XXX may need to initialize state. 04428 //initialize_state(__state._M_init()); 04429 04430 char* __from_next; 04431 // XXX what size for this string? 04432 _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); 04433 const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv); 04434 __cvt.out(__state, __msg, __msg + __len, __from_next, 04435 __to, __to + __len + 1, __to_next); 04436 return string_type(__to); 04437 #endif 04438 #if 0 04439 typedef ctype<_CharT> __ctype_type; 04440 // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg); 04441 const __ctype_type& __cvt = use_facet<__ctype_type>(locale()); 04442 // XXX Again, proper length of converted string an issue here. 04443 // For now, assume the converted length is not larger. 04444 _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1)); 04445 __cvt.widen(__msg, __msg + __len, __dest); 04446 return basic_string<_CharT>(__dest); 04447 #endif 04448 return string_type(); 04449 } 04450 }; 04451 04452 template<typename _CharT> 04453 locale::id messages<_CharT>::id; 04454 04455 // Specializations for required instantiations. 04456 template<> 04457 string 04458 messages<char>::do_get(catalog, int, int, const string&) const; 04459 04460 #ifdef _GLIBCXX_USE_WCHAR_T 04461 template<> 04462 wstring 04463 messages<wchar_t>::do_get(catalog, int, int, const wstring&) const; 04464 #endif 04465 04466 template<typename _CharT> 04467 class messages_byname : public messages<_CharT> 04468 { 04469 public: 04470 typedef _CharT char_type; 04471 typedef basic_string<_CharT> string_type; 04472 04473 explicit 04474 messages_byname(const char* __s, size_t __refs = 0); 04475 04476 protected: 04477 virtual 04478 ~messages_byname() 04479 { } 04480 }; 04481 04482 // Include host and configuration specific messages functions. 04483 #include <bits/messages_members.h> 04484 04485 04486 // Subclause convenience interfaces, inlines. 04487 // NB: These are inline because, when used in a loop, some compilers 04488 // can hoist the body out of the loop; then it's just as fast as the 04489 // C is*() function. 04490 //@{ 04491 /// Convenience interface to ctype.is(). 04492 template<typename _CharT> 04493 inline bool 04494 isspace(_CharT __c, const locale& __loc) 04495 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); } 04496 04497 template<typename _CharT> 04498 inline bool 04499 isprint(_CharT __c, const locale& __loc) 04500 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); } 04501 04502 template<typename _CharT> 04503 inline bool 04504 iscntrl(_CharT __c, const locale& __loc) 04505 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); } 04506 04507 template<typename _CharT> 04508 inline bool 04509 isupper(_CharT __c, const locale& __loc) 04510 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); } 04511 04512 template<typename _CharT> 04513 inline bool islower(_CharT __c, const locale& __loc) 04514 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); } 04515 04516 template<typename _CharT> 04517 inline bool 04518 isalpha(_CharT __c, const locale& __loc) 04519 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); } 04520 04521 template<typename _CharT> 04522 inline bool 04523 isdigit(_CharT __c, const locale& __loc) 04524 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); } 04525 04526 template<typename _CharT> 04527 inline bool 04528 ispunct(_CharT __c, const locale& __loc) 04529 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); } 04530 04531 template<typename _CharT> 04532 inline bool 04533 isxdigit(_CharT __c, const locale& __loc) 04534 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); } 04535 04536 template<typename _CharT> 04537 inline bool 04538 isalnum(_CharT __c, const locale& __loc) 04539 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); } 04540 04541 template<typename _CharT> 04542 inline bool 04543 isgraph(_CharT __c, const locale& __loc) 04544 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); } 04545 04546 template<typename _CharT> 04547 inline _CharT 04548 toupper(_CharT __c, const locale& __loc) 04549 { return use_facet<ctype<_CharT> >(__loc).toupper(__c); } 04550 04551 template<typename _CharT> 04552 inline _CharT 04553 tolower(_CharT __c, const locale& __loc) 04554 { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } 04555 //@} 04556 } // namespace std 04557 04558 #endif