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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 /// @brief class ctype_byname [22.2.1.2]. 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 /// @brief class numpunct_byname [22.2.3.2]. 01888 template<typename _CharT> 01889 class numpunct_byname : public numpunct<_CharT> 01890 { 01891 public: 01892 typedef _CharT char_type; 01893 typedef basic_string<_CharT> string_type; 01894 01895 explicit 01896 numpunct_byname(const char* __s, size_t __refs = 0) 01897 : numpunct<_CharT>(__refs) 01898 { 01899 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 01900 { 01901 __c_locale __tmp; 01902 this->_S_create_c_locale(__tmp, __s); 01903 this->_M_initialize_numpunct(__tmp); 01904 this->_S_destroy_c_locale(__tmp); 01905 } 01906 } 01907 01908 protected: 01909 virtual 01910 ~numpunct_byname() { } 01911 }; 01912 01913 /** 01914 * @brief Facet for parsing number strings. 01915 * 01916 * This facet encapsulates the code to parse and return a number 01917 * from a string. It is used by the istream numeric extraction 01918 * operators. 01919 * 01920 * The num_get template uses protected virtual functions to provide the 01921 * actual results. The public accessors forward the call to the virtual 01922 * functions. These virtual functions are hooks for developers to 01923 * implement the behavior they require from the num_get facet. 01924 */ 01925 template<typename _CharT, typename _InIter> 01926 class num_get : public locale::facet 01927 { 01928 public: 01929 // Types: 01930 //@{ 01931 /// Public typedefs 01932 typedef _CharT char_type; 01933 typedef _InIter iter_type; 01934 //@} 01935 01936 /// Numpunct facet id. 01937 static locale::id id; 01938 01939 /** 01940 * @brief Constructor performs initialization. 01941 * 01942 * This is the constructor provided by the standard. 01943 * 01944 * @param refs Passed to the base facet class. 01945 */ 01946 explicit 01947 num_get(size_t __refs = 0) : facet(__refs) { } 01948 01949 /** 01950 * @brief Numeric parsing. 01951 * 01952 * Parses the input stream into the bool @a v. It does so by calling 01953 * num_get::do_get(). 01954 * 01955 * If ios_base::boolalpha is set, attempts to read 01956 * ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets 01957 * @a v to true or false if successful. Sets err to 01958 * ios_base::failbit if reading the string fails. Sets err to 01959 * ios_base::eofbit if the stream is emptied. 01960 * 01961 * If ios_base::boolalpha is not set, proceeds as with reading a long, 01962 * except if the value is 1, sets @a v to true, if the value is 0, sets 01963 * @a v to false, and otherwise set err to ios_base::failbit. 01964 * 01965 * @param in Start of input stream. 01966 * @param end End of input stream. 01967 * @param io Source of locale and flags. 01968 * @param err Error flags to set. 01969 * @param v Value to format and insert. 01970 * @return Iterator after reading. 01971 */ 01972 iter_type 01973 get(iter_type __in, iter_type __end, ios_base& __io, 01974 ios_base::iostate& __err, bool& __v) const 01975 { return this->do_get(__in, __end, __io, __err, __v); } 01976 01977 //@{ 01978 /** 01979 * @brief Numeric parsing. 01980 * 01981 * Parses the input stream into the integral variable @a v. It does so 01982 * by calling num_get::do_get(). 01983 * 01984 * Parsing is affected by the flag settings in @a io. 01985 * 01986 * The basic parse is affected by the value of io.flags() & 01987 * ios_base::basefield. If equal to ios_base::oct, parses like the 01988 * scanf %o specifier. Else if equal to ios_base::hex, parses like %X 01989 * specifier. Else if basefield equal to 0, parses like the %i 01990 * specifier. Otherwise, parses like %d for signed and %u for unsigned 01991 * types. The matching type length modifier is also used. 01992 * 01993 * Digit grouping is intrepreted according to numpunct::grouping() and 01994 * numpunct::thousands_sep(). If the pattern of digit groups isn't 01995 * consistent, sets err to ios_base::failbit. 01996 * 01997 * If parsing the string yields a valid value for @a v, @a v is set. 01998 * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 01999 * Sets err to ios_base::eofbit if the stream is emptied. 02000 * 02001 * @param in Start of input stream. 02002 * @param end End of input stream. 02003 * @param io Source of locale and flags. 02004 * @param err Error flags to set. 02005 * @param v Value to format and insert. 02006 * @return Iterator after reading. 02007 */ 02008 iter_type 02009 get(iter_type __in, iter_type __end, ios_base& __io, 02010 ios_base::iostate& __err, long& __v) const 02011 { return this->do_get(__in, __end, __io, __err, __v); } 02012 02013 iter_type 02014 get(iter_type __in, iter_type __end, ios_base& __io, 02015 ios_base::iostate& __err, unsigned short& __v) const 02016 { return this->do_get(__in, __end, __io, __err, __v); } 02017 02018 iter_type 02019 get(iter_type __in, iter_type __end, ios_base& __io, 02020 ios_base::iostate& __err, unsigned int& __v) const 02021 { return this->do_get(__in, __end, __io, __err, __v); } 02022 02023 iter_type 02024 get(iter_type __in, iter_type __end, ios_base& __io, 02025 ios_base::iostate& __err, unsigned long& __v) const 02026 { return this->do_get(__in, __end, __io, __err, __v); } 02027 02028 #ifdef _GLIBCXX_USE_LONG_LONG 02029 iter_type 02030 get(iter_type __in, iter_type __end, ios_base& __io, 02031 ios_base::iostate& __err, long long& __v) const 02032 { return this->do_get(__in, __end, __io, __err, __v); } 02033 02034 iter_type 02035 get(iter_type __in, iter_type __end, ios_base& __io, 02036 ios_base::iostate& __err, unsigned long long& __v) const 02037 { return this->do_get(__in, __end, __io, __err, __v); } 02038 #endif 02039 //@} 02040 02041 //@{ 02042 /** 02043 * @brief Numeric parsing. 02044 * 02045 * Parses the input stream into the integral variable @a v. It does so 02046 * by calling num_get::do_get(). 02047 * 02048 * The input characters are parsed like the scanf %g specifier. The 02049 * matching type length modifier is also used. 02050 * 02051 * The decimal point character used is numpunct::decimal_point(). 02052 * Digit grouping is intrepreted according to numpunct::grouping() and 02053 * numpunct::thousands_sep(). If the pattern of digit groups isn't 02054 * consistent, sets err to ios_base::failbit. 02055 * 02056 * If parsing the string yields a valid value for @a v, @a v is set. 02057 * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 02058 * Sets err to ios_base::eofbit if the stream is emptied. 02059 * 02060 * @param in Start of input stream. 02061 * @param end End of input stream. 02062 * @param io Source of locale and flags. 02063 * @param err Error flags to set. 02064 * @param v Value to format and insert. 02065 * @return Iterator after reading. 02066 */ 02067 iter_type 02068 get(iter_type __in, iter_type __end, ios_base& __io, 02069 ios_base::iostate& __err, float& __v) const 02070 { return this->do_get(__in, __end, __io, __err, __v); } 02071 02072 iter_type 02073 get(iter_type __in, iter_type __end, ios_base& __io, 02074 ios_base::iostate& __err, double& __v) const 02075 { return this->do_get(__in, __end, __io, __err, __v); } 02076 02077 iter_type 02078 get(iter_type __in, iter_type __end, ios_base& __io, 02079 ios_base::iostate& __err, long double& __v) const 02080 { return this->do_get(__in, __end, __io, __err, __v); } 02081 //@} 02082 02083 /** 02084 * @brief Numeric parsing. 02085 * 02086 * Parses the input stream into the pointer variable @a v. It does so 02087 * by calling num_get::do_get(). 02088 * 02089 * The input characters are parsed like the scanf %p specifier. 02090 * 02091 * Digit grouping is intrepreted according to numpunct::grouping() and 02092 * numpunct::thousands_sep(). If the pattern of digit groups isn't 02093 * consistent, sets err to ios_base::failbit. 02094 * 02095 * Note that the digit grouping effect for pointers is a bit ambiguous 02096 * in the standard and shouldn't be relied on. See DR 344. 02097 * 02098 * If parsing the string yields a valid value for @a v, @a v is set. 02099 * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 02100 * Sets err to ios_base::eofbit if the stream is emptied. 02101 * 02102 * @param in Start of input stream. 02103 * @param end End of input stream. 02104 * @param io Source of locale and flags. 02105 * @param err Error flags to set. 02106 * @param v Value to format and insert. 02107 * @return Iterator after reading. 02108 */ 02109 iter_type 02110 get(iter_type __in, iter_type __end, ios_base& __io, 02111 ios_base::iostate& __err, void*& __v) const 02112 { return this->do_get(__in, __end, __io, __err, __v); } 02113 02114 protected: 02115 /// Destructor. 02116 virtual ~num_get() { } 02117 02118 iter_type 02119 _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, 02120 string& __xtrc) const; 02121 02122 template<typename _ValueT> 02123 iter_type 02124 _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, 02125 _ValueT& __v) const; 02126 02127 //@{ 02128 /** 02129 * @brief Numeric parsing. 02130 * 02131 * Parses the input stream into the variable @a v. This function is a 02132 * hook for derived classes to change the value returned. @see get() 02133 * for more details. 02134 * 02135 * @param in Start of input stream. 02136 * @param end End of input stream. 02137 * @param io Source of locale and flags. 02138 * @param err Error flags to set. 02139 * @param v Value to format and insert. 02140 * @return Iterator after reading. 02141 */ 02142 virtual iter_type 02143 do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; 02144 02145 02146 virtual iter_type 02147 do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; 02148 02149 virtual iter_type 02150 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02151 unsigned short&) const; 02152 02153 virtual iter_type 02154 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02155 unsigned int&) const; 02156 02157 virtual iter_type 02158 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02159 unsigned long&) const; 02160 02161 #ifdef _GLIBCXX_USE_LONG_LONG 02162 virtual iter_type 02163 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02164 long long&) const; 02165 02166 virtual iter_type 02167 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02168 unsigned long long&) const; 02169 #endif 02170 02171 virtual iter_type 02172 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02173 float&) const; 02174 02175 virtual iter_type 02176 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02177 double&) const; 02178 02179 virtual iter_type 02180 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02181 long double&) const; 02182 02183 virtual iter_type 02184 do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 02185 void*&) const; 02186 //@} 02187 }; 02188 02189 template<typename _CharT, typename _InIter> 02190 locale::id num_get<_CharT, _InIter>::id; 02191 02192 02193 /** 02194 * @brief Facet for converting numbers to strings. 02195 * 02196 * This facet encapsulates the code to convert a number to a string. It is 02197 * used by the ostream numeric insertion operators. 02198 * 02199 * The num_put template uses protected virtual functions to provide the 02200 * actual results. The public accessors forward the call to the virtual 02201 * functions. These virtual functions are hooks for developers to 02202 * implement the behavior they require from the num_put facet. 02203 */ 02204 template<typename _CharT, typename _OutIter> 02205 class num_put : public locale::facet 02206 { 02207 public: 02208 // Types: 02209 //@{ 02210 /// Public typedefs 02211 typedef _CharT char_type; 02212 typedef _OutIter iter_type; 02213 //@} 02214 02215 /// Numpunct facet id. 02216 static locale::id id; 02217 02218 /** 02219 * @brief Constructor performs initialization. 02220 * 02221 * This is the constructor provided by the standard. 02222 * 02223 * @param refs Passed to the base facet class. 02224 */ 02225 explicit 02226 num_put(size_t __refs = 0) : facet(__refs) { } 02227 02228 /** 02229 * @brief Numeric formatting. 02230 * 02231 * Formats the boolean @a v and inserts it into a stream. It does so 02232 * by calling num_put::do_put(). 02233 * 02234 * If ios_base::boolalpha is set, writes ctype<CharT>::truename() or 02235 * ctype<CharT>::falsename(). Otherwise formats @a v as an int. 02236 * 02237 * @param s Stream to write to. 02238 * @param io Source of locale and flags. 02239 * @param fill Char_type to use for filling. 02240 * @param v Value to format and insert. 02241 * @return Iterator after writing. 02242 */ 02243 iter_type 02244 put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const 02245 { return this->do_put(__s, __f, __fill, __v); } 02246 02247 //@{ 02248 /** 02249 * @brief Numeric formatting. 02250 * 02251 * Formats the integral value @a v and inserts it into a 02252 * stream. It does so by calling num_put::do_put(). 02253 * 02254 * Formatting is affected by the flag settings in @a io. 02255 * 02256 * The basic format is affected by the value of io.flags() & 02257 * ios_base::basefield. If equal to ios_base::oct, formats like the 02258 * printf %o specifier. Else if equal to ios_base::hex, formats like 02259 * %x or %X with ios_base::uppercase unset or set respectively. 02260 * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu 02261 * for unsigned values. Note that if both oct and hex are set, neither 02262 * will take effect. 02263 * 02264 * If ios_base::showpos is set, '+' is output before positive values. 02265 * If ios_base::showbase is set, '0' precedes octal values (except 0) 02266 * and '0[xX]' precedes hex values. 02267 * 02268 * Thousands separators are inserted according to numpunct::grouping() 02269 * and numpunct::thousands_sep(). The decimal point character used is 02270 * numpunct::decimal_point(). 02271 * 02272 * If io.width() is non-zero, enough @a fill characters are inserted to 02273 * make the result at least that wide. If 02274 * (io.flags() & ios_base::adjustfield) == ios_base::left, result is 02275 * padded at the end. If ios_base::internal, then padding occurs 02276 * immediately after either a '+' or '-' or after '0x' or '0X'. 02277 * Otherwise, padding occurs at the beginning. 02278 * 02279 * @param s Stream to write to. 02280 * @param io Source of locale and flags. 02281 * @param fill Char_type to use for filling. 02282 * @param v Value to format and insert. 02283 * @return Iterator after writing. 02284 */ 02285 iter_type 02286 put(iter_type __s, ios_base& __f, char_type __fill, long __v) const 02287 { return this->do_put(__s, __f, __fill, __v); } 02288 02289 iter_type 02290 put(iter_type __s, ios_base& __f, char_type __fill, 02291 unsigned long __v) const 02292 { return this->do_put(__s, __f, __fill, __v); } 02293 02294 #ifdef _GLIBCXX_USE_LONG_LONG 02295 iter_type 02296 put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const 02297 { return this->do_put(__s, __f, __fill, __v); } 02298 02299 iter_type 02300 put(iter_type __s, ios_base& __f, char_type __fill, 02301 unsigned long long __v) const 02302 { return this->do_put(__s, __f, __fill, __v); } 02303 #endif 02304 //@} 02305 02306 //@{ 02307 /** 02308 * @brief Numeric formatting. 02309 * 02310 * Formats the floating point value @a v and inserts it into a stream. 02311 * It does so by calling num_put::do_put(). 02312 * 02313 * Formatting is affected by the flag settings in @a io. 02314 * 02315 * The basic format is affected by the value of io.flags() & 02316 * ios_base::floatfield. If equal to ios_base::fixed, formats like the 02317 * printf %f specifier. Else if equal to ios_base::scientific, formats 02318 * like %e or %E with ios_base::uppercase unset or set respectively. 02319 * Otherwise, formats like %g or %G depending on uppercase. Note that 02320 * if both fixed and scientific are set, the effect will also be like 02321 * %g or %G. 02322 * 02323 * The output precision is given by io.precision(). This precision is 02324 * capped at numeric_limits::digits10 + 2 (different for double and 02325 * long double). The default precision is 6. 02326 * 02327 * If ios_base::showpos is set, '+' is output before positive values. 02328 * If ios_base::showpoint is set, a decimal point will always be 02329 * output. 02330 * 02331 * Thousands separators are inserted according to numpunct::grouping() 02332 * and numpunct::thousands_sep(). The decimal point character used is 02333 * numpunct::decimal_point(). 02334 * 02335 * If io.width() is non-zero, enough @a fill characters are inserted to 02336 * make the result at least that wide. If 02337 * (io.flags() & ios_base::adjustfield) == ios_base::left, result is 02338 * padded at the end. If ios_base::internal, then padding occurs 02339 * immediately after either a '+' or '-' or after '0x' or '0X'. 02340 * Otherwise, padding occurs at the beginning. 02341 * 02342 * @param s Stream to write to. 02343 * @param io Source of locale and flags. 02344 * @param fill Char_type to use for filling. 02345 * @param v Value to format and insert. 02346 * @return Iterator after writing. 02347 */ 02348 iter_type 02349 put(iter_type __s, ios_base& __f, char_type __fill, double __v) const 02350 { return this->do_put(__s, __f, __fill, __v); } 02351 02352 iter_type 02353 put(iter_type __s, ios_base& __f, char_type __fill, 02354 long double __v) const 02355 { return this->do_put(__s, __f, __fill, __v); } 02356 //@} 02357 02358 /** 02359 * @brief Numeric formatting. 02360 * 02361 * Formats the pointer value @a v and inserts it into a stream. It 02362 * does so by calling num_put::do_put(). 02363 * 02364 * This function formats @a v as an unsigned long with ios_base::hex 02365 * and ios_base::showbase set. 02366 * 02367 * @param s Stream to write to. 02368 * @param io Source of locale and flags. 02369 * @param fill Char_type to use for filling. 02370 * @param v Value to format and insert. 02371 * @return Iterator after writing. 02372 */ 02373 iter_type 02374 put(iter_type __s, ios_base& __f, char_type __fill, 02375 const void* __v) const 02376 { return this->do_put(__s, __f, __fill, __v); } 02377 02378 protected: 02379 template<typename _ValueT> 02380 iter_type 02381 _M_insert_float(iter_type, ios_base& __io, char_type __fill, 02382 char __mod, _ValueT __v) const; 02383 02384 void 02385 _M_group_float(const char* __grouping, size_t __grouping_size, 02386 char_type __sep, const char_type* __p, char_type* __new, 02387 char_type* __cs, int& __len) const; 02388 02389 template<typename _ValueT> 02390 iter_type 02391 _M_insert_int(iter_type, ios_base& __io, char_type __fill, 02392 _ValueT __v) const; 02393 02394 void 02395 _M_group_int(const char* __grouping, size_t __grouping_size, 02396 char_type __sep, ios_base& __io, char_type* __new, 02397 char_type* __cs, int& __len) const; 02398 02399 void 02400 _M_pad(char_type __fill, streamsize __w, ios_base& __io, 02401 char_type* __new, const char_type* __cs, int& __len) const; 02402 02403 /// Destructor. 02404 virtual 02405 ~num_put() { }; 02406 02407 //@{ 02408 /** 02409 * @brief Numeric formatting. 02410 * 02411 * These functions do the work of formatting numeric values and 02412 * inserting them into a stream. This function is a hook for derived 02413 * classes to change the value returned. 02414 * 02415 * @param s Stream to write to. 02416 * @param io Source of locale and flags. 02417 * @param fill Char_type to use for filling. 02418 * @param v Value to format and insert. 02419 * @return Iterator after writing. 02420 */ 02421 virtual iter_type 02422 do_put(iter_type, ios_base&, char_type __fill, bool __v) const; 02423 02424 virtual iter_type 02425 do_put(iter_type, ios_base&, char_type __fill, long __v) const; 02426 02427 virtual iter_type 02428 do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; 02429 02430 #ifdef _GLIBCXX_USE_LONG_LONG 02431 virtual iter_type 02432 do_put(iter_type, ios_base&, char_type __fill, long long __v) const; 02433 02434 virtual iter_type 02435 do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; 02436 #endif 02437 02438 virtual iter_type 02439 do_put(iter_type, ios_base&, char_type __fill, double __v) const; 02440 02441 virtual iter_type 02442 do_put(iter_type, ios_base&, char_type __fill, long double __v) const; 02443 02444 virtual iter_type 02445 do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; 02446 //@} 02447 }; 02448 02449 template <typename _CharT, typename _OutIter> 02450 locale::id num_put<_CharT, _OutIter>::id; 02451 02452 02453 /** 02454 * @brief Facet for localized string comparison. 02455 * 02456 * This facet encapsulates the code to compare strings in a localized 02457 * manner. 02458 * 02459 * The collate template uses protected virtual functions to provide 02460 * the actual results. The public accessors forward the call to 02461 * the virtual functions. These virtual functions are hooks for 02462 * developers to implement the behavior they require from the 02463 * collate facet. 02464 */ 02465 template<typename _CharT> 02466 class collate : public locale::facet 02467 { 02468 public: 02469 // Types: 02470 //@{ 02471 /// Public typedefs 02472 typedef _CharT char_type; 02473 typedef basic_string<_CharT> string_type; 02474 //@} 02475 02476 protected: 02477 // Underlying "C" library locale information saved from 02478 // initialization, needed by collate_byname as well. 02479 __c_locale _M_c_locale_collate; 02480 02481 public: 02482 /// Numpunct facet id. 02483 static locale::id id; 02484 02485 /** 02486 * @brief Constructor performs initialization. 02487 * 02488 * This is the constructor provided by the standard. 02489 * 02490 * @param refs Passed to the base facet class. 02491 */ 02492 explicit 02493 collate(size_t __refs = 0) 02494 : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) 02495 { } 02496 02497 /** 02498 * @brief Internal constructor. Not for general use. 02499 * 02500 * This is a constructor for use by the library itself to set up new 02501 * locales. 02502 * 02503 * @param cloc The "C" locale. 02504 * @param refs Passed to the base facet class. 02505 */ 02506 explicit 02507 collate(__c_locale __cloc, size_t __refs = 0) 02508 : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) 02509 { } 02510 02511 /** 02512 * @brief Compare two strings. 02513 * 02514 * This function compares two strings and returns the result by calling 02515 * collate::do_compare(). 02516 * 02517 * @param lo1 Start of string 1. 02518 * @param hi1 End of string 1. 02519 * @param lo2 Start of string 2. 02520 * @param hi2 End of string 2. 02521 * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 02522 */ 02523 int 02524 compare(const _CharT* __lo1, const _CharT* __hi1, 02525 const _CharT* __lo2, const _CharT* __hi2) const 02526 { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } 02527 02528 /** 02529 * @brief Transform string to comparable form. 02530 * 02531 * This function is a wrapper for strxfrm functionality. It takes the 02532 * input string and returns a modified string that can be directly 02533 * compared to other transformed strings. In the "C" locale, this 02534 * function just returns a copy of the input string. In some other 02535 * locales, it may replace two chars with one, change a char for 02536 * another, etc. It does so by returning collate::do_transform(). 02537 * 02538 * @param lo Start of string. 02539 * @param hi End of string. 02540 * @return Transformed string_type. 02541 */ 02542 string_type 02543 transform(const _CharT* __lo, const _CharT* __hi) const 02544 { return this->do_transform(__lo, __hi); } 02545 02546 /** 02547 * @brief Return hash of a string. 02548 * 02549 * This function computes and returns a hash on the input string. It 02550 * does so by returning collate::do_hash(). 02551 * 02552 * @param lo Start of string. 02553 * @param hi End of string. 02554 * @return Hash value. 02555 */ 02556 long 02557 hash(const _CharT* __lo, const _CharT* __hi) const 02558 { return this->do_hash(__lo, __hi); } 02559 02560 // Used to abstract out _CharT bits in virtual member functions, below. 02561 int 02562 _M_compare(const _CharT*, const _CharT*) const; 02563 02564 size_t 02565 _M_transform(_CharT*, const _CharT*, size_t) const; 02566 02567 protected: 02568 /// Destructor. 02569 virtual 02570 ~collate() 02571 { _S_destroy_c_locale(_M_c_locale_collate); } 02572 02573 /** 02574 * @brief Compare two strings. 02575 * 02576 * This function is a hook for derived classes to change the value 02577 * returned. @see compare(). 02578 * 02579 * @param lo1 Start of string 1. 02580 * @param hi1 End of string 1. 02581 * @param lo2 Start of string 2. 02582 * @param hi2 End of string 2. 02583 * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 02584 */ 02585 virtual int 02586 do_compare(const _CharT* __lo1, const _CharT* __hi1, 02587 const _CharT* __lo2, const _CharT* __hi2) const; 02588 02589 /** 02590 * @brief Transform string to comparable form. 02591 * 02592 * This function is a hook for derived classes to change the value 02593 * returned. 02594 * 02595 * @param lo1 Start of string 1. 02596 * @param hi1 End of string 1. 02597 * @param lo2 Start of string 2. 02598 * @param hi2 End of string 2. 02599 * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 02600 */ 02601 virtual string_type 02602 do_transform(const _CharT* __lo, const _CharT* __hi) const; 02603 02604 /** 02605 * @brief Return hash of a string. 02606 * 02607 * This function computes and returns a hash on the input string. This 02608 * function is a hook for derived classes to change the value returned. 02609 * 02610 * @param lo Start of string. 02611 * @param hi End of string. 02612 * @return Hash value. 02613 */ 02614 virtual long 02615 do_hash(const _CharT* __lo, const _CharT* __hi) const; 02616 }; 02617 02618 template<typename _CharT> 02619 locale::id collate<_CharT>::id; 02620 02621 // Specializations. 02622 template<> 02623 int 02624 collate<char>::_M_compare(const char*, const char*) const; 02625 02626 template<> 02627 size_t 02628 collate<char>::_M_transform(char*, const char*, size_t) const; 02629 02630 #ifdef _GLIBCXX_USE_WCHAR_T 02631 template<> 02632 int 02633 collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const; 02634 02635 template<> 02636 size_t 02637 collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const; 02638 #endif 02639 02640 /// @brief class collate_byname [22.2.4.2]. 02641 template<typename _CharT> 02642 class collate_byname : public collate<_CharT> 02643 { 02644 public: 02645 //@{ 02646 /// Public typedefs 02647 typedef _CharT char_type; 02648 typedef basic_string<_CharT> string_type; 02649 //@} 02650 02651 explicit 02652 collate_byname(const char* __s, size_t __refs = 0) 02653 : collate<_CharT>(__refs) 02654 { 02655 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 02656 { 02657 this->_S_destroy_c_locale(this->_M_c_locale_collate); 02658 this->_S_create_c_locale(this->_M_c_locale_collate, __s); 02659 } 02660 } 02661 02662 protected: 02663 virtual 02664 ~collate_byname() { } 02665 }; 02666 02667 02668 /** 02669 * @brief Time format ordering data. 02670 * 02671 * This class provides an enum representing different orderings of day, 02672 * month, and year. 02673 */ 02674 class time_base 02675 { 02676 public: 02677 enum dateorder { no_order, dmy, mdy, ymd, ydm }; 02678 }; 02679 02680 template<typename _CharT> 02681 struct __timepunct_cache : public locale::facet 02682 { 02683 // List of all known timezones, with GMT first. 02684 static const _CharT* _S_timezones[14]; 02685 02686 const _CharT* _M_date_format; 02687 const _CharT* _M_date_era_format; 02688 const _CharT* _M_time_format; 02689 const _CharT* _M_time_era_format; 02690 const _CharT* _M_date_time_format; 02691 const _CharT* _M_date_time_era_format; 02692 const _CharT* _M_am; 02693 const _CharT* _M_pm; 02694 const _CharT* _M_am_pm_format; 02695 02696 // Day names, starting with "C"'s Sunday. 02697 const _CharT* _M_day1; 02698 const _CharT* _M_day2; 02699 const _CharT* _M_day3; 02700 const _CharT* _M_day4; 02701 const _CharT* _M_day5; 02702 const _CharT* _M_day6; 02703 const _CharT* _M_day7; 02704 02705 // Abbreviated day names, starting with "C"'s Sun. 02706 const _CharT* _M_aday1; 02707 const _CharT* _M_aday2; 02708 const _CharT* _M_aday3; 02709 const _CharT* _M_aday4; 02710 const _CharT* _M_aday5; 02711 const _CharT* _M_aday6; 02712 const _CharT* _M_aday7; 02713 02714 // Month names, starting with "C"'s January. 02715 const _CharT* _M_month01; 02716 const _CharT* _M_month02; 02717 const _CharT* _M_month03; 02718 const _CharT* _M_month04; 02719 const _CharT* _M_month05; 02720 const _CharT* _M_month06; 02721 const _CharT* _M_month07; 02722 const _CharT* _M_month08; 02723 const _CharT* _M_month09; 02724 const _CharT* _M_month10; 02725 const _CharT* _M_month11; 02726 const _CharT* _M_month12; 02727 02728 // Abbreviated month names, starting with "C"'s Jan. 02729 const _CharT* _M_amonth01; 02730 const _CharT* _M_amonth02; 02731 const _CharT* _M_amonth03; 02732 const _CharT* _M_amonth04; 02733 const _CharT* _M_amonth05; 02734 const _CharT* _M_amonth06; 02735 const _CharT* _M_amonth07; 02736 const _CharT* _M_amonth08; 02737 const _CharT* _M_amonth09; 02738 const _CharT* _M_amonth10; 02739 const _CharT* _M_amonth11; 02740 const _CharT* _M_amonth12; 02741 02742 bool _M_allocated; 02743 02744 __timepunct_cache(size_t __refs = 0) : facet(__refs), 02745 _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), 02746 _M_time_era_format(NULL), _M_date_time_format(NULL), 02747 _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), 02748 _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), 02749 _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), 02750 _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), 02751 _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), 02752 _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), 02753 _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), 02754 _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), 02755 _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), 02756 _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), 02757 _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), 02758 _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) 02759 { } 02760 02761 ~__timepunct_cache(); 02762 02763 void 02764 _M_cache(const locale& __loc); 02765 02766 private: 02767 __timepunct_cache& 02768 operator=(const __timepunct_cache&); 02769 02770 explicit 02771 __timepunct_cache(const __timepunct_cache&); 02772 }; 02773 02774 template<typename _CharT> 02775 __timepunct_cache<_CharT>::~__timepunct_cache() 02776 { 02777 if (_M_allocated) 02778 { 02779 // Unused. 02780 } 02781 } 02782 02783 // Specializations. 02784 template<> 02785 const char* 02786 __timepunct_cache<char>::_S_timezones[14]; 02787 02788 #ifdef _GLIBCXX_USE_WCHAR_T 02789 template<> 02790 const wchar_t* 02791 __timepunct_cache<wchar_t>::_S_timezones[14]; 02792 #endif 02793 02794 // Generic. 02795 template<typename _CharT> 02796 const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; 02797 02798 template<typename _CharT> 02799 class __timepunct : public locale::facet 02800 { 02801 public: 02802 // Types: 02803 typedef _CharT __char_type; 02804 typedef basic_string<_CharT> __string_type; 02805 typedef __timepunct_cache<_CharT> __cache_type; 02806 02807 protected: 02808 __cache_type* _M_data; 02809 __c_locale _M_c_locale_timepunct; 02810 const char* _M_name_timepunct; 02811 02812 public: 02813 /// Numpunct facet id. 02814 static locale::id id; 02815 02816 explicit 02817 __timepunct(size_t __refs = 0); 02818 02819 explicit 02820 __timepunct(__cache_type* __cache, size_t __refs = 0); 02821 02822 /** 02823 * @brief Internal constructor. Not for general use. 02824 * 02825 * This is a constructor for use by the library itself to set up new 02826 * locales. 02827 * 02828 * @param cloc The "C" locale. 02829 * @param s The name of a locale. 02830 * @param refs Passed to the base facet class. 02831 */ 02832 explicit 02833 __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); 02834 02835 // FIXME: for error checking purposes _M_put should return the return 02836 // value of strftime/wcsftime. 02837 void 02838 _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, 02839 const tm* __tm) const; 02840 02841 void 02842 _M_date_formats(const _CharT** __date) const 02843 { 02844 // Always have default first. 02845 __date[0] = _M_data->_M_date_format; 02846 __date[1] = _M_data->_M_date_era_format; 02847 } 02848 02849 void 02850 _M_time_formats(const _CharT** __time) const 02851 { 02852 // Always have default first. 02853 __time[0] = _M_data->_M_time_format; 02854 __time[1] = _M_data->_M_time_era_format; 02855 } 02856 02857 void 02858 _M_date_time_formats(const _CharT** __dt) const 02859 { 02860 // Always have default first. 02861 __dt[0] = _M_data->_M_date_time_format; 02862 __dt[1] = _M_data->_M_date_time_era_format; 02863 } 02864 02865 void 02866 _M_am_pm_format(const _CharT* __ampm) const 02867 { __ampm = _M_data->_M_am_pm_format; } 02868 02869 void 02870 _M_am_pm(const _CharT** __ampm) const 02871 { 02872 __ampm[0] = _M_data->_M_am; 02873 __ampm[1] = _M_data->_M_pm; 02874 } 02875 02876 void 02877 _M_days(const _CharT** __days) const 02878 { 02879 __days[0] = _M_data->_M_day1; 02880 __days[1] = _M_data->_M_day2; 02881 __days[2] = _M_data->_M_day3; 02882 __days[3] = _M_data->_M_day4; 02883 __days[4] = _M_data->_M_day5; 02884 __days[5] = _M_data->_M_day6; 02885 __days[6] = _M_data->_M_day7; 02886 } 02887 02888 void 02889 _M_days_abbreviated(const _CharT** __days) const 02890 { 02891 __days[0] = _M_data->_M_aday1; 02892 __days[1] = _M_data->_M_aday2; 02893 __days[2] = _M_data->_M_aday3; 02894 __days[3] = _M_data->_M_aday4; 02895 __days[4] = _M_data->_M_aday5; 02896 __days[5] = _M_data->_M_aday6; 02897 __days[6] = _M_data->_M_aday7; 02898 } 02899 02900 void 02901 _M_months(const _CharT** __months) const 02902 { 02903 __months[0] = _M_data->_M_month01; 02904 __months[1] = _M_data->_M_month02; 02905 __months[2] = _M_data->_M_month03; 02906 __months[3] = _M_data->_M_month04; 02907 __months[4] = _M_data->_M_month05; 02908 __months[5] = _M_data->_M_month06; 02909 __months[6] = _M_data->_M_month07; 02910 __months[7] = _M_data->_M_month08; 02911 __months[8] = _M_data->_M_month09; 02912 __months[9] = _M_data->_M_month10; 02913 __months[10] = _M_data->_M_month11; 02914 __months[11] = _M_data->_M_month12; 02915 } 02916 02917 void 02918 _M_months_abbreviated(const _CharT** __months) const 02919 { 02920 __months[0] = _M_data->_M_amonth01; 02921 __months[1] = _M_data->_M_amonth02; 02922 __months[2] = _M_data->_M_amonth03; 02923 __months[3] = _M_data->_M_amonth04; 02924 __months[4] = _M_data->_M_amonth05; 02925 __months[5] = _M_data->_M_amonth06; 02926 __months[6] = _M_data->_M_amonth07; 02927 __months[7] = _M_data->_M_amonth08; 02928 __months[8] = _M_data->_M_amonth09; 02929 __months[9] = _M_data->_M_amonth10; 02930 __months[10] = _M_data->_M_amonth11; 02931 __months[11] = _M_data->_M_amonth12; 02932 } 02933 02934 protected: 02935 virtual 02936 ~__timepunct(); 02937 02938 // For use at construction time only. 02939 void 02940 _M_initialize_timepunct(__c_locale __cloc = NULL); 02941 }; 02942 02943 template<typename _CharT> 02944 locale::id __timepunct<_CharT>::id; 02945 02946 // Specializations. 02947 template<> 02948 void 02949 __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc); 02950 02951 template<> 02952 void 02953 __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const; 02954 02955 #ifdef _GLIBCXX_USE_WCHAR_T 02956 template<> 02957 void 02958 __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc); 02959 02960 template<> 02961 void 02962 __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*, 02963 const tm*) const; 02964 #endif 02965 02966 // Include host and configuration specific timepunct functions. 02967 #include <bits/time_members.h> 02968 02969 /** 02970 * @brief Facet for parsing dates and times. 02971 * 02972 * This facet encapsulates the code to parse and return a date or 02973 * time from a string. It is used by the istream numeric 02974 * extraction operators. 02975 * 02976 * The time_get template uses protected virtual functions to provide the 02977 * actual results. The public accessors forward the call to the virtual 02978 * functions. These virtual functions are hooks for developers to 02979 * implement the behavior they require from the time_get facet. 02980 */ 02981 template<typename _CharT, typename _InIter> 02982 class time_get : public locale::facet, public time_base 02983 { 02984 public: 02985 // Types: 02986 //@{ 02987 /// Public typedefs 02988 typedef _CharT char_type; 02989 typedef _InIter iter_type; 02990 //@} 02991 typedef basic_string<_CharT> __string_type; 02992 02993 /// Numpunct facet id. 02994 static locale::id id; 02995 02996 /** 02997 * @brief Constructor performs initialization. 02998 * 02999 * This is the constructor provided by the standard. 03000 * 03001 * @param refs Passed to the base facet class. 03002 */ 03003 explicit 03004 time_get(size_t __refs = 0) 03005 : facet (__refs) { } 03006 03007 /** 03008 * @brief Return preferred order of month, day, and year. 03009 * 03010 * This function returns an enum from timebase::dateorder giving the 03011 * preferred ordering if the format "x" given to time_put::put() only 03012 * uses month, day, and year. If the format "x" for the associated 03013 * locale uses other fields, this function returns 03014 * timebase::dateorder::noorder. 03015 * 03016 * NOTE: The library always returns noorder at the moment. 03017 * 03018 * @return A member of timebase::dateorder. 03019 */ 03020 dateorder 03021 date_order() const 03022 { return this->do_date_order(); } 03023 03024 /** 03025 * @brief Parse input time string. 03026 * 03027 * This function parses a time according to the format "x" and puts the 03028 * results into a user-supplied struct tm. The result is returned by 03029 * calling time_get::do_get_time(). 03030 * 03031 * If there is a valid time string according to format "x", @a tm will 03032 * be filled in accordingly and the returned iterator will point to the 03033 * first character beyond the time string. If an error occurs before 03034 * the end, err |= ios_base::failbit. If parsing reads all the 03035 * characters, err |= ios_base::eofbit. 03036 * 03037 * @param beg Start of string to parse. 03038 * @param end End of string to parse. 03039 * @param io Source of the locale. 03040 * @param err Error flags to set. 03041 * @param tm Pointer to struct tm to fill in. 03042 * @return Iterator to first char beyond time string. 03043 */ 03044 iter_type 03045 get_time(iter_type __beg, iter_type __end, ios_base& __io, 03046 ios_base::iostate& __err, tm* __tm) const 03047 { return this->do_get_time(__beg, __end, __io, __err, __tm); } 03048 03049 /** 03050 * @brief Parse input date string. 03051 * 03052 * This function parses a date according to the format "X" and puts the 03053 * results into a user-supplied struct tm. The result is returned by 03054 * calling time_get::do_get_date(). 03055 * 03056 * If there is a valid date string according to format "X", @a tm will 03057 * be filled in accordingly and the returned iterator will point to the 03058 * first character beyond the date string. If an error occurs before 03059 * the end, err |= ios_base::failbit. If parsing reads all the 03060 * characters, err |= ios_base::eofbit. 03061 * 03062 * @param beg Start of string to parse. 03063 * @param end End of string to parse. 03064 * @param io Source of the locale. 03065 * @param err Error flags to set. 03066 * @param tm Pointer to struct tm to fill in. 03067 * @return Iterator to first char beyond date string. 03068 */ 03069 iter_type 03070 get_date(iter_type __beg, iter_type __end, ios_base& __io, 03071 ios_base::iostate& __err, tm* __tm) const 03072 { return this->do_get_date(__beg, __end, __io, __err, __tm); } 03073 03074 /** 03075 * @brief Parse input weekday string. 03076 * 03077 * This function parses a weekday name and puts the results into a 03078 * user-supplied struct tm. The result is returned by calling 03079 * time_get::do_get_weekday(). 03080 * 03081 * Parsing starts by parsing an abbreviated weekday name. If a valid 03082 * abbreviation is followed by a character that would lead to the full 03083 * weekday name, parsing continues until the full name is found or an 03084 * error occurs. Otherwise parsing finishes at the end of the 03085 * abbreviated name. 03086 * 03087 * If an error occurs before the end, err |= ios_base::failbit. If 03088 * parsing reads all the characters, err |= ios_base::eofbit. 03089 * 03090 * @param beg Start of string to parse. 03091 * @param end End of string to parse. 03092 * @param io Source of the locale. 03093 * @param err Error flags to set. 03094 * @param tm Pointer to struct tm to fill in. 03095 * @return Iterator to first char beyond weekday name. 03096 */ 03097 iter_type 03098 get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 03099 ios_base::iostate& __err, tm* __tm) const 03100 { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } 03101 03102 /** 03103 * @brief Parse input month string. 03104 * 03105 * This function parses a month name and puts the results into a 03106 * user-supplied struct tm. The result is returned by calling 03107 * time_get::do_get_monthname(). 03108 * 03109 * Parsing starts by parsing an abbreviated month name. If a valid 03110 * abbreviation is followed by a character that would lead to the full 03111 * month name, parsing continues until the full name is found or an 03112 * error occurs. Otherwise parsing finishes at the end of the 03113 * abbreviated name. 03114 * 03115 * If an error occurs before the end, err |= ios_base::failbit. If 03116 * parsing reads all the characters, err |= 03117 * ios_base::eofbit. 03118 * 03119 * @param beg Start of string to parse. 03120 * @param end End of string to parse. 03121 * @param io Source of the locale. 03122 * @param err Error flags to set. 03123 * @param tm Pointer to struct tm to fill in. 03124 * @return Iterator to first char beyond month name. 03125 */ 03126 iter_type 03127 get_monthname(iter_type __beg, iter_type __end, ios_base& __io, 03128 ios_base::iostate& __err, tm* __tm) const 03129 { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } 03130 03131 /** 03132 * @brief Parse input year string. 03133 * 03134 * This function reads up to 4 characters to parse a year string and 03135 * puts the results into a user-supplied struct tm. The result is 03136 * returned by calling time_get::do_get_year(). 03137 * 03138 * 4 consecutive digits are interpreted as a full year. If there are 03139 * exactly 2 consecutive digits, the library interprets this as the 03140 * number of years since 1900. 03141 * 03142 * If an error occurs before the end, err |= ios_base::failbit. If 03143 * parsing reads all the characters, err |= ios_base::eofbit. 03144 * 03145 * @param beg Start of string to parse. 03146 * @param end End of string to parse. 03147 * @param io Source of the locale. 03148 * @param err Error flags to set. 03149 * @param tm Pointer to struct tm to fill in. 03150 * @return Iterator to first char beyond year. 03151 */ 03152 iter_type 03153 get_year(iter_type __beg, iter_type __end, ios_base& __io, 03154 ios_base::iostate& __err, tm* __tm) const 03155 { return this->do_get_year(__beg, __end, __io, __err, __tm); } 03156 03157 protected: 03158 /// Destructor. 03159 virtual 03160 ~time_get() { } 03161 03162 /** 03163 * @brief Return preferred order of month, day, and year. 03164 * 03165 * This function returns an enum from timebase::dateorder giving the 03166 * preferred ordering if the format "x" given to time_put::put() only 03167 * uses month, day, and year. This function is a hook for derived 03168 * classes to change the value returned. 03169 * 03170 * @return A member of timebase::dateorder. 03171 */ 03172 virtual dateorder 03173 do_date_order() const; 03174 03175 /** 03176 * @brief Parse input time string. 03177 * 03178 * This function parses a time according to the format "x" and puts the 03179 * results into a user-supplied struct tm. This function is a hook for 03180 * derived classes to change the value returned. @see get_time() for 03181 * details. 03182 * 03183 * @param beg Start of string to parse. 03184 * @param end End of string to parse. 03185 * @param io Source of the locale. 03186 * @param err Error flags to set. 03187 * @param tm Pointer to struct tm to fill in. 03188 * @return Iterator to first char beyond time string. 03189 */ 03190 virtual iter_type 03191 do_get_time(iter_type __beg, iter_type __end, ios_base& __io, 03192 ios_base::iostate& __err, tm* __tm) const; 03193 03194 /** 03195 * @brief Parse input date string. 03196 * 03197 * This function parses a date according to the format "X" and puts the 03198 * results into a user-supplied struct tm. This function is a hook for 03199 * derived classes to change the value returned. @see get_date() for 03200 * details. 03201 * 03202 * @param beg Start of string to parse. 03203 * @param end End of string to parse. 03204 * @param io Source of the locale. 03205 * @param err Error flags to set. 03206 * @param tm Pointer to struct tm to fill in. 03207 * @return Iterator to first char beyond date string. 03208 */ 03209 virtual iter_type 03210 do_get_date(iter_type __beg, iter_type __end, ios_base& __io, 03211 ios_base::iostate& __err, tm* __tm) const; 03212 03213 /** 03214 * @brief Parse input weekday string. 03215 * 03216 * This function parses a weekday name and puts the results into a 03217 * user-supplied struct tm. This function is a hook for derived 03218 * classes to change the value returned. @see get_weekday() for 03219 * details. 03220 * 03221 * @param beg Start of string to parse. 03222 * @param end End of string to parse. 03223 * @param io Source of the locale. 03224 * @param err Error flags to set. 03225 * @param tm Pointer to struct tm to fill in. 03226 * @return Iterator to first char beyond weekday name. 03227 */ 03228 virtual iter_type 03229 do_get_weekday(iter_type __beg, iter_type __end, ios_base&, 03230 ios_base::iostate& __err, tm* __tm) const; 03231 03232 /** 03233 * @brief Parse input month string. 03234 * 03235 * This function parses a month name and puts the results into a 03236 * user-supplied struct tm. This function is a hook for derived 03237 * classes to change the value returned. @see get_monthname() for 03238 * details. 03239 * 03240 * @param beg Start of string to parse. 03241 * @param end End of string to parse. 03242 * @param io Source of the locale. 03243 * @param err Error flags to set. 03244 * @param tm Pointer to struct tm to fill in. 03245 * @return Iterator to first char beyond month name. 03246 */ 03247 virtual iter_type 03248 do_get_monthname(iter_type __beg, iter_type __end, ios_base&, 03249 ios_base::iostate& __err, tm* __tm) const; 03250 03251 /** 03252 * @brief Parse input year string. 03253 * 03254 * This function reads up to 4 characters to parse a year string and 03255 * puts the results into a user-supplied struct tm. This function is a 03256 * hook for derived classes to change the value returned. @see 03257 * get_year() for details. 03258 * 03259 * @param beg Start of string to parse. 03260 * @param end End of string to parse. 03261 * @param io Source of the locale. 03262 * @param err Error flags to set. 03263 * @param tm Pointer to struct tm to fill in. 03264 * @return Iterator to first char beyond year. 03265 */ 03266 virtual iter_type 03267 do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 03268 ios_base::iostate& __err, tm* __tm) const; 03269 03270 // Extract numeric component of length __len. 03271 iter_type 03272 _M_extract_num(iter_type __beg, iter_type __end, int& __member, 03273 int __min, int __max, size_t __len, 03274 ios_base& __io, ios_base::iostate& __err) const; 03275 03276 // Extract day or month name, or any unique array of string 03277 // literals in a const _CharT* array. 03278 iter_type 03279 _M_extract_name(iter_type __beg, iter_type __end, int& __member, 03280 const _CharT** __names, size_t __indexlen, 03281 ios_base& __io, ios_base::iostate& __err) const; 03282 03283 // Extract on a component-by-component basis, via __format argument. 03284 iter_type 03285 _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 03286 ios_base::iostate& __err, tm* __tm, 03287 const _CharT* __format) const; 03288 }; 03289 03290 template<typename _CharT, typename _InIter> 03291 locale::id time_get<_CharT, _InIter>::id; 03292 03293 /// @brief class time_get_byname [22.2.5.2]. 03294 template<typename _CharT, typename _InIter> 03295 class time_get_byname : public time_get<_CharT, _InIter> 03296 { 03297 public: 03298 // Types: 03299 typedef _CharT char_type; 03300 typedef _InIter iter_type; 03301 03302 explicit 03303 time_get_byname(const char*, size_t __refs = 0) 03304 : time_get<_CharT, _InIter>(__refs) { } 03305 03306 protected: 03307 virtual 03308 ~time_get_byname() { } 03309 }; 03310 03311 /** 03312 * @brief Facet for outputting dates and times. 03313 * 03314 * This facet encapsulates the code to format and output dates and times 03315 * according to formats used by strftime(). 03316 * 03317 * The time_put template uses protected virtual functions to provide the 03318 * actual results. The public accessors forward the call to the virtual 03319 * functions. These virtual functions are hooks for developers to 03320 * implement the behavior they require from the time_put facet. 03321 */ 03322 template<typename _CharT, typename _OutIter> 03323 class time_put : public locale::facet 03324 { 03325 public: 03326 // Types: 03327 //@{ 03328 /// Public typedefs 03329 typedef _CharT char_type; 03330 typedef _OutIter iter_type; 03331 //@} 03332 03333 /// Numpunct facet id. 03334 static locale::id id; 03335 03336 /** 03337 * @brief Constructor performs initialization. 03338 * 03339 * This is the constructor provided by the standard. 03340 * 03341 * @param refs Passed to the base facet class. 03342 */ 03343 explicit 03344 time_put(size_t __refs = 0) 03345 : facet(__refs) { } 03346 03347 /** 03348 * @brief Format and output a time or date. 03349 * 03350 * This function formats the data in struct tm according to the 03351 * provided format string. The format string is interpreted as by 03352 * strftime(). 03353 * 03354 * @param s The stream to write to. 03355 * @param io Source of locale. 03356 * @param fill char_type to use for padding. 03357 * @param tm Struct tm with date and time info to format. 03358 * @param beg Start of format string. 03359 * @param end End of format string. 03360 * @return Iterator after writing. 03361 */ 03362 iter_type 03363 put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 03364 const _CharT* __beg, const _CharT* __end) const; 03365 03366 /** 03367 * @brief Format and output a time or date. 03368 * 03369 * This function formats the data in struct tm according to the 03370 * provided format char and optional modifier. The format and modifier 03371 * are interpreted as by strftime(). It does so by returning 03372 * time_put::do_put(). 03373 * 03374 * @param s The stream to write to. 03375 * @param io Source of locale. 03376 * @param fill char_type to use for padding. 03377 * @param tm Struct tm with date and time info to format. 03378 * @param format Format char. 03379 * @param mod Optional modifier char. 03380 * @return Iterator after writing. 03381 */ 03382 iter_type 03383 put(iter_type __s, ios_base& __io, char_type __fill, 03384 const tm* __tm, char __format, char __mod = 0) const 03385 { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } 03386 03387 protected: 03388 /// Destructor. 03389 virtual 03390 ~time_put() 03391 { } 03392 03393 /** 03394 * @brief Format and output a time or date. 03395 * 03396 * This function formats the data in struct tm according to the 03397 * provided format char and optional modifier. This function is a hook 03398 * for derived classes to change the value returned. @see put() for 03399 * more details. 03400 * 03401 * @param s The stream to write to. 03402 * @param io Source of locale. 03403 * @param fill char_type to use for padding. 03404 * @param tm Struct tm with date and time info to format. 03405 * @param format Format char. 03406 * @param mod Optional modifier char. 03407 * @return Iterator after writing. 03408 */ 03409 virtual iter_type 03410 do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 03411 char __format, char __mod) const; 03412 }; 03413 03414 template<typename _CharT, typename _OutIter> 03415 locale::id time_put<_CharT, _OutIter>::id; 03416 03417 /// @brief class time_put_byname [22.2.5.4]. 03418 template<typename _CharT, typename _OutIter> 03419 class time_put_byname : public time_put<_CharT, _OutIter> 03420 { 03421 public: 03422 // Types: 03423 typedef _CharT char_type; 03424 typedef _OutIter iter_type; 03425 03426 explicit 03427 time_put_byname(const char*, size_t __refs = 0) 03428 : time_put<_CharT, _OutIter>(__refs) 03429 { }; 03430 03431 protected: 03432 virtual 03433 ~time_put_byname() { } 03434 }; 03435 03436 03437 /** 03438 * @brief Money format ordering data. 03439 * 03440 * This class contains an ordered array of 4 fields to represent the 03441 * pattern for formatting a money amount. Each field may contain one entry 03442 * from the part enum. symbol, sign, and value must be present and the 03443 * remaining field must contain either none or space. @see 03444 * moneypunct::pos_format() and moneypunct::neg_format() for details of how 03445 * these fields are interpreted. 03446 */ 03447 class money_base 03448 { 03449 public: 03450 enum part { none, space, symbol, sign, value }; 03451 struct pattern { char field[4]; }; 03452 03453 static const pattern _S_default_pattern; 03454 03455 enum 03456 { 03457 _S_minus, 03458 _S_zero, 03459 _S_end = 11 03460 }; 03461 03462 // String literal of acceptable (narrow) input/output, for 03463 // money_get/money_put. "-0123456789" 03464 static const char* _S_atoms; 03465 03466 // Construct and return valid pattern consisting of some combination of: 03467 // space none symbol sign value 03468 static pattern 03469 _S_construct_pattern(char __precedes, char __space, char __posn); 03470 }; 03471 03472 template<typename _CharT, bool _Intl> 03473 struct __moneypunct_cache : public locale::facet 03474 { 03475 const char* _M_grouping; 03476 size_t _M_grouping_size; 03477 bool _M_use_grouping; 03478 _CharT _M_decimal_point; 03479 _CharT _M_thousands_sep; 03480 const _CharT* _M_curr_symbol; 03481 size_t _M_curr_symbol_size; 03482 const _CharT* _M_positive_sign; 03483 size_t _M_positive_sign_size; 03484 const _CharT* _M_negative_sign; 03485 size_t _M_negative_sign_size; 03486 int _M_frac_digits; 03487 money_base::pattern _M_pos_format; 03488 money_base::pattern _M_neg_format; 03489 03490 // A list of valid numeric literals for input and output: in the standard 03491 // "C" locale, this is "-0123456789". This array contains the chars after 03492 // having been passed through the current locale's ctype<_CharT>.widen(). 03493 _CharT _M_atoms[money_base::_S_end]; 03494 03495 bool _M_allocated; 03496 03497 __moneypunct_cache(size_t __refs = 0) : facet(__refs), 03498 _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), 03499 _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), 03500 _M_curr_symbol(NULL), _M_curr_symbol_size(0), 03501 _M_positive_sign(NULL), _M_positive_sign_size(0), 03502 _M_negative_sign(NULL), _M_negative_sign_size(0), 03503 _M_frac_digits(0), 03504 _M_pos_format(money_base::pattern()), 03505 _M_neg_format(money_base::pattern()), _M_allocated(false) 03506 { } 03507 03508 ~__moneypunct_cache(); 03509 03510 void 03511 _M_cache(const locale& __loc); 03512 03513 private: 03514 __moneypunct_cache& 03515 operator=(const __moneypunct_cache&); 03516 03517 explicit 03518 __moneypunct_cache(const __moneypunct_cache&); 03519 }; 03520 03521 template<typename _CharT, bool _Intl> 03522 __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() 03523 { 03524 if (_M_allocated) 03525 { 03526 delete [] _M_grouping; 03527 delete [] _M_curr_symbol; 03528 delete [] _M_positive_sign; 03529 delete [] _M_negative_sign; 03530 } 03531 } 03532 03533 /** 03534 * @brief Facet for formatting data for money amounts. 03535 * 03536 * This facet encapsulates the punctuation, grouping and other formatting 03537 * features of money amount string representations. 03538 */ 03539 template<typename _CharT, bool _Intl> 03540 class moneypunct : public locale::facet, public money_base 03541 { 03542 public: 03543 // Types: 03544 //@{ 03545 /// Public typedefs 03546 typedef _CharT char_type; 03547 typedef basic_string<_CharT> string_type; 03548 //@} 03549 typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 03550 03551 private: 03552 __cache_type* _M_data; 03553 03554 public: 03555 /// This value is provided by the standard, but no reason for its 03556 /// existence. 03557 static const bool intl = _Intl; 03558 /// Numpunct facet id. 03559 static locale::id id; 03560 03561 /** 03562 * @brief Constructor performs initialization. 03563 * 03564 * This is the constructor provided by the standard. 03565 * 03566 * @param refs Passed to the base facet class. 03567 */ 03568 explicit 03569 moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) 03570 { _M_initialize_moneypunct(); } 03571 03572 /** 03573 * @brief Constructor performs initialization. 03574 * 03575 * This is an internal constructor. 03576 * 03577 * @param cache Cache for optimization. 03578 * @param refs Passed to the base facet class. 03579 */ 03580 explicit 03581 moneypunct(__cache_type* __cache, size_t __refs = 0) 03582 : facet(__refs), _M_data(__cache) 03583 { _M_initialize_moneypunct(); } 03584 03585 /** 03586 * @brief Internal constructor. Not for general use. 03587 * 03588 * This is a constructor for use by the library itself to set up new 03589 * locales. 03590 * 03591 * @param cloc The "C" locale. 03592 * @param s The name of a locale. 03593 * @param refs Passed to the base facet class. 03594 */ 03595 explicit 03596 moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) 03597 : facet(__refs), _M_data(NULL) 03598 { _M_initialize_moneypunct(__cloc, __s); } 03599 03600 /** 03601 * @brief Return decimal point character. 03602 * 03603 * This function returns a char_type to use as a decimal point. It 03604 * does so by returning returning 03605 * moneypunct<char_type>::do_decimal_point(). 03606 * 03607 * @return @a char_type representing a decimal point. 03608 */ 03609 char_type 03610 decimal_point() const 03611 { return this->do_decimal_point(); } 03612 03613 /** 03614 * @brief Return thousands separator character. 03615 * 03616 * This function returns a char_type to use as a thousands 03617 * separator. It does so by returning returning 03618 * moneypunct<char_type>::do_thousands_sep(). 03619 * 03620 * @return char_type representing a thousands separator. 03621 */ 03622 char_type 03623 thousands_sep() const 03624 { return this->do_thousands_sep(); } 03625 03626 /** 03627 * @brief Return grouping specification. 03628 * 03629 * This function returns a string representing groupings for the 03630 * integer part of an amount. Groupings indicate where thousands 03631 * separators should be inserted. 03632 * 03633 * Each char in the return string is interpret as an integer rather 03634 * than a character. These numbers represent the number of digits in a 03635 * group. The first char in the string represents the number of digits 03636 * in the least significant group. If a char is negative, it indicates 03637 * an unlimited number of digits for the group. If more chars from the 03638 * string are required to group a number, the last char is used 03639 * repeatedly. 03640 * 03641 * For example, if the grouping() returns "\003\002" and is applied to 03642 * the number 123456789, this corresponds to 12,34,56,789. Note that 03643 * if the string was "32", this would put more than 50 digits into the 03644 * least significant group if the character set is ASCII. 03645 * 03646 * The string is returned by calling 03647 * moneypunct<char_type>::do_grouping(). 03648 * 03649 * @return string representing grouping specification. 03650 */ 03651 string 03652 grouping() const 03653 { return this->do_grouping(); } 03654 03655 /** 03656 * @brief Return currency symbol string. 03657 * 03658 * This function returns a string_type to use as a currency symbol. It 03659 * does so by returning returning 03660 * moneypunct<char_type>::do_curr_symbol(). 03661 * 03662 * @return @a string_type representing a currency symbol. 03663 */ 03664 string_type 03665 curr_symbol() const 03666 { return this->do_curr_symbol(); } 03667 03668 /** 03669 * @brief Return positive sign string. 03670 * 03671 * This function returns a string_type to use as a sign for positive 03672 * amounts. It does so by returning returning 03673 * moneypunct<char_type>::do_positive_sign(). 03674 * 03675 * If the return value contains more than one character, the first 03676 * character appears in the position indicated by pos_format() and the 03677 * remainder appear at the end of the formatted string. 03678 * 03679 * @return @a string_type representing a positive sign. 03680 */ 03681 string_type 03682 positive_sign() const 03683 { return this->do_positive_sign(); } 03684 03685 /** 03686 * @brief Return negative sign string. 03687 * 03688 * This function returns a string_type to use as a sign for negative 03689 * amounts. It does so by returning returning 03690 * moneypunct<char_type>::do_negative_sign(). 03691 * 03692 * If the return value contains more than one character, the first 03693 * character appears in the position indicated by neg_format() and the 03694 * remainder appear at the end of the formatted string. 03695 * 03696 * @return @a string_type representing a negative sign. 03697 */ 03698 string_type 03699 negative_sign() const 03700 { return this->do_negative_sign(); } 03701 03702 /** 03703 * @brief Return number of digits in fraction. 03704 * 03705 * This function returns the exact number of digits that make up the 03706 * fractional part of a money amount. It does so by returning 03707 * returning moneypunct<char_type>::do_frac_digits(). 03708 * 03709 * The fractional part of a money amount is optional. But if it is 03710 * present, there must be frac_digits() digits. 03711 * 03712 * @return Number of digits in amount fraction. 03713 */ 03714 int 03715 frac_digits() const 03716 { return this->do_frac_digits(); } 03717 03718 //@{ 03719 /** 03720 * @brief Return pattern for money values. 03721 * 03722 * This function returns a pattern describing the formatting of a 03723 * positive or negative valued money amount. It does so by returning 03724 * returning moneypunct<char_type>::do_pos_format() or 03725 * moneypunct<char_type>::do_neg_format(). 03726 * 03727 * The pattern has 4 fields describing the ordering of symbol, sign, 03728 * value, and none or space. There must be one of each in the pattern. 03729 * The none and space enums may not appear in the first field and space 03730 * may not appear in the final field. 03731 * 03732 * The parts of a money string must appear in the order indicated by 03733 * the fields of the pattern. The symbol field indicates that the 03734 * value of curr_symbol() may be present. The sign field indicates 03735 * that the value of positive_sign() or negative_sign() must be 03736 * present. The value field indicates that the absolute value of the 03737 * money amount is present. none indicates 0 or more whitespace 03738 * characters, except at the end, where it permits no whitespace. 03739 * space indicates that 1 or more whitespace characters must be 03740 * present. 03741 * 03742 * For example, for the US locale and pos_format() pattern 03743 * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == 03744 * '+', and value 10.01, and options set to force the symbol, the 03745 * corresponding string is "$+10.01". 03746 * 03747 * @return Pattern for money values. 03748 */ 03749 pattern 03750 pos_format() const 03751 { return this->do_pos_format(); } 03752 03753 pattern 03754 neg_format() const 03755 { return this->do_neg_format(); } 03756 //@} 03757 03758 protected: 03759 /// Destructor. 03760 virtual 03761 ~moneypunct(); 03762 03763 /** 03764 * @brief Return decimal point character. 03765 * 03766 * Returns a char_type to use as a decimal point. This function is a 03767 * hook for derived classes to change the value returned. 03768 * 03769 * @return @a char_type representing a decimal point. 03770 */ 03771 virtual char_type 03772 do_decimal_point() const 03773 { return _M_data->_M_decimal_point; } 03774 03775 /** 03776 * @brief Return thousands separator character. 03777 * 03778 * Returns a char_type to use as a thousands separator. This function 03779 * is a hook for derived classes to change the value returned. 03780 * 03781 * @return @a char_type representing a thousands separator. 03782 */ 03783 virtual char_type 03784 do_thousands_sep() const 03785 { return _M_data->_M_thousands_sep; } 03786 03787 /** 03788 * @brief Return grouping specification. 03789 * 03790 * Returns a string representing groupings for the integer part of a 03791 * number. This function is a hook for derived classes to change the 03792 * value returned. @see grouping() for details. 03793 * 03794 * @return String representing grouping specification. 03795 */ 03796 virtual string 03797 do_grouping() const 03798 { return _M_data->_M_grouping; } 03799 03800 /** 03801 * @brief Return currency symbol string. 03802 * 03803 * This function returns a string_type to use as a currency symbol. 03804 * This function is a hook for derived classes to change the value 03805 * returned. @see curr_symbol() for details. 03806 * 03807 * @return @a string_type representing a currency symbol. 03808 */ 03809 virtual string_type 03810 do_curr_symbol() const 03811 { return _M_data->_M_curr_symbol; } 03812 03813 /** 03814 * @brief Return positive sign string. 03815 * 03816 * This function returns a string_type to use as a sign for positive 03817 * amounts. This function is a hook for derived classes to change the 03818 * value returned. @see positive_sign() for details. 03819 * 03820 * @return @a string_type representing a positive sign. 03821 */ 03822 virtual string_type 03823 do_positive_sign() const 03824 { return _M_data->_M_positive_sign; } 03825 03826 /** 03827 * @brief Return negative sign string. 03828 * 03829 * This function returns a string_type to use as a sign for negative 03830 * amounts. This function is a hook for derived classes to change the 03831 * value returned. @see negative_sign() for details. 03832 * 03833 * @return @a string_type representing a negative sign. 03834 */ 03835 virtual string_type 03836 do_negative_sign() const 03837 { return _M_data->_M_negative_sign; } 03838 03839 /** 03840 * @brief Return number of digits in fraction. 03841 * 03842 * This function returns the exact number of digits that make up the 03843 * fractional part of a money amount. This function is a hook for 03844 * derived classes to change the value returned. @see frac_digits() 03845 * for details. 03846 * 03847 * @return Number of digits in amount fraction. 03848 */ 03849 virtual int 03850 do_frac_digits() const 03851 { return _M_data->_M_frac_digits; } 03852 03853 /** 03854 * @brief Return pattern for money values. 03855 * 03856 * This function returns a pattern describing the formatting of a 03857 * positive valued money amount. This function is a hook for derived 03858 * classes to change the value returned. @see pos_format() for 03859 * details. 03860 * 03861 * @return Pattern for money values. 03862 */ 03863 virtual pattern 03864 do_pos_format() const 03865 { return _M_data->_M_pos_format; } 03866 03867 /** 03868 * @brief Return pattern for money values. 03869 * 03870 * This function returns a pattern describing the formatting of a 03871 * negative valued money amount. This function is a hook for derived 03872 * classes to change the value returned. @see neg_format() for 03873 * details. 03874 * 03875 * @return Pattern for money values. 03876 */ 03877 virtual pattern 03878 do_neg_format() const 03879 { return _M_data->_M_neg_format; } 03880 03881 // For use at construction time only. 03882 void 03883 _M_initialize_moneypunct(__c_locale __cloc = NULL, 03884 const char* __name = NULL); 03885 }; 03886 03887 template<typename _CharT, bool _Intl> 03888 locale::id moneypunct<_CharT, _Intl>::id; 03889 03890 template<typename _CharT, bool _Intl> 03891 const bool moneypunct<_CharT, _Intl>::intl; 03892 03893 template<> 03894 moneypunct<char, true>::~moneypunct(); 03895 03896 template<> 03897 moneypunct<char, false>::~moneypunct(); 03898 03899 template<> 03900 void 03901 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*); 03902 03903 template<> 03904 void 03905 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*); 03906 03907 #ifdef _GLIBCXX_USE_WCHAR_T 03908 template<> 03909 moneypunct<wchar_t, true>::~moneypunct(); 03910 03911 template<> 03912 moneypunct<wchar_t, false>::~moneypunct(); 03913 03914 template<> 03915 void 03916 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale, 03917 const char*); 03918 03919 template<> 03920 void 03921 moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale, 03922 const char*); 03923 #endif 03924 03925 /// @brief class moneypunct_byname [22.2.6.4]. 03926 template<typename _CharT, bool _Intl> 03927 class moneypunct_byname : public moneypunct<_CharT, _Intl> 03928 { 03929 public: 03930 typedef _CharT char_type; 03931 typedef basic_string<_CharT> string_type; 03932 03933 static const bool intl = _Intl; 03934 03935 explicit 03936 moneypunct_byname(const char* __s, size_t __refs = 0) 03937 : moneypunct<_CharT, _Intl>(__refs) 03938 { 03939 if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 03940 { 03941 __c_locale __tmp; 03942 this->_S_create_c_locale(__tmp, __s); 03943 this->_M_initialize_moneypunct(__tmp); 03944 this->_S_destroy_c_locale(__tmp); 03945 } 03946 } 03947 03948 protected: 03949 virtual 03950 ~moneypunct_byname() { } 03951 }; 03952 03953 template<typename _CharT, bool _Intl> 03954 const bool moneypunct_byname<_CharT, _Intl>::intl; 03955 03956 /** 03957 * @brief Facet for parsing monetary amounts. 03958 * 03959 * This facet encapsulates the code to parse and return a monetary 03960 * amount from a string. 03961 * 03962 * The money_get template uses protected virtual functions to 03963 * provide the actual results. The public accessors forward the 03964 * call to the virtual functions. These virtual functions are 03965 * hooks for developers to implement the behavior they require from 03966 * the money_get facet. 03967 */ 03968 template<typename _CharT, typename _InIter> 03969 class money_get : public locale::facet 03970 { 03971 public: 03972 // Types: 03973 //@{ 03974 /// Public typedefs 03975 typedef _CharT char_type; 03976 typedef _InIter iter_type; 03977 typedef basic_string<_CharT> string_type; 03978 //@} 03979 03980 /// Numpunct facet id. 03981 static locale::id id; 03982 03983 /** 03984 * @brief Constructor performs initialization. 03985 * 03986 * This is the constructor provided by the standard. 03987 * 03988 * @param refs Passed to the base facet class. 03989 */ 03990 explicit 03991 money_get(size_t __refs = 0) : facet(__refs) { } 03992 03993 /** 03994 * @brief Read and parse a monetary value. 03995 * 03996 * This function reads characters from @a s, interprets them as a 03997 * monetary value according to moneypunct and ctype facets retrieved 03998 * from io.getloc(), and returns the result in @a units as an integral 03999 * value moneypunct::frac_digits() * the actual amount. For example, 04000 * the string $10.01 in a US locale would store 1001 in @a units. 04001 * 04002 * Any characters not part of a valid money amount are not consumed. 04003 * 04004 * If a money value cannot be parsed from the input stream, sets 04005 * err=(err|io.failbit). If the stream is consumed before finishing 04006 * parsing, sets err=(err|io.failbit|io.eofbit). @a units is 04007 * unchanged if parsing fails. 04008 * 04009 * This function works by returning the result of do_get(). 04010 * 04011 * @param s Start of characters to parse. 04012 * @param end End of characters to parse. 04013 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04014 * @param io Source of facets and io state. 04015 * @param err Error field to set if parsing fails. 04016 * @param units Place to store result of parsing. 04017 * @return Iterator referencing first character beyond valid money 04018 * amount. 04019 */ 04020 iter_type 04021 get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 04022 ios_base::iostate& __err, long double& __units) const 04023 { return this->do_get(__s, __end, __intl, __io, __err, __units); } 04024 04025 /** 04026 * @brief Read and parse a monetary value. 04027 * 04028 * This function reads characters from @a s, interprets them as a 04029 * monetary value according to moneypunct and ctype facets retrieved 04030 * from io.getloc(), and returns the result in @a digits. For example, 04031 * the string $10.01 in a US locale would store "1001" in @a digits. 04032 * 04033 * Any characters not part of a valid money amount are not consumed. 04034 * 04035 * If a money value cannot be parsed from the input stream, sets 04036 * err=(err|io.failbit). If the stream is consumed before finishing 04037 * parsing, sets err=(err|io.failbit|io.eofbit). 04038 * 04039 * This function works by returning the result of do_get(). 04040 * 04041 * @param s Start of characters to parse. 04042 * @param end End of characters to parse. 04043 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04044 * @param io Source of facets and io state. 04045 * @param err Error field to set if parsing fails. 04046 * @param digits Place to store result of parsing. 04047 * @return Iterator referencing first character beyond valid money 04048 * amount. 04049 */ 04050 iter_type 04051 get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 04052 ios_base::iostate& __err, string_type& __digits) const 04053 { return this->do_get(__s, __end, __intl, __io, __err, __digits); } 04054 04055 protected: 04056 /// Destructor. 04057 virtual 04058 ~money_get() { } 04059 04060 /** 04061 * @brief Read and parse a monetary value. 04062 * 04063 * This function reads and parses characters representing a monetary 04064 * value. This function is a hook for derived classes to change the 04065 * value returned. @see get() for details. 04066 */ 04067 virtual iter_type 04068 do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 04069 ios_base::iostate& __err, long double& __units) const; 04070 04071 /** 04072 * @brief Read and parse a monetary value. 04073 * 04074 * This function reads and parses characters representing a monetary 04075 * value. This function is a hook for derived classes to change the 04076 * value returned. @see get() for details. 04077 */ 04078 virtual iter_type 04079 do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 04080 ios_base::iostate& __err, string_type& __digits) const; 04081 04082 template<bool _Intl> 04083 iter_type 04084 _M_extract(iter_type __s, iter_type __end, ios_base& __io, 04085 ios_base::iostate& __err, string& __digits) const; 04086 }; 04087 04088 template<typename _CharT, typename _InIter> 04089 locale::id money_get<_CharT, _InIter>::id; 04090 04091 /** 04092 * @brief Facet for outputting monetary amounts. 04093 * 04094 * This facet encapsulates the code to format and output a monetary 04095 * amount. 04096 * 04097 * The money_put template uses protected virtual functions to 04098 * provide the actual results. The public accessors forward the 04099 * call to the virtual functions. These virtual functions are 04100 * hooks for developers to implement the behavior they require from 04101 * the money_put facet. 04102 */ 04103 template<typename _CharT, typename _OutIter> 04104 class money_put : public locale::facet 04105 { 04106 public: 04107 //@{ 04108 /// Public typedefs 04109 typedef _CharT char_type; 04110 typedef _OutIter iter_type; 04111 typedef basic_string<_CharT> string_type; 04112 //@} 04113 04114 /// Numpunct facet id. 04115 static locale::id id; 04116 04117 /** 04118 * @brief Constructor performs initialization. 04119 * 04120 * This is the constructor provided by the standard. 04121 * 04122 * @param refs Passed to the base facet class. 04123 */ 04124 explicit 04125 money_put(size_t __refs = 0) : facet(__refs) { } 04126 04127 /** 04128 * @brief Format and output a monetary value. 04129 * 04130 * This function formats @a units as a monetary value according to 04131 * moneypunct and ctype facets retrieved from io.getloc(), and writes 04132 * the resulting characters to @a s. For example, the value 1001 in a 04133 * US locale would write "$10.01" to @a s. 04134 * 04135 * This function works by returning the result of do_put(). 04136 * 04137 * @param s The stream to write to. 04138 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04139 * @param io Source of facets and io state. 04140 * @param fill char_type to use for padding. 04141 * @param units Place to store result of parsing. 04142 * @return Iterator after writing. 04143 */ 04144 iter_type 04145 put(iter_type __s, bool __intl, ios_base& __io, 04146 char_type __fill, long double __units) const 04147 { return this->do_put(__s, __intl, __io, __fill, __units); } 04148 04149 /** 04150 * @brief Format and output a monetary value. 04151 * 04152 * This function formats @a digits as a monetary value according to 04153 * moneypunct and ctype facets retrieved from io.getloc(), and writes 04154 * the resulting characters to @a s. For example, the string "1001" in 04155 * a US locale would write "$10.01" to @a s. 04156 * 04157 * This function works by returning the result of do_put(). 04158 * 04159 * @param s The stream to write to. 04160 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04161 * @param io Source of facets and io state. 04162 * @param fill char_type to use for padding. 04163 * @param units Place to store result of parsing. 04164 * @return Iterator after writing. 04165 */ 04166 iter_type 04167 put(iter_type __s, bool __intl, ios_base& __io, 04168 char_type __fill, const string_type& __digits) const 04169 { return this->do_put(__s, __intl, __io, __fill, __digits); } 04170 04171 protected: 04172 /// Destructor. 04173 virtual 04174 ~money_put() { } 04175 04176 /** 04177 * @brief Format and output a monetary value. 04178 * 04179 * This function formats @a units as a monetary value according to 04180 * moneypunct and ctype facets retrieved from io.getloc(), and writes 04181 * the resulting characters to @a s. For example, the value 1001 in a 04182 * US locale would write "$10.01" to @a s. 04183 * 04184 * This function is a hook for derived classes to change the value 04185 * returned. @see put(). 04186 * 04187 * @param s The stream to write to. 04188 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04189 * @param io Source of facets and io state. 04190 * @param fill char_type to use for padding. 04191 * @param units Place to store result of parsing. 04192 * @return Iterator after writing. 04193 */ 04194 virtual iter_type 04195 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 04196 long double __units) const; 04197 04198 /** 04199 * @brief Format and output a monetary value. 04200 * 04201 * This function formats @a digits as a monetary value according to 04202 * moneypunct and ctype facets retrieved from io.getloc(), and writes 04203 * the resulting characters to @a s. For example, the string "1001" in 04204 * a US locale would write "$10.01" to @a s. 04205 * 04206 * This function is a hook for derived classes to change the value 04207 * returned. @see put(). 04208 * 04209 * @param s The stream to write to. 04210 * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 04211 * @param io Source of facets and io state. 04212 * @param fill char_type to use for padding. 04213 * @param units Place to store result of parsing. 04214 * @return Iterator after writing. 04215 */ 04216 virtual iter_type 04217 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 04218 const string_type& __digits) const; 04219 04220 template<bool _Intl> 04221 iter_type 04222 _M_insert(iter_type __s, ios_base& __io, char_type __fill, 04223 const string_type& __digits) const; 04224 }; 04225 04226 template<typename _CharT, typename _OutIter> 04227 locale::id money_put<_CharT, _OutIter>::id; 04228 04229 /** 04230 * @brief Messages facet base class providing catalog typedef. 04231 */ 04232 struct messages_base 04233 { 04234 typedef int catalog; 04235 }; 04236 04237 /** 04238 * @brief Facet for handling message catalogs 04239 * 04240 * This facet encapsulates the code to retrieve messages from 04241 * message catalogs. The only thing defined by the standard for this facet 04242 * is the interface. All underlying functionality is 04243 * implementation-defined. 04244 * 04245 * This library currently implements 3 versions of the message facet. The 04246 * first version (gnu) is a wrapper around gettext, provided by libintl. 04247 * The second version (ieee) is a wrapper around catgets. The final 04248 * version (default) does no actual translation. These implementations are 04249 * only provided for char and wchar_t instantiations. 04250 * 04251 * The messages template uses protected virtual functions to 04252 * provide the actual results. The public accessors forward the 04253 * call to the virtual functions. These virtual functions are 04254 * hooks for developers to implement the behavior they require from 04255 * the messages facet. 04256 */ 04257 template<typename _CharT> 04258 class messages : public locale::facet, public messages_base 04259 { 04260 public: 04261 // Types: 04262 //@{ 04263 /// Public typedefs 04264 typedef _CharT char_type; 04265 typedef basic_string<_CharT> string_type; 04266 //@} 04267 04268 protected: 04269 // Underlying "C" library locale information saved from 04270 // initialization, needed by messages_byname as well. 04271 __c_locale _M_c_locale_messages; 04272 const char* _M_name_messages; 04273 04274 public: 04275 /// Numpunct facet id. 04276 static locale::id id; 04277 04278 /** 04279 * @brief Constructor performs initialization. 04280 * 04281 * This is the constructor provided by the standard. 04282 * 04283 * @param refs Passed to the base facet class. 04284 */ 04285 explicit 04286 messages(size_t __refs = 0); 04287 04288 // Non-standard. 04289 /** 04290 * @brief Internal constructor. Not for general use. 04291 * 04292 * This is a constructor for use by the library itself to set up new 04293 * locales. 04294 * 04295 * @param cloc The "C" locale. 04296 * @param s The name of a locale. 04297 * @param refs Refcount to pass to the base class. 04298 */ 04299 explicit 04300 messages(__c_locale __cloc, const char* __s, size_t __refs = 0); 04301 04302 /* 04303 * @brief Open a message catalog. 04304 * 04305 * This function opens and returns a handle to a message catalog by 04306 * returning do_open(s, loc). 04307 * 04308 * @param s The catalog to open. 04309 * @param loc Locale to use for character set conversions. 04310 * @return Handle to the catalog or value < 0 if open fails. 04311 */ 04312 catalog 04313 open(const basic_string<char>& __s, const locale& __loc) const 04314 { return this->do_open(__s, __loc); } 04315 04316 // Non-standard and unorthodox, yet effective. 04317 /* 04318 * @brief Open a message catalog. 04319 * 04320 * This non-standard function opens and returns a handle to a message 04321 * catalog by returning do_open(s, loc). The third argument provides a 04322 * message catalog root directory for gnu gettext and is ignored 04323 * otherwise. 04324 * 04325 * @param s The catalog to open. 04326 * @param loc Locale to use for character set conversions. 04327 * @param dir Message catalog root directory. 04328 * @return Handle to the catalog or value < 0 if open fails. 04329 */ 04330 catalog 04331 open(const basic_string<char>&, const locale&, const char*) const; 04332 04333 /* 04334 * @brief Look up a string in a message catalog. 04335 * 04336 * This function retrieves and returns a message from a catalog by 04337 * returning do_get(c, set, msgid, s). 04338 * 04339 * For gnu, @a set and @a msgid are ignored. Returns gettext(s). 04340 * For default, returns s. For ieee, returns catgets(c,set,msgid,s). 04341 * 04342 * @param c The catalog to access. 04343 * @param set Implementation-defined. 04344 * @param msgid Implementation-defined. 04345 * @param s Default return value if retrieval fails. 04346 * @return Retrieved message or @a s if get fails. 04347 */ 04348 string_type 04349 get(catalog __c, int __set, int __msgid, const string_type& __s) const 04350 { return this->do_get(__c, __set, __msgid, __s); } 04351 04352 /* 04353 * @brief Close a message catalog. 04354 * 04355 * Closes catalog @a c by calling do_close(c). 04356 * 04357 * @param c The catalog to close. 04358 */ 04359 void 04360 close(catalog __c) const 04361 { return this->do_close(__c); } 04362 04363 protected: 04364 /// Destructor. 04365 virtual 04366 ~messages(); 04367 04368 /* 04369 * @brief Open a message catalog. 04370 * 04371 * This function opens and returns a handle to a message catalog in an 04372 * implementation-defined manner. This function is a hook for derived 04373 * classes to change the value returned. 04374 * 04375 * @param s The catalog to open. 04376 * @param loc Locale to use for character set conversions. 04377 * @return Handle to the opened catalog, value < 0 if open failed. 04378 */ 04379 virtual catalog 04380 do_open(const basic_string<char>&, const locale&) const; 04381 04382 /* 04383 * @brief Look up a string in a message catalog. 04384 * 04385 * This function retrieves and returns a message from a catalog in an 04386 * implementation-defined manner. This function is a hook for derived 04387 * classes to change the value returned. 04388 * 04389 * For gnu, @a set and @a msgid are ignored. Returns gettext(s). 04390 * For default, returns s. For ieee, returns catgets(c,set,msgid,s). 04391 * 04392 * @param c The catalog to access. 04393 * @param set Implementation-defined. 04394 * @param msgid Implementation-defined. 04395 * @param s Default return value if retrieval fails. 04396 * @return Retrieved message or @a s if get fails. 04397 */ 04398 virtual string_type 04399 do_get(catalog, int, int, const string_type& __dfault) const; 04400 04401 /* 04402 * @brief Close a message catalog. 04403 * 04404 * @param c The catalog to close. 04405 */ 04406 virtual void 04407 do_close(catalog) const; 04408 04409 // Returns a locale and codeset-converted string, given a char* message. 04410 char* 04411 _M_convert_to_char(const string_type& __msg) const 04412 { 04413 // XXX 04414 return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str())); 04415 } 04416 04417 // Returns a locale and codeset-converted string, given a char* message. 04418 string_type 04419 _M_convert_from_char(char*) const 04420 { 04421 #if 0 04422 // Length of message string without terminating null. 04423 size_t __len = char_traits<char>::length(__msg) - 1; 04424 04425 // "everybody can easily convert the string using 04426 // mbsrtowcs/wcsrtombs or with iconv()" 04427 04428 // Convert char* to _CharT in locale used to open catalog. 04429 // XXX need additional template parameter on messages class for this.. 04430 // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type; 04431 typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type; 04432 04433 __codecvt_type::state_type __state; 04434 // XXX may need to initialize state. 04435 //initialize_state(__state._M_init()); 04436 04437 char* __from_next; 04438 // XXX what size for this string? 04439 _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); 04440 const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv); 04441 __cvt.out(__state, __msg, __msg + __len, __from_next, 04442 __to, __to + __len + 1, __to_next); 04443 return string_type(__to); 04444 #endif 04445 #if 0 04446 typedef ctype<_CharT> __ctype_type; 04447 // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg); 04448 const __ctype_type& __cvt = use_facet<__ctype_type>(locale()); 04449 // XXX Again, proper length of converted string an issue here. 04450 // For now, assume the converted length is not larger. 04451 _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1)); 04452 __cvt.widen(__msg, __msg + __len, __dest); 04453 return basic_string<_CharT>(__dest); 04454 #endif 04455 return string_type(); 04456 } 04457 }; 04458 04459 template<typename _CharT> 04460 locale::id messages<_CharT>::id; 04461 04462 // Specializations for required instantiations. 04463 template<> 04464 string 04465 messages<char>::do_get(catalog, int, int, const string&) const; 04466 04467 #ifdef _GLIBCXX_USE_WCHAR_T 04468 template<> 04469 wstring 04470 messages<wchar_t>::do_get(catalog, int, int, const wstring&) const; 04471 #endif 04472 04473 /// @brief class messages_byname [22.2.7.2]. 04474 template<typename _CharT> 04475 class messages_byname : public messages<_CharT> 04476 { 04477 public: 04478 typedef _CharT char_type; 04479 typedef basic_string<_CharT> string_type; 04480 04481 explicit 04482 messages_byname(const char* __s, size_t __refs = 0); 04483 04484 protected: 04485 virtual 04486 ~messages_byname() 04487 { } 04488 }; 04489 04490 // Include host and configuration specific messages functions. 04491 #include <bits/messages_members.h> 04492 04493 04494 // Subclause convenience interfaces, inlines. 04495 // NB: These are inline because, when used in a loop, some compilers 04496 // can hoist the body out of the loop; then it's just as fast as the 04497 // C is*() function. 04498 04499 /// Convenience interface to ctype.is(ctype_base::space, __c). 04500 template<typename _CharT> 04501 inline bool 04502 isspace(_CharT __c, const locale& __loc) 04503 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); } 04504 04505 /// Convenience interface to ctype.is(ctype_base::print, __c). 04506 template<typename _CharT> 04507 inline bool 04508 isprint(_CharT __c, const locale& __loc) 04509 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); } 04510 04511 /// Convenience interface to ctype.is(ctype_base::cntrl, __c). 04512 template<typename _CharT> 04513 inline bool 04514 iscntrl(_CharT __c, const locale& __loc) 04515 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); } 04516 04517 /// Convenience interface to ctype.is(ctype_base::upper, __c). 04518 template<typename _CharT> 04519 inline bool 04520 isupper(_CharT __c, const locale& __loc) 04521 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); } 04522 04523 /// Convenience interface to ctype.is(ctype_base::lower, __c). 04524 template<typename _CharT> 04525 inline bool 04526 islower(_CharT __c, const locale& __loc) 04527 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); } 04528 04529 /// Convenience interface to ctype.is(ctype_base::alpha, __c). 04530 template<typename _CharT> 04531 inline bool 04532 isalpha(_CharT __c, const locale& __loc) 04533 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); } 04534 04535 /// Convenience interface to ctype.is(ctype_base::digit, __c). 04536 template<typename _CharT> 04537 inline bool 04538 isdigit(_CharT __c, const locale& __loc) 04539 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); } 04540 04541 /// Convenience interface to ctype.is(ctype_base::punct, __c). 04542 template<typename _CharT> 04543 inline bool 04544 ispunct(_CharT __c, const locale& __loc) 04545 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); } 04546 04547 /// Convenience interface to ctype.is(ctype_base::xdigit, __c). 04548 template<typename _CharT> 04549 inline bool 04550 isxdigit(_CharT __c, const locale& __loc) 04551 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); } 04552 04553 /// Convenience interface to ctype.is(ctype_base::alnum, __c). 04554 template<typename _CharT> 04555 inline bool 04556 isalnum(_CharT __c, const locale& __loc) 04557 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); } 04558 04559 /// Convenience interface to ctype.is(ctype_base::graph, __c). 04560 template<typename _CharT> 04561 inline bool 04562 isgraph(_CharT __c, const locale& __loc) 04563 { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); } 04564 04565 /// Convenience interface to ctype.toupper(__c). 04566 template<typename _CharT> 04567 inline _CharT 04568 toupper(_CharT __c, const locale& __loc) 04569 { return use_facet<ctype<_CharT> >(__loc).toupper(__c); } 04570 04571 /// Convenience interface to ctype.tolower(__c). 04572 template<typename _CharT> 04573 inline _CharT 04574 tolower(_CharT __c, const locale& __loc) 04575 { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } 04576 } // namespace std 04577 04578 #endif