locale_facets.h

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

Generated on Wed Jun 9 11:18:39 2004 for libstdc++-v3 Source by doxygen 1.3.7