197403Sobrien// Locale support -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 497403Sobrien// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien/** @file locale_facets.h 3297403Sobrien * This is an internal header file, included by other library headers. 3397403Sobrien * You should not attempt to use it directly. 3497403Sobrien */ 3597403Sobrien 36169691Skan// 37169691Skan// ISO C++ 14882: 22.1 Locales 38169691Skan// 39169691Skan 40132720Skan#ifndef _LOCALE_FACETS_H 41132720Skan#define _LOCALE_FACETS_H 1 4297403Sobrien 4397403Sobrien#pragma GCC system_header 4497403Sobrien 4597403Sobrien#include <ctime> // For struct tm 4697403Sobrien#include <cwctype> // For wctype_t 47169691Skan#include <bits/ctype_base.h> 48117397Skan#include <iosfwd> 49117397Skan#include <bits/ios_base.h> // For ios_base, ios_base::iostate 50117397Skan#include <streambuf> 51169691Skan#include <bits/cpp_type_traits.h> 5297403Sobrien 53169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 54169691Skan 5597403Sobrien // NB: Don't instantiate required wchar_t facets if no wchar_t support. 56132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 57132720Skan# define _GLIBCXX_NUM_FACETS 28 5897403Sobrien#else 59132720Skan# define _GLIBCXX_NUM_FACETS 14 6097403Sobrien#endif 6197403Sobrien 62132720Skan // Convert string to numeric value of type _Tv and store results. 63117397Skan // NB: This is specialized for all required types, there is no 64117397Skan // generic definition. 65117397Skan template<typename _Tv> 66117397Skan void 67132720Skan __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, 68132720Skan const __c_locale& __cloc); 69117397Skan 70117397Skan // Explicit specializations for required types. 71117397Skan template<> 72117397Skan void 73132720Skan __convert_to_v(const char*, float&, ios_base::iostate&, 74132720Skan const __c_locale&); 75117397Skan 76117397Skan template<> 77117397Skan void 78132720Skan __convert_to_v(const char*, double&, ios_base::iostate&, 79132720Skan const __c_locale&); 80117397Skan 81117397Skan template<> 82117397Skan void 83132720Skan __convert_to_v(const char*, long double&, ios_base::iostate&, 84132720Skan const __c_locale&); 85117397Skan 86117397Skan // NB: __pad is a struct, rather than a function, so it can be 87117397Skan // partially-specialized. 88102782Skan template<typename _CharT, typename _Traits> 89117397Skan struct __pad 90117397Skan { 91117397Skan static void 92132720Skan _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, 93132720Skan const _CharT* __olds, const streamsize __newlen, 94117397Skan const streamsize __oldlen, const bool __num); 95117397Skan }; 96102782Skan 97117397Skan // Used by both numeric and monetary facets. 98117397Skan // Inserts "group separator" characters into an array of characters. 99117397Skan // It's recursive, one iteration per group. It moves the characters 100117397Skan // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this 101132720Skan // only with __glen != 0. 102117397Skan template<typename _CharT> 103117397Skan _CharT* 104132720Skan __add_grouping(_CharT* __s, _CharT __sep, 105132720Skan const char* __gbeg, size_t __gsize, 106117397Skan const _CharT* __first, const _CharT* __last); 107117397Skan 108117397Skan // This template permits specializing facet output code for 109117397Skan // ostreambuf_iterator. For ostreambuf_iterator, sputn is 110117397Skan // significantly more efficient than incrementing iterators. 111117397Skan template<typename _CharT> 112117397Skan inline 113117397Skan ostreambuf_iterator<_CharT> 114117397Skan __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) 115117397Skan { 116117397Skan __s._M_put(__ws, __len); 117117397Skan return __s; 118117397Skan } 119117397Skan 120117397Skan // This is the unspecialized form of the template. 121117397Skan template<typename _CharT, typename _OutIter> 122117397Skan inline 123117397Skan _OutIter 124117397Skan __write(_OutIter __s, const _CharT* __ws, int __len) 125117397Skan { 126117397Skan for (int __j = 0; __j < __len; __j++, ++__s) 127117397Skan *__s = __ws[__j]; 128117397Skan return __s; 129117397Skan } 130117397Skan 131132720Skan 13297403Sobrien // 22.2.1.1 Template class ctype 13397403Sobrien // Include host and configuration specific ctype enums for ctype_base. 13497403Sobrien 135132720Skan // Common base for ctype<_CharT>. 136132720Skan /** 137132720Skan * @brief Common base for ctype facet 138132720Skan * 139132720Skan * This template class provides implementations of the public functions 140132720Skan * that forward to the protected virtual functions. 141132720Skan * 142132720Skan * This template also provides abtract stubs for the protected virtual 143132720Skan * functions. 144132720Skan */ 14597403Sobrien template<typename _CharT> 14697403Sobrien class __ctype_abstract_base : public locale::facet, public ctype_base 14797403Sobrien { 14897403Sobrien public: 14997403Sobrien // Types: 150132720Skan /// Typedef for the template parameter 15197403Sobrien typedef _CharT char_type; 15297403Sobrien 153132720Skan /** 154132720Skan * @brief Test char_type classification. 155132720Skan * 156132720Skan * This function finds a mask M for @a c and compares it to mask @a m. 157132720Skan * It does so by returning the value of ctype<char_type>::do_is(). 158132720Skan * 159132720Skan * @param c The char_type to compare the mask of. 160132720Skan * @param m The mask to compare against. 161132720Skan * @return (M & m) != 0. 162132720Skan */ 163132720Skan bool 16497403Sobrien is(mask __m, char_type __c) const 16597403Sobrien { return this->do_is(__m, __c); } 16697403Sobrien 167132720Skan /** 168132720Skan * @brief Return a mask array. 169132720Skan * 170132720Skan * This function finds the mask for each char_type in the range [lo,hi) 171132720Skan * and successively writes it to vec. vec must have as many elements 172132720Skan * as the char array. It does so by returning the value of 173132720Skan * ctype<char_type>::do_is(). 174132720Skan * 175132720Skan * @param lo Pointer to start of range. 176132720Skan * @param hi Pointer to end of range. 177132720Skan * @param vec Pointer to an array of mask storage. 178132720Skan * @return @a hi. 179132720Skan */ 18097403Sobrien const char_type* 181132720Skan is(const char_type *__lo, const char_type *__hi, mask *__vec) const 18297403Sobrien { return this->do_is(__lo, __hi, __vec); } 18397403Sobrien 184132720Skan /** 185132720Skan * @brief Find char_type matching a mask 186132720Skan * 187132720Skan * This function searches for and returns the first char_type c in 188132720Skan * [lo,hi) for which is(m,c) is true. It does so by returning 189132720Skan * ctype<char_type>::do_scan_is(). 190132720Skan * 191132720Skan * @param m The mask to compare against. 192132720Skan * @param lo Pointer to start of range. 193132720Skan * @param hi Pointer to end of range. 194132720Skan * @return Pointer to matching char_type if found, else @a hi. 195132720Skan */ 19697403Sobrien const char_type* 19797403Sobrien scan_is(mask __m, const char_type* __lo, const char_type* __hi) const 19897403Sobrien { return this->do_scan_is(__m, __lo, __hi); } 19997403Sobrien 200132720Skan /** 201132720Skan * @brief Find char_type not matching a mask 202132720Skan * 203132720Skan * This function searches for and returns the first char_type c in 204132720Skan * [lo,hi) for which is(m,c) is false. It does so by returning 205132720Skan * ctype<char_type>::do_scan_not(). 206132720Skan * 207132720Skan * @param m The mask to compare against. 208132720Skan * @param lo Pointer to first char in range. 209132720Skan * @param hi Pointer to end of range. 210132720Skan * @return Pointer to non-matching char if found, else @a hi. 211132720Skan */ 21297403Sobrien const char_type* 21397403Sobrien scan_not(mask __m, const char_type* __lo, const char_type* __hi) const 21497403Sobrien { return this->do_scan_not(__m, __lo, __hi); } 21597403Sobrien 216132720Skan /** 217132720Skan * @brief Convert to uppercase. 218132720Skan * 219132720Skan * This function converts the argument to uppercase if possible. 220132720Skan * If not possible (for example, '2'), returns the argument. It does 221132720Skan * so by returning ctype<char_type>::do_toupper(). 222132720Skan * 223132720Skan * @param c The char_type to convert. 224132720Skan * @return The uppercase char_type if convertible, else @a c. 225132720Skan */ 226132720Skan char_type 22797403Sobrien toupper(char_type __c) const 22897403Sobrien { return this->do_toupper(__c); } 22997403Sobrien 230132720Skan /** 231132720Skan * @brief Convert array to uppercase. 232132720Skan * 233132720Skan * This function converts each char_type in the range [lo,hi) to 234132720Skan * uppercase if possible. Other elements remain untouched. It does so 235132720Skan * by returning ctype<char_type>:: do_toupper(lo, hi). 236132720Skan * 237132720Skan * @param lo Pointer to start of range. 238132720Skan * @param hi Pointer to end of range. 239132720Skan * @return @a hi. 240132720Skan */ 24197403Sobrien const char_type* 24297403Sobrien toupper(char_type *__lo, const char_type* __hi) const 24397403Sobrien { return this->do_toupper(__lo, __hi); } 24497403Sobrien 245132720Skan /** 246132720Skan * @brief Convert to lowercase. 247132720Skan * 248132720Skan * This function converts the argument to lowercase if possible. If 249132720Skan * not possible (for example, '2'), returns the argument. It does so 250132720Skan * by returning ctype<char_type>::do_tolower(c). 251132720Skan * 252132720Skan * @param c The char_type to convert. 253132720Skan * @return The lowercase char_type if convertible, else @a c. 254132720Skan */ 255132720Skan char_type 25697403Sobrien tolower(char_type __c) const 25797403Sobrien { return this->do_tolower(__c); } 25897403Sobrien 259132720Skan /** 260132720Skan * @brief Convert array to lowercase. 261132720Skan * 262132720Skan * This function converts each char_type in the range [lo,hi) to 263132720Skan * lowercase if possible. Other elements remain untouched. It does so 264132720Skan * by returning ctype<char_type>:: do_tolower(lo, hi). 265132720Skan * 266132720Skan * @param lo Pointer to start of range. 267132720Skan * @param hi Pointer to end of range. 268132720Skan * @return @a hi. 269132720Skan */ 27097403Sobrien const char_type* 27197403Sobrien tolower(char_type* __lo, const char_type* __hi) const 27297403Sobrien { return this->do_tolower(__lo, __hi); } 27397403Sobrien 274132720Skan /** 275132720Skan * @brief Widen char to char_type 276132720Skan * 277132720Skan * This function converts the char argument to char_type using the 278132720Skan * simplest reasonable transformation. It does so by returning 279132720Skan * ctype<char_type>::do_widen(c). 280132720Skan * 281132720Skan * Note: this is not what you want for codepage conversions. See 282132720Skan * codecvt for that. 283132720Skan * 284132720Skan * @param c The char to convert. 285132720Skan * @return The converted char_type. 286132720Skan */ 287132720Skan char_type 28897403Sobrien widen(char __c) const 28997403Sobrien { return this->do_widen(__c); } 29097403Sobrien 291132720Skan /** 292132720Skan * @brief Widen array to char_type 293132720Skan * 294132720Skan * This function converts each char in the input to char_type using the 295132720Skan * simplest reasonable transformation. It does so by returning 296132720Skan * ctype<char_type>::do_widen(c). 297132720Skan * 298132720Skan * Note: this is not what you want for codepage conversions. See 299132720Skan * codecvt for that. 300132720Skan * 301132720Skan * @param lo Pointer to start of range. 302132720Skan * @param hi Pointer to end of range. 303132720Skan * @param to Pointer to the destination array. 304132720Skan * @return @a hi. 305132720Skan */ 30697403Sobrien const char* 30797403Sobrien widen(const char* __lo, const char* __hi, char_type* __to) const 30897403Sobrien { return this->do_widen(__lo, __hi, __to); } 30997403Sobrien 310132720Skan /** 311132720Skan * @brief Narrow char_type to char 312132720Skan * 313132720Skan * This function converts the char_type to char using the simplest 314132720Skan * reasonable transformation. If the conversion fails, dfault is 315132720Skan * returned instead. It does so by returning 316132720Skan * ctype<char_type>::do_narrow(c). 317132720Skan * 318132720Skan * Note: this is not what you want for codepage conversions. See 319132720Skan * codecvt for that. 320132720Skan * 321132720Skan * @param c The char_type to convert. 322132720Skan * @param dfault Char to return if conversion fails. 323132720Skan * @return The converted char. 324132720Skan */ 325132720Skan char 32697403Sobrien narrow(char_type __c, char __dfault) const 32797403Sobrien { return this->do_narrow(__c, __dfault); } 32897403Sobrien 329132720Skan /** 330132720Skan * @brief Narrow array to char array 331132720Skan * 332132720Skan * This function converts each char_type in the input to char using the 333132720Skan * simplest reasonable transformation and writes the results to the 334132720Skan * destination array. For any char_type in the input that cannot be 335132720Skan * converted, @a dfault is used instead. It does so by returning 336132720Skan * ctype<char_type>::do_narrow(lo, hi, dfault, to). 337132720Skan * 338132720Skan * Note: this is not what you want for codepage conversions. See 339132720Skan * codecvt for that. 340132720Skan * 341132720Skan * @param lo Pointer to start of range. 342132720Skan * @param hi Pointer to end of range. 343132720Skan * @param dfault Char to use if conversion fails. 344132720Skan * @param to Pointer to the destination array. 345132720Skan * @return @a hi. 346132720Skan */ 34797403Sobrien const char_type* 34897403Sobrien narrow(const char_type* __lo, const char_type* __hi, 34997403Sobrien char __dfault, char *__to) const 35097403Sobrien { return this->do_narrow(__lo, __hi, __dfault, __to); } 35197403Sobrien 35297403Sobrien protected: 353132720Skan explicit 354132720Skan __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } 35597403Sobrien 356132720Skan virtual 35797403Sobrien ~__ctype_abstract_base() { } 358132720Skan 359132720Skan /** 360132720Skan * @brief Test char_type classification. 361132720Skan * 362132720Skan * This function finds a mask M for @a c and compares it to mask @a m. 363132720Skan * 364132720Skan * do_is() is a hook for a derived facet to change the behavior of 365132720Skan * classifying. do_is() must always return the same result for the 366132720Skan * same input. 367132720Skan * 368132720Skan * @param c The char_type to find the mask of. 369132720Skan * @param m The mask to compare against. 370132720Skan * @return (M & m) != 0. 371132720Skan */ 372132720Skan virtual bool 37397403Sobrien do_is(mask __m, char_type __c) const = 0; 37497403Sobrien 375132720Skan /** 376132720Skan * @brief Return a mask array. 377132720Skan * 378132720Skan * This function finds the mask for each char_type in the range [lo,hi) 379132720Skan * and successively writes it to vec. vec must have as many elements 380132720Skan * as the input. 381132720Skan * 382132720Skan * do_is() is a hook for a derived facet to change the behavior of 383132720Skan * classifying. do_is() must always return the same result for the 384132720Skan * same input. 385132720Skan * 386132720Skan * @param lo Pointer to start of range. 387132720Skan * @param hi Pointer to end of range. 388132720Skan * @param vec Pointer to an array of mask storage. 389132720Skan * @return @a hi. 390132720Skan */ 39197403Sobrien virtual const char_type* 392132720Skan do_is(const char_type* __lo, const char_type* __hi, 39397403Sobrien mask* __vec) const = 0; 39497403Sobrien 395132720Skan /** 396132720Skan * @brief Find char_type matching mask 397132720Skan * 398132720Skan * This function searches for and returns the first char_type c in 399132720Skan * [lo,hi) for which is(m,c) is true. 400132720Skan * 401132720Skan * do_scan_is() is a hook for a derived facet to change the behavior of 402132720Skan * match searching. do_is() must always return the same result for the 403132720Skan * same input. 404132720Skan * 405132720Skan * @param m The mask to compare against. 406132720Skan * @param lo Pointer to start of range. 407132720Skan * @param hi Pointer to end of range. 408132720Skan * @return Pointer to a matching char_type if found, else @a hi. 409132720Skan */ 41097403Sobrien virtual const char_type* 41197403Sobrien do_scan_is(mask __m, const char_type* __lo, 41297403Sobrien const char_type* __hi) const = 0; 41397403Sobrien 414132720Skan /** 415132720Skan * @brief Find char_type not matching mask 416132720Skan * 417132720Skan * This function searches for and returns a pointer to the first 418132720Skan * char_type c of [lo,hi) for which is(m,c) is false. 419132720Skan * 420132720Skan * do_scan_is() is a hook for a derived facet to change the behavior of 421132720Skan * match searching. do_is() must always return the same result for the 422132720Skan * same input. 423132720Skan * 424132720Skan * @param m The mask to compare against. 425132720Skan * @param lo Pointer to start of range. 426132720Skan * @param hi Pointer to end of range. 427132720Skan * @return Pointer to a non-matching char_type if found, else @a hi. 428132720Skan */ 42997403Sobrien virtual const char_type* 430132720Skan do_scan_not(mask __m, const char_type* __lo, 43197403Sobrien const char_type* __hi) const = 0; 43297403Sobrien 433132720Skan /** 434132720Skan * @brief Convert to uppercase. 435132720Skan * 436132720Skan * This virtual function converts the char_type argument to uppercase 437132720Skan * if possible. If not possible (for example, '2'), returns the 438132720Skan * argument. 439132720Skan * 440132720Skan * do_toupper() is a hook for a derived facet to change the behavior of 441132720Skan * uppercasing. do_toupper() must always return the same result for 442132720Skan * the same input. 443132720Skan * 444132720Skan * @param c The char_type to convert. 445132720Skan * @return The uppercase char_type if convertible, else @a c. 446132720Skan */ 447132720Skan virtual char_type 44897403Sobrien do_toupper(char_type) const = 0; 44997403Sobrien 450132720Skan /** 451132720Skan * @brief Convert array to uppercase. 452132720Skan * 453132720Skan * This virtual function converts each char_type in the range [lo,hi) 454132720Skan * to uppercase if possible. Other elements remain untouched. 455132720Skan * 456132720Skan * do_toupper() is a hook for a derived facet to change the behavior of 457132720Skan * uppercasing. do_toupper() must always return the same result for 458132720Skan * the same input. 459132720Skan * 460132720Skan * @param lo Pointer to start of range. 461132720Skan * @param hi Pointer to end of range. 462132720Skan * @return @a hi. 463132720Skan */ 46497403Sobrien virtual const char_type* 46597403Sobrien do_toupper(char_type* __lo, const char_type* __hi) const = 0; 46697403Sobrien 467132720Skan /** 468132720Skan * @brief Convert to lowercase. 469132720Skan * 470132720Skan * This virtual function converts the argument to lowercase if 471132720Skan * possible. If not possible (for example, '2'), returns the argument. 472132720Skan * 473132720Skan * do_tolower() is a hook for a derived facet to change the behavior of 474132720Skan * lowercasing. do_tolower() must always return the same result for 475132720Skan * the same input. 476132720Skan * 477132720Skan * @param c The char_type to convert. 478132720Skan * @return The lowercase char_type if convertible, else @a c. 479132720Skan */ 480132720Skan virtual char_type 48197403Sobrien do_tolower(char_type) const = 0; 48297403Sobrien 483132720Skan /** 484132720Skan * @brief Convert array to lowercase. 485132720Skan * 486132720Skan * This virtual function converts each char_type in the range [lo,hi) 487132720Skan * to lowercase if possible. Other elements remain untouched. 488132720Skan * 489132720Skan * do_tolower() is a hook for a derived facet to change the behavior of 490132720Skan * lowercasing. do_tolower() must always return the same result for 491132720Skan * the same input. 492132720Skan * 493132720Skan * @param lo Pointer to start of range. 494132720Skan * @param hi Pointer to end of range. 495132720Skan * @return @a hi. 496132720Skan */ 49797403Sobrien virtual const char_type* 49897403Sobrien do_tolower(char_type* __lo, const char_type* __hi) const = 0; 499132720Skan 500132720Skan /** 501132720Skan * @brief Widen char 502132720Skan * 503132720Skan * This virtual function converts the char to char_type using the 504132720Skan * simplest reasonable transformation. 505132720Skan * 506132720Skan * do_widen() is a hook for a derived facet to change the behavior of 507132720Skan * widening. do_widen() must always return the same result for the 508132720Skan * same input. 509132720Skan * 510132720Skan * Note: this is not what you want for codepage conversions. See 511132720Skan * codecvt for that. 512132720Skan * 513132720Skan * @param c The char to convert. 514132720Skan * @return The converted char_type 515132720Skan */ 516132720Skan virtual char_type 51797403Sobrien do_widen(char) const = 0; 51897403Sobrien 519132720Skan /** 520132720Skan * @brief Widen char array 521132720Skan * 522132720Skan * This function converts each char in the input to char_type using the 523132720Skan * simplest reasonable transformation. 524132720Skan * 525132720Skan * do_widen() is a hook for a derived facet to change the behavior of 526132720Skan * widening. do_widen() must always return the same result for the 527132720Skan * same input. 528132720Skan * 529132720Skan * Note: this is not what you want for codepage conversions. See 530132720Skan * codecvt for that. 531132720Skan * 532132720Skan * @param lo Pointer to start range. 533132720Skan * @param hi Pointer to end of range. 534132720Skan * @param to Pointer to the destination array. 535132720Skan * @return @a hi. 536132720Skan */ 53797403Sobrien virtual const char* 538132720Skan do_widen(const char* __lo, const char* __hi, 53997403Sobrien char_type* __dest) const = 0; 54097403Sobrien 541132720Skan /** 542132720Skan * @brief Narrow char_type to char 543132720Skan * 544132720Skan * This virtual function converts the argument to char using the 545132720Skan * simplest reasonable transformation. If the conversion fails, dfault 546132720Skan * is returned instead. 547132720Skan * 548132720Skan * do_narrow() is a hook for a derived facet to change the behavior of 549132720Skan * narrowing. do_narrow() must always return the same result for the 550132720Skan * same input. 551132720Skan * 552132720Skan * Note: this is not what you want for codepage conversions. See 553132720Skan * codecvt for that. 554132720Skan * 555132720Skan * @param c The char_type to convert. 556132720Skan * @param dfault Char to return if conversion fails. 557132720Skan * @return The converted char. 558132720Skan */ 559132720Skan virtual char 56097403Sobrien do_narrow(char_type, char __dfault) const = 0; 56197403Sobrien 562132720Skan /** 563132720Skan * @brief Narrow char_type array to char 564132720Skan * 565132720Skan * This virtual function converts each char_type in the range [lo,hi) to 566132720Skan * char using the simplest reasonable transformation and writes the 567132720Skan * results to the destination array. For any element in the input that 568132720Skan * cannot be converted, @a dfault is used instead. 569132720Skan * 570132720Skan * do_narrow() is a hook for a derived facet to change the behavior of 571132720Skan * narrowing. do_narrow() must always return the same result for the 572132720Skan * same input. 573132720Skan * 574132720Skan * Note: this is not what you want for codepage conversions. See 575132720Skan * codecvt for that. 576132720Skan * 577132720Skan * @param lo Pointer to start of range. 578132720Skan * @param hi Pointer to end of range. 579132720Skan * @param dfault Char to use if conversion fails. 580132720Skan * @param to Pointer to the destination array. 581132720Skan * @return @a hi. 582132720Skan */ 58397403Sobrien virtual const char_type* 58497403Sobrien do_narrow(const char_type* __lo, const char_type* __hi, 585132720Skan char __dfault, char* __dest) const = 0; 58697403Sobrien }; 58797403Sobrien 58897403Sobrien // NB: Generic, mostly useless implementation. 589132720Skan /** 590132720Skan * @brief Template ctype facet 591132720Skan * 592132720Skan * This template class defines classification and conversion functions for 593132720Skan * character sets. It wraps <cctype> functionality. Ctype gets used by 594132720Skan * streams for many I/O operations. 595132720Skan * 596132720Skan * This template provides the protected virtual functions the developer 597132720Skan * will have to replace in a derived class or specialization to make a 598132720Skan * working facet. The public functions that access them are defined in 599132720Skan * __ctype_abstract_base, to allow for implementation flexibility. See 600132720Skan * ctype<wchar_t> for an example. The functions are documented in 601132720Skan * __ctype_abstract_base. 602132720Skan * 603132720Skan * Note: implementations are provided for all the protected virtual 604132720Skan * functions, but will likely not be useful. 605132720Skan */ 60697403Sobrien template<typename _CharT> 60797403Sobrien class ctype : public __ctype_abstract_base<_CharT> 60897403Sobrien { 60997403Sobrien public: 61097403Sobrien // Types: 611132720Skan typedef _CharT char_type; 612132720Skan typedef typename __ctype_abstract_base<_CharT>::mask mask; 61397403Sobrien 614132720Skan /// The facet id for ctype<char_type> 615132720Skan static locale::id id; 61697403Sobrien 617132720Skan explicit 61897403Sobrien ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } 61997403Sobrien 62097403Sobrien protected: 621132720Skan virtual 62297403Sobrien ~ctype(); 62397403Sobrien 624132720Skan virtual bool 62597403Sobrien do_is(mask __m, char_type __c) const; 62697403Sobrien 62797403Sobrien virtual const char_type* 62897403Sobrien do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; 62997403Sobrien 63097403Sobrien virtual const char_type* 63197403Sobrien do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; 63297403Sobrien 63397403Sobrien virtual const char_type* 63497403Sobrien do_scan_not(mask __m, const char_type* __lo, 63597403Sobrien const char_type* __hi) const; 63697403Sobrien 637132720Skan virtual char_type 63897403Sobrien do_toupper(char_type __c) const; 63997403Sobrien 64097403Sobrien virtual const char_type* 64197403Sobrien do_toupper(char_type* __lo, const char_type* __hi) const; 64297403Sobrien 643132720Skan virtual char_type 64497403Sobrien do_tolower(char_type __c) const; 64597403Sobrien 64697403Sobrien virtual const char_type* 64797403Sobrien do_tolower(char_type* __lo, const char_type* __hi) const; 64897403Sobrien 649132720Skan virtual char_type 65097403Sobrien do_widen(char __c) const; 65197403Sobrien 65297403Sobrien virtual const char* 65397403Sobrien do_widen(const char* __lo, const char* __hi, char_type* __dest) const; 65497403Sobrien 655132720Skan virtual char 65697403Sobrien do_narrow(char_type, char __dfault) const; 65797403Sobrien 65897403Sobrien virtual const char_type* 65997403Sobrien do_narrow(const char_type* __lo, const char_type* __hi, 66097403Sobrien char __dfault, char* __dest) const; 66197403Sobrien }; 66297403Sobrien 66397403Sobrien template<typename _CharT> 66497403Sobrien locale::id ctype<_CharT>::id; 66597403Sobrien 66697403Sobrien // 22.2.1.3 ctype<char> specialization. 667132720Skan /** 668132720Skan * @brief The ctype<char> specialization. 669132720Skan * 670132720Skan * This class defines classification and conversion functions for 671132720Skan * the char type. It gets used by char streams for many I/O 672132720Skan * operations. The char specialization provides a number of 673132720Skan * optimizations as well. 674132720Skan */ 67597403Sobrien template<> 676132720Skan class ctype<char> : public locale::facet, public ctype_base 67797403Sobrien { 67897403Sobrien public: 67997403Sobrien // Types: 680132720Skan /// Typedef for the template parameter char. 681132720Skan typedef char char_type; 68297403Sobrien 68397403Sobrien protected: 68497403Sobrien // Data Members: 68597403Sobrien __c_locale _M_c_locale_ctype; 686132720Skan bool _M_del; 687132720Skan __to_type _M_toupper; 688132720Skan __to_type _M_tolower; 689132720Skan const mask* _M_table; 690132720Skan mutable char _M_widen_ok; 691132720Skan mutable char _M_widen[1 + static_cast<unsigned char>(-1)]; 692132720Skan mutable char _M_narrow[1 + static_cast<unsigned char>(-1)]; 693132720Skan mutable char _M_narrow_ok; // 0 uninitialized, 1 init, 694146897Skan // 2 memcpy can't be used 695132720Skan 69697403Sobrien public: 697132720Skan /// The facet id for ctype<char> 69897403Sobrien static locale::id id; 699132720Skan /// The size of the mask table. It is SCHAR_MAX + 1. 70097403Sobrien static const size_t table_size = 1 + static_cast<unsigned char>(-1); 70197403Sobrien 702132720Skan /** 703132720Skan * @brief Constructor performs initialization. 704132720Skan * 705132720Skan * This is the constructor provided by the standard. 706132720Skan * 707132720Skan * @param table If non-zero, table is used as the per-char mask. 708132720Skan * Else classic_table() is used. 709132720Skan * @param del If true, passes ownership of table to this facet. 710132720Skan * @param refs Passed to the base facet class. 711132720Skan */ 712132720Skan explicit 71397403Sobrien ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); 71497403Sobrien 715132720Skan /** 716132720Skan * @brief Constructor performs static initialization. 717132720Skan * 718132720Skan * This constructor is used to construct the initial C locale facet. 719132720Skan * 720132720Skan * @param cloc Handle to C locale data. 721132720Skan * @param table If non-zero, table is used as the per-char mask. 722132720Skan * @param del If true, passes ownership of table to this facet. 723132720Skan * @param refs Passed to the base facet class. 724132720Skan */ 725132720Skan explicit 726132720Skan ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, 72797403Sobrien size_t __refs = 0); 72897403Sobrien 729132720Skan /** 730132720Skan * @brief Test char classification. 731132720Skan * 732132720Skan * This function compares the mask table[c] to @a m. 733132720Skan * 734132720Skan * @param c The char to compare the mask of. 735132720Skan * @param m The mask to compare against. 736132720Skan * @return True if m & table[c] is true, false otherwise. 737132720Skan */ 738132720Skan inline bool 73997403Sobrien is(mask __m, char __c) const; 740132720Skan 741132720Skan /** 742132720Skan * @brief Return a mask array. 743132720Skan * 744132720Skan * This function finds the mask for each char in the range [lo, hi) and 745132720Skan * successively writes it to vec. vec must have as many elements as 746132720Skan * the char array. 747132720Skan * 748132720Skan * @param lo Pointer to start of range. 749132720Skan * @param hi Pointer to end of range. 750132720Skan * @param vec Pointer to an array of mask storage. 751132720Skan * @return @a hi. 752132720Skan */ 75397403Sobrien inline const char* 75497403Sobrien is(const char* __lo, const char* __hi, mask* __vec) const; 755132720Skan 756132720Skan /** 757132720Skan * @brief Find char matching a mask 758132720Skan * 759132720Skan * This function searches for and returns the first char in [lo,hi) for 760132720Skan * which is(m,char) is true. 761132720Skan * 762132720Skan * @param m The mask to compare against. 763132720Skan * @param lo Pointer to start of range. 764132720Skan * @param hi Pointer to end of range. 765132720Skan * @return Pointer to a matching char if found, else @a hi. 766132720Skan */ 76797403Sobrien inline const char* 76897403Sobrien scan_is(mask __m, const char* __lo, const char* __hi) const; 76997403Sobrien 770132720Skan /** 771132720Skan * @brief Find char not matching a mask 772132720Skan * 773132720Skan * This function searches for and returns a pointer to the first char 774132720Skan * in [lo,hi) for which is(m,char) is false. 775132720Skan * 776132720Skan * @param m The mask to compare against. 777132720Skan * @param lo Pointer to start of range. 778132720Skan * @param hi Pointer to end of range. 779132720Skan * @return Pointer to a non-matching char if found, else @a hi. 780132720Skan */ 78197403Sobrien inline const char* 78297403Sobrien scan_not(mask __m, const char* __lo, const char* __hi) const; 783132720Skan 784132720Skan /** 785132720Skan * @brief Convert to uppercase. 786132720Skan * 787132720Skan * This function converts the char argument to uppercase if possible. 788132720Skan * If not possible (for example, '2'), returns the argument. 789132720Skan * 790132720Skan * toupper() acts as if it returns ctype<char>::do_toupper(c). 791132720Skan * do_toupper() must always return the same result for the same input. 792132720Skan * 793132720Skan * @param c The char to convert. 794132720Skan * @return The uppercase char if convertible, else @a c. 795132720Skan */ 796132720Skan char_type 797132720Skan toupper(char_type __c) const 798132720Skan { return this->do_toupper(__c); } 799132720Skan 800132720Skan /** 801132720Skan * @brief Convert array to uppercase. 802132720Skan * 803132720Skan * This function converts each char in the range [lo,hi) to uppercase 804132720Skan * if possible. Other chars remain untouched. 805132720Skan * 806132720Skan * toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi). 807132720Skan * do_toupper() must always return the same result for the same input. 808132720Skan * 809132720Skan * @param lo Pointer to first char in range. 810132720Skan * @param hi Pointer to end of range. 811132720Skan * @return @a hi. 812132720Skan */ 813132720Skan const char_type* 814132720Skan toupper(char_type *__lo, const char_type* __hi) const 815132720Skan { return this->do_toupper(__lo, __hi); } 816132720Skan 817132720Skan /** 818132720Skan * @brief Convert to lowercase. 819132720Skan * 820132720Skan * This function converts the char argument to lowercase if possible. 821132720Skan * If not possible (for example, '2'), returns the argument. 822132720Skan * 823132720Skan * tolower() acts as if it returns ctype<char>::do_tolower(c). 824132720Skan * do_tolower() must always return the same result for the same input. 825132720Skan * 826132720Skan * @param c The char to convert. 827132720Skan * @return The lowercase char if convertible, else @a c. 828132720Skan */ 829132720Skan char_type 830132720Skan tolower(char_type __c) const 831132720Skan { return this->do_tolower(__c); } 832132720Skan 833132720Skan /** 834132720Skan * @brief Convert array to lowercase. 835132720Skan * 836132720Skan * This function converts each char in the range [lo,hi) to lowercase 837132720Skan * if possible. Other chars remain untouched. 838132720Skan * 839132720Skan * tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi). 840132720Skan * do_tolower() must always return the same result for the same input. 841132720Skan * 842132720Skan * @param lo Pointer to first char in range. 843132720Skan * @param hi Pointer to end of range. 844132720Skan * @return @a hi. 845132720Skan */ 846132720Skan const char_type* 847132720Skan tolower(char_type* __lo, const char_type* __hi) const 848132720Skan { return this->do_tolower(__lo, __hi); } 849132720Skan 850132720Skan /** 851132720Skan * @brief Widen char 852132720Skan * 853132720Skan * This function converts the char to char_type using the simplest 854132720Skan * reasonable transformation. For an underived ctype<char> facet, the 855132720Skan * argument will be returned unchanged. 856132720Skan * 857132720Skan * This function works as if it returns ctype<char>::do_widen(c). 858132720Skan * do_widen() must always return the same result for the same input. 859132720Skan * 860132720Skan * Note: this is not what you want for codepage conversions. See 861132720Skan * codecvt for that. 862132720Skan * 863132720Skan * @param c The char to convert. 864132720Skan * @return The converted character. 865132720Skan */ 866132720Skan char_type 867132720Skan widen(char __c) const 868132720Skan { 869146897Skan if (_M_widen_ok) 870146897Skan return _M_widen[static_cast<unsigned char>(__c)]; 871132720Skan this->_M_widen_init(); 872132720Skan return this->do_widen(__c); 873132720Skan } 874132720Skan 875132720Skan /** 876132720Skan * @brief Widen char array 877132720Skan * 878132720Skan * This function converts each char in the input to char using the 879132720Skan * simplest reasonable transformation. For an underived ctype<char> 880132720Skan * facet, the argument will be copied unchanged. 881132720Skan * 882132720Skan * This function works as if it returns ctype<char>::do_widen(c). 883132720Skan * do_widen() must always return the same result for the same input. 884132720Skan * 885132720Skan * Note: this is not what you want for codepage conversions. See 886132720Skan * codecvt for that. 887132720Skan * 888132720Skan * @param lo Pointer to first char in range. 889132720Skan * @param hi Pointer to end of range. 890132720Skan * @param to Pointer to the destination array. 891132720Skan * @return @a hi. 892132720Skan */ 893132720Skan const char* 894132720Skan widen(const char* __lo, const char* __hi, char_type* __to) const 895132720Skan { 896132720Skan if (_M_widen_ok == 1) 897132720Skan { 898132720Skan memcpy(__to, __lo, __hi - __lo); 899132720Skan return __hi; 900132720Skan } 901146897Skan if (!_M_widen_ok) 902146897Skan _M_widen_init(); 903132720Skan return this->do_widen(__lo, __hi, __to); 904132720Skan } 905132720Skan 906132720Skan /** 907132720Skan * @brief Narrow char 908132720Skan * 909132720Skan * This function converts the char to char using the simplest 910132720Skan * reasonable transformation. If the conversion fails, dfault is 911132720Skan * returned instead. For an underived ctype<char> facet, @a c 912132720Skan * will be returned unchanged. 913132720Skan * 914132720Skan * This function works as if it returns ctype<char>::do_narrow(c). 915132720Skan * do_narrow() must always return the same result for the same input. 916132720Skan * 917132720Skan * Note: this is not what you want for codepage conversions. See 918132720Skan * codecvt for that. 919132720Skan * 920132720Skan * @param c The char to convert. 921132720Skan * @param dfault Char to return if conversion fails. 922132720Skan * @return The converted character. 923132720Skan */ 924132720Skan char 925132720Skan narrow(char_type __c, char __dfault) const 926132720Skan { 927132720Skan if (_M_narrow[static_cast<unsigned char>(__c)]) 928132720Skan return _M_narrow[static_cast<unsigned char>(__c)]; 929132720Skan const char __t = do_narrow(__c, __dfault); 930146897Skan if (__t != __dfault) 931146897Skan _M_narrow[static_cast<unsigned char>(__c)] = __t; 932132720Skan return __t; 933132720Skan } 934132720Skan 935132720Skan /** 936132720Skan * @brief Narrow char array 937132720Skan * 938132720Skan * This function converts each char in the input to char using the 939132720Skan * simplest reasonable transformation and writes the results to the 940132720Skan * destination array. For any char in the input that cannot be 941132720Skan * converted, @a dfault is used instead. For an underived ctype<char> 942132720Skan * facet, the argument will be copied unchanged. 943132720Skan * 944132720Skan * This function works as if it returns ctype<char>::do_narrow(lo, hi, 945132720Skan * dfault, to). do_narrow() must always return the same result for the 946132720Skan * same input. 947132720Skan * 948132720Skan * Note: this is not what you want for codepage conversions. See 949132720Skan * codecvt for that. 950132720Skan * 951132720Skan * @param lo Pointer to start of range. 952132720Skan * @param hi Pointer to end of range. 953132720Skan * @param dfault Char to use if conversion fails. 954132720Skan * @param to Pointer to the destination array. 955132720Skan * @return @a hi. 956132720Skan */ 957132720Skan const char_type* 958132720Skan narrow(const char_type* __lo, const char_type* __hi, 959132720Skan char __dfault, char *__to) const 960132720Skan { 961146897Skan if (__builtin_expect(_M_narrow_ok == 1, true)) 962132720Skan { 963132720Skan memcpy(__to, __lo, __hi - __lo); 964132720Skan return __hi; 965132720Skan } 966132720Skan if (!_M_narrow_ok) 967132720Skan _M_narrow_init(); 968132720Skan return this->do_narrow(__lo, __hi, __dfault, __to); 969132720Skan } 970132720Skan 97197403Sobrien protected: 972132720Skan /// Returns a pointer to the mask table provided to the constructor, or 973132720Skan /// the default from classic_table() if none was provided. 974132720Skan const mask* 97597403Sobrien table() const throw() 97697403Sobrien { return _M_table; } 97797403Sobrien 978132720Skan /// Returns a pointer to the C locale mask table. 979132720Skan static const mask* 98097403Sobrien classic_table() throw(); 98197403Sobrien 982132720Skan /** 983132720Skan * @brief Destructor. 984132720Skan * 985132720Skan * This function deletes table() if @a del was true in the 986132720Skan * constructor. 987132720Skan */ 988132720Skan virtual 98997403Sobrien ~ctype(); 99097403Sobrien 991132720Skan /** 992132720Skan * @brief Convert to uppercase. 993132720Skan * 994132720Skan * This virtual function converts the char argument to uppercase if 995132720Skan * possible. If not possible (for example, '2'), returns the argument. 996132720Skan * 997132720Skan * do_toupper() is a hook for a derived facet to change the behavior of 998132720Skan * uppercasing. do_toupper() must always return the same result for 999132720Skan * the same input. 1000132720Skan * 1001132720Skan * @param c The char to convert. 1002132720Skan * @return The uppercase char if convertible, else @a c. 1003132720Skan */ 1004132720Skan virtual char_type 100597403Sobrien do_toupper(char_type) const; 100697403Sobrien 1007132720Skan /** 1008132720Skan * @brief Convert array to uppercase. 1009132720Skan * 1010132720Skan * This virtual function converts each char in the range [lo,hi) to 1011132720Skan * uppercase if possible. Other chars remain untouched. 1012132720Skan * 1013132720Skan * do_toupper() is a hook for a derived facet to change the behavior of 1014132720Skan * uppercasing. do_toupper() must always return the same result for 1015132720Skan * the same input. 1016132720Skan * 1017132720Skan * @param lo Pointer to start of range. 1018132720Skan * @param hi Pointer to end of range. 1019132720Skan * @return @a hi. 1020132720Skan */ 102197403Sobrien virtual const char_type* 102297403Sobrien do_toupper(char_type* __lo, const char_type* __hi) const; 102397403Sobrien 1024132720Skan /** 1025132720Skan * @brief Convert to lowercase. 1026132720Skan * 1027132720Skan * This virtual function converts the char argument to lowercase if 1028132720Skan * possible. If not possible (for example, '2'), returns the argument. 1029132720Skan * 1030132720Skan * do_tolower() is a hook for a derived facet to change the behavior of 1031132720Skan * lowercasing. do_tolower() must always return the same result for 1032132720Skan * the same input. 1033132720Skan * 1034132720Skan * @param c The char to convert. 1035132720Skan * @return The lowercase char if convertible, else @a c. 1036132720Skan */ 1037132720Skan virtual char_type 103897403Sobrien do_tolower(char_type) const; 103997403Sobrien 1040132720Skan /** 1041132720Skan * @brief Convert array to lowercase. 1042132720Skan * 1043132720Skan * This virtual function converts each char in the range [lo,hi) to 1044132720Skan * lowercase if possible. Other chars remain untouched. 1045132720Skan * 1046132720Skan * do_tolower() is a hook for a derived facet to change the behavior of 1047132720Skan * lowercasing. do_tolower() must always return the same result for 1048132720Skan * the same input. 1049132720Skan * 1050132720Skan * @param lo Pointer to first char in range. 1051132720Skan * @param hi Pointer to end of range. 1052132720Skan * @return @a hi. 1053132720Skan */ 105497403Sobrien virtual const char_type* 105597403Sobrien do_tolower(char_type* __lo, const char_type* __hi) const; 105697403Sobrien 1057132720Skan /** 1058132720Skan * @brief Widen char 1059132720Skan * 1060132720Skan * This virtual function converts the char to char using the simplest 1061132720Skan * reasonable transformation. For an underived ctype<char> facet, the 1062132720Skan * argument will be returned unchanged. 1063132720Skan * 1064132720Skan * do_widen() is a hook for a derived facet to change the behavior of 1065132720Skan * widening. do_widen() must always return the same result for the 1066132720Skan * same input. 1067132720Skan * 1068132720Skan * Note: this is not what you want for codepage conversions. See 1069132720Skan * codecvt for that. 1070132720Skan * 1071132720Skan * @param c The char to convert. 1072132720Skan * @return The converted character. 1073132720Skan */ 1074132720Skan virtual char_type 1075132720Skan do_widen(char __c) const 1076132720Skan { return __c; } 1077132720Skan 1078132720Skan /** 1079132720Skan * @brief Widen char array 1080132720Skan * 1081132720Skan * This function converts each char in the range [lo,hi) to char using 1082132720Skan * the simplest reasonable transformation. For an underived 1083132720Skan * ctype<char> facet, the argument will be copied unchanged. 1084132720Skan * 1085132720Skan * do_widen() is a hook for a derived facet to change the behavior of 1086132720Skan * widening. do_widen() must always return the same result for the 1087132720Skan * same input. 1088132720Skan * 1089132720Skan * Note: this is not what you want for codepage conversions. See 1090132720Skan * codecvt for that. 1091132720Skan * 1092132720Skan * @param lo Pointer to start of range. 1093132720Skan * @param hi Pointer to end of range. 1094132720Skan * @param to Pointer to the destination array. 1095132720Skan * @return @a hi. 1096132720Skan */ 109797403Sobrien virtual const char* 1098132720Skan do_widen(const char* __lo, const char* __hi, char_type* __dest) const 1099132720Skan { 1100132720Skan memcpy(__dest, __lo, __hi - __lo); 1101132720Skan return __hi; 1102132720Skan } 110397403Sobrien 1104132720Skan /** 1105132720Skan * @brief Narrow char 1106132720Skan * 1107132720Skan * This virtual function converts the char to char using the simplest 1108132720Skan * reasonable transformation. If the conversion fails, dfault is 1109132720Skan * returned instead. For an underived ctype<char> facet, @a c will be 1110132720Skan * returned unchanged. 1111132720Skan * 1112132720Skan * do_narrow() is a hook for a derived facet to change the behavior of 1113132720Skan * narrowing. do_narrow() must always return the same result for the 1114132720Skan * same input. 1115132720Skan * 1116132720Skan * Note: this is not what you want for codepage conversions. See 1117132720Skan * codecvt for that. 1118132720Skan * 1119132720Skan * @param c The char to convert. 1120132720Skan * @param dfault Char to return if conversion fails. 1121132720Skan * @return The converted char. 1122132720Skan */ 1123132720Skan virtual char 1124132720Skan do_narrow(char_type __c, char) const 1125132720Skan { return __c; } 112697403Sobrien 1127132720Skan /** 1128132720Skan * @brief Narrow char array to char array 1129132720Skan * 1130132720Skan * This virtual function converts each char in the range [lo,hi) to 1131132720Skan * char using the simplest reasonable transformation and writes the 1132132720Skan * results to the destination array. For any char in the input that 1133132720Skan * cannot be converted, @a dfault is used instead. For an underived 1134132720Skan * ctype<char> facet, the argument will be copied unchanged. 1135132720Skan * 1136132720Skan * do_narrow() is a hook for a derived facet to change the behavior of 1137132720Skan * narrowing. do_narrow() must always return the same result for the 1138132720Skan * same input. 1139132720Skan * 1140132720Skan * Note: this is not what you want for codepage conversions. See 1141132720Skan * codecvt for that. 1142132720Skan * 1143132720Skan * @param lo Pointer to start of range. 1144132720Skan * @param hi Pointer to end of range. 1145132720Skan * @param dfault Char to use if conversion fails. 1146132720Skan * @param to Pointer to the destination array. 1147132720Skan * @return @a hi. 1148132720Skan */ 114997403Sobrien virtual const char_type* 115097403Sobrien do_narrow(const char_type* __lo, const char_type* __hi, 1151132720Skan char, char* __dest) const 1152132720Skan { 1153132720Skan memcpy(__dest, __lo, __hi - __lo); 1154132720Skan return __hi; 1155132720Skan } 1156132720Skan 1157132720Skan private: 1158132720Skan 1159132720Skan void _M_widen_init() const 1160132720Skan { 1161132720Skan char __tmp[sizeof(_M_widen)]; 1162132720Skan for (size_t __i = 0; __i < sizeof(_M_widen); ++__i) 1163132720Skan __tmp[__i] = __i; 1164132720Skan do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); 1165132720Skan 1166132720Skan _M_widen_ok = 1; 1167132720Skan // Set _M_widen_ok to 2 if memcpy can't be used. 1168146897Skan if (memcmp(__tmp, _M_widen, sizeof(_M_widen))) 1169146897Skan _M_widen_ok = 2; 1170132720Skan } 1171132720Skan 1172132720Skan // Fill in the narrowing cache and flag whether all values are 1173146897Skan // valid or not. _M_narrow_ok is set to 2 if memcpy can't 1174146897Skan // be used. 1175132720Skan void _M_narrow_init() const 1176132720Skan { 1177132720Skan char __tmp[sizeof(_M_narrow)]; 1178132720Skan for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i) 1179132720Skan __tmp[__i] = __i; 1180132720Skan do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); 1181132720Skan 1182146897Skan _M_narrow_ok = 1; 1183146897Skan if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow))) 1184146897Skan _M_narrow_ok = 2; 1185146897Skan else 1186146897Skan { 1187146897Skan // Deal with the special case of zero: renarrow with a 1188146897Skan // different default and compare. 1189146897Skan char __c; 1190146897Skan do_narrow(__tmp, __tmp + 1, 1, &__c); 1191146897Skan if (__c == 1) 1192146897Skan _M_narrow_ok = 2; 1193146897Skan } 1194132720Skan } 119597403Sobrien }; 1196132720Skan 119797403Sobrien template<> 119897403Sobrien const ctype<char>& 119997403Sobrien use_facet<ctype<char> >(const locale& __loc); 120097403Sobrien 1201132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 120297403Sobrien // 22.2.1.3 ctype<wchar_t> specialization 1203132720Skan /** 1204132720Skan * @brief The ctype<wchar_t> specialization. 1205132720Skan * 1206132720Skan * This class defines classification and conversion functions for the 1207132720Skan * wchar_t type. It gets used by wchar_t streams for many I/O operations. 1208132720Skan * The wchar_t specialization provides a number of optimizations as well. 1209132720Skan * 1210132720Skan * ctype<wchar_t> inherits its public methods from 1211132720Skan * __ctype_abstract_base<wchar_t>. 1212132720Skan */ 121397403Sobrien template<> 121497403Sobrien class ctype<wchar_t> : public __ctype_abstract_base<wchar_t> 121597403Sobrien { 121697403Sobrien public: 121797403Sobrien // Types: 1218132720Skan /// Typedef for the template parameter wchar_t. 1219132720Skan typedef wchar_t char_type; 1220132720Skan typedef wctype_t __wmask_type; 122197403Sobrien 122297403Sobrien protected: 122397403Sobrien __c_locale _M_c_locale_ctype; 122497403Sobrien 1225132720Skan // Pre-computed narrowed and widened chars. 1226132720Skan bool _M_narrow_ok; 1227132720Skan char _M_narrow[128]; 1228132720Skan wint_t _M_widen[1 + static_cast<unsigned char>(-1)]; 1229132720Skan 1230132720Skan // Pre-computed elements for do_is. 1231132720Skan mask _M_bit[16]; 1232132720Skan __wmask_type _M_wmask[16]; 1233132720Skan 123497403Sobrien public: 123597403Sobrien // Data Members: 1236132720Skan /// The facet id for ctype<wchar_t> 1237132720Skan static locale::id id; 123897403Sobrien 1239132720Skan /** 1240132720Skan * @brief Constructor performs initialization. 1241132720Skan * 1242132720Skan * This is the constructor provided by the standard. 1243132720Skan * 1244132720Skan * @param refs Passed to the base facet class. 1245132720Skan */ 1246132720Skan explicit 124797403Sobrien ctype(size_t __refs = 0); 124897403Sobrien 1249132720Skan /** 1250132720Skan * @brief Constructor performs static initialization. 1251132720Skan * 1252132720Skan * This constructor is used to construct the initial C locale facet. 1253132720Skan * 1254132720Skan * @param cloc Handle to C locale data. 1255132720Skan * @param refs Passed to the base facet class. 1256132720Skan */ 1257132720Skan explicit 125897403Sobrien ctype(__c_locale __cloc, size_t __refs = 0); 125997403Sobrien 126097403Sobrien protected: 126197403Sobrien __wmask_type 126297403Sobrien _M_convert_to_wmask(const mask __m) const; 126397403Sobrien 1264132720Skan /// Destructor 1265132720Skan virtual 126697403Sobrien ~ctype(); 126797403Sobrien 1268132720Skan /** 1269132720Skan * @brief Test wchar_t classification. 1270132720Skan * 1271132720Skan * This function finds a mask M for @a c and compares it to mask @a m. 1272132720Skan * 1273132720Skan * do_is() is a hook for a derived facet to change the behavior of 1274132720Skan * classifying. do_is() must always return the same result for the 1275132720Skan * same input. 1276132720Skan * 1277132720Skan * @param c The wchar_t to find the mask of. 1278132720Skan * @param m The mask to compare against. 1279132720Skan * @return (M & m) != 0. 1280132720Skan */ 1281132720Skan virtual bool 128297403Sobrien do_is(mask __m, char_type __c) const; 128397403Sobrien 1284132720Skan /** 1285132720Skan * @brief Return a mask array. 1286132720Skan * 1287132720Skan * This function finds the mask for each wchar_t in the range [lo,hi) 1288132720Skan * and successively writes it to vec. vec must have as many elements 1289132720Skan * as the input. 1290132720Skan * 1291132720Skan * do_is() is a hook for a derived facet to change the behavior of 1292132720Skan * classifying. do_is() must always return the same result for the 1293132720Skan * same input. 1294132720Skan * 1295132720Skan * @param lo Pointer to start of range. 1296132720Skan * @param hi Pointer to end of range. 1297132720Skan * @param vec Pointer to an array of mask storage. 1298132720Skan * @return @a hi. 1299132720Skan */ 130097403Sobrien virtual const char_type* 130197403Sobrien do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; 130297403Sobrien 1303132720Skan /** 1304132720Skan * @brief Find wchar_t matching mask 1305132720Skan * 1306132720Skan * This function searches for and returns the first wchar_t c in 1307132720Skan * [lo,hi) for which is(m,c) is true. 1308132720Skan * 1309132720Skan * do_scan_is() is a hook for a derived facet to change the behavior of 1310132720Skan * match searching. do_is() must always return the same result for the 1311132720Skan * same input. 1312132720Skan * 1313132720Skan * @param m The mask to compare against. 1314132720Skan * @param lo Pointer to start of range. 1315132720Skan * @param hi Pointer to end of range. 1316132720Skan * @return Pointer to a matching wchar_t if found, else @a hi. 1317132720Skan */ 131897403Sobrien virtual const char_type* 131997403Sobrien do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; 132097403Sobrien 1321132720Skan /** 1322132720Skan * @brief Find wchar_t not matching mask 1323132720Skan * 1324132720Skan * This function searches for and returns a pointer to the first 1325132720Skan * wchar_t c of [lo,hi) for which is(m,c) is false. 1326132720Skan * 1327132720Skan * do_scan_is() is a hook for a derived facet to change the behavior of 1328132720Skan * match searching. do_is() must always return the same result for the 1329132720Skan * same input. 1330132720Skan * 1331132720Skan * @param m The mask to compare against. 1332132720Skan * @param lo Pointer to start of range. 1333132720Skan * @param hi Pointer to end of range. 1334132720Skan * @return Pointer to a non-matching wchar_t if found, else @a hi. 1335132720Skan */ 133697403Sobrien virtual const char_type* 1337132720Skan do_scan_not(mask __m, const char_type* __lo, 133897403Sobrien const char_type* __hi) const; 133997403Sobrien 1340132720Skan /** 1341132720Skan * @brief Convert to uppercase. 1342132720Skan * 1343132720Skan * This virtual function converts the wchar_t argument to uppercase if 1344132720Skan * possible. If not possible (for example, '2'), returns the argument. 1345132720Skan * 1346132720Skan * do_toupper() is a hook for a derived facet to change the behavior of 1347132720Skan * uppercasing. do_toupper() must always return the same result for 1348132720Skan * the same input. 1349132720Skan * 1350132720Skan * @param c The wchar_t to convert. 1351132720Skan * @return The uppercase wchar_t if convertible, else @a c. 1352132720Skan */ 1353132720Skan virtual char_type 135497403Sobrien do_toupper(char_type) const; 135597403Sobrien 1356132720Skan /** 1357132720Skan * @brief Convert array to uppercase. 1358132720Skan * 1359132720Skan * This virtual function converts each wchar_t in the range [lo,hi) to 1360132720Skan * uppercase if possible. Other elements remain untouched. 1361132720Skan * 1362132720Skan * do_toupper() is a hook for a derived facet to change the behavior of 1363132720Skan * uppercasing. do_toupper() must always return the same result for 1364132720Skan * the same input. 1365132720Skan * 1366132720Skan * @param lo Pointer to start of range. 1367132720Skan * @param hi Pointer to end of range. 1368132720Skan * @return @a hi. 1369132720Skan */ 137097403Sobrien virtual const char_type* 137197403Sobrien do_toupper(char_type* __lo, const char_type* __hi) const; 137297403Sobrien 1373132720Skan /** 1374132720Skan * @brief Convert to lowercase. 1375132720Skan * 1376132720Skan * This virtual function converts the argument to lowercase if 1377132720Skan * possible. If not possible (for example, '2'), returns the argument. 1378132720Skan * 1379132720Skan * do_tolower() is a hook for a derived facet to change the behavior of 1380132720Skan * lowercasing. do_tolower() must always return the same result for 1381132720Skan * the same input. 1382132720Skan * 1383132720Skan * @param c The wchar_t to convert. 1384132720Skan * @return The lowercase wchar_t if convertible, else @a c. 1385132720Skan */ 1386132720Skan virtual char_type 138797403Sobrien do_tolower(char_type) const; 138897403Sobrien 1389132720Skan /** 1390132720Skan * @brief Convert array to lowercase. 1391132720Skan * 1392132720Skan * This virtual function converts each wchar_t in the range [lo,hi) to 1393132720Skan * lowercase if possible. Other elements remain untouched. 1394132720Skan * 1395132720Skan * do_tolower() is a hook for a derived facet to change the behavior of 1396132720Skan * lowercasing. do_tolower() must always return the same result for 1397132720Skan * the same input. 1398132720Skan * 1399132720Skan * @param lo Pointer to start of range. 1400132720Skan * @param hi Pointer to end of range. 1401132720Skan * @return @a hi. 1402132720Skan */ 140397403Sobrien virtual const char_type* 140497403Sobrien do_tolower(char_type* __lo, const char_type* __hi) const; 1405132720Skan 1406132720Skan /** 1407132720Skan * @brief Widen char to wchar_t 1408132720Skan * 1409132720Skan * This virtual function converts the char to wchar_t using the 1410132720Skan * simplest reasonable transformation. For an underived ctype<wchar_t> 1411132720Skan * facet, the argument will be cast to wchar_t. 1412132720Skan * 1413132720Skan * do_widen() is a hook for a derived facet to change the behavior of 1414132720Skan * widening. do_widen() must always return the same result for the 1415132720Skan * same input. 1416132720Skan * 1417132720Skan * Note: this is not what you want for codepage conversions. See 1418132720Skan * codecvt for that. 1419132720Skan * 1420132720Skan * @param c The char to convert. 1421132720Skan * @return The converted wchar_t. 1422132720Skan */ 1423132720Skan virtual char_type 142497403Sobrien do_widen(char) const; 142597403Sobrien 1426132720Skan /** 1427132720Skan * @brief Widen char array to wchar_t array 1428132720Skan * 1429132720Skan * This function converts each char in the input to wchar_t using the 1430132720Skan * simplest reasonable transformation. For an underived ctype<wchar_t> 1431132720Skan * facet, the argument will be copied, casting each element to wchar_t. 1432132720Skan * 1433132720Skan * do_widen() is a hook for a derived facet to change the behavior of 1434132720Skan * widening. do_widen() must always return the same result for the 1435132720Skan * same input. 1436132720Skan * 1437132720Skan * Note: this is not what you want for codepage conversions. See 1438132720Skan * codecvt for that. 1439132720Skan * 1440132720Skan * @param lo Pointer to start range. 1441132720Skan * @param hi Pointer to end of range. 1442132720Skan * @param to Pointer to the destination array. 1443132720Skan * @return @a hi. 1444132720Skan */ 144597403Sobrien virtual const char* 144697403Sobrien do_widen(const char* __lo, const char* __hi, char_type* __dest) const; 144797403Sobrien 1448132720Skan /** 1449132720Skan * @brief Narrow wchar_t to char 1450132720Skan * 1451132720Skan * This virtual function converts the argument to char using 1452132720Skan * the simplest reasonable transformation. If the conversion 1453132720Skan * fails, dfault is returned instead. For an underived 1454132720Skan * ctype<wchar_t> facet, @a c will be cast to char and 1455132720Skan * returned. 1456132720Skan * 1457132720Skan * do_narrow() is a hook for a derived facet to change the 1458132720Skan * behavior of narrowing. do_narrow() must always return the 1459132720Skan * same result for the same input. 1460132720Skan * 1461132720Skan * Note: this is not what you want for codepage conversions. See 1462132720Skan * codecvt for that. 1463132720Skan * 1464132720Skan * @param c The wchar_t to convert. 1465132720Skan * @param dfault Char to return if conversion fails. 1466132720Skan * @return The converted char. 1467132720Skan */ 1468132720Skan virtual char 146997403Sobrien do_narrow(char_type, char __dfault) const; 147097403Sobrien 1471132720Skan /** 1472132720Skan * @brief Narrow wchar_t array to char array 1473132720Skan * 1474132720Skan * This virtual function converts each wchar_t in the range [lo,hi) to 1475132720Skan * char using the simplest reasonable transformation and writes the 1476132720Skan * results to the destination array. For any wchar_t in the input that 1477132720Skan * cannot be converted, @a dfault is used instead. For an underived 1478132720Skan * ctype<wchar_t> facet, the argument will be copied, casting each 1479132720Skan * element to char. 1480132720Skan * 1481132720Skan * do_narrow() is a hook for a derived facet to change the behavior of 1482132720Skan * narrowing. do_narrow() must always return the same result for the 1483132720Skan * same input. 1484132720Skan * 1485132720Skan * Note: this is not what you want for codepage conversions. See 1486132720Skan * codecvt for that. 1487132720Skan * 1488132720Skan * @param lo Pointer to start of range. 1489132720Skan * @param hi Pointer to end of range. 1490132720Skan * @param dfault Char to use if conversion fails. 1491132720Skan * @param to Pointer to the destination array. 1492132720Skan * @return @a hi. 1493132720Skan */ 149497403Sobrien virtual const char_type* 149597403Sobrien do_narrow(const char_type* __lo, const char_type* __hi, 149697403Sobrien char __dfault, char* __dest) const; 149797403Sobrien 1498132720Skan // For use at construction time only. 1499132720Skan void 1500132720Skan _M_initialize_ctype(); 150197403Sobrien }; 150297403Sobrien 150397403Sobrien template<> 150497403Sobrien const ctype<wchar_t>& 150597403Sobrien use_facet<ctype<wchar_t> >(const locale& __loc); 1506132720Skan#endif //_GLIBCXX_USE_WCHAR_T 150797403Sobrien 1508169691Skan /// @brief class ctype_byname [22.2.1.2]. 150997403Sobrien template<typename _CharT> 151097403Sobrien class ctype_byname : public ctype<_CharT> 151197403Sobrien { 151297403Sobrien public: 1513132720Skan typedef _CharT char_type; 151497403Sobrien 1515132720Skan explicit 151697403Sobrien ctype_byname(const char* __s, size_t __refs = 0); 151797403Sobrien 151897403Sobrien protected: 1519132720Skan virtual 152097403Sobrien ~ctype_byname() { }; 152197403Sobrien }; 152297403Sobrien 1523169691Skan /// 22.2.1.4 Class ctype_byname specializations. 152497403Sobrien template<> 152597403Sobrien ctype_byname<char>::ctype_byname(const char*, size_t refs); 152697403Sobrien 152797403Sobrien template<> 152897403Sobrien ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs); 152997403Sobrien 1530169691Skan_GLIBCXX_END_NAMESPACE 153197403Sobrien 1532169691Skan// Include host and configuration specific ctype inlines. 1533169691Skan#include <bits/ctype_inline.h> 1534169691Skan 1535169691Skan// 22.2.1.5 Template class codecvt 1536169691Skan#include <bits/codecvt.h> 1537169691Skan 1538169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 1539169691Skan 154097403Sobrien // 22.2.2 The numeric category. 1541132720Skan class __num_base 154297403Sobrien { 1543117397Skan public: 1544117397Skan // NB: Code depends on the order of _S_atoms_out elements. 1545117397Skan // Below are the indices into _S_atoms_out. 1546132720Skan enum 1547132720Skan { 1548132720Skan _S_ominus, 1549132720Skan _S_oplus, 1550132720Skan _S_ox, 1551132720Skan _S_oX, 1552132720Skan _S_odigits, 1553132720Skan _S_odigits_end = _S_odigits + 16, 1554132720Skan _S_oudigits = _S_odigits_end, 1555132720Skan _S_oudigits_end = _S_oudigits + 16, 1556132720Skan _S_oe = _S_odigits + 14, // For scientific notation, 'e' 1557132720Skan _S_oE = _S_oudigits + 14, // For scientific notation, 'E' 1558132720Skan _S_oend = _S_oudigits_end 1559117397Skan }; 1560132720Skan 1561117397Skan // A list of valid numeric literals for output. This array 1562117397Skan // contains chars that will be passed through the current locale's 1563117397Skan // ctype<_CharT>.widen() and then used to render numbers. 1564117397Skan // For the standard "C" locale, this is 1565117397Skan // "-+xX0123456789abcdef0123456789ABCDEF". 1566117397Skan static const char* _S_atoms_out; 1567117397Skan 156897403Sobrien // String literal of acceptable (narrow) input, for num_get. 1569132720Skan // "-+xX0123456789abcdefABCDEF" 1570117397Skan static const char* _S_atoms_in; 157197403Sobrien 1572132720Skan enum 1573132720Skan { 1574132720Skan _S_iminus, 1575132720Skan _S_iplus, 1576132720Skan _S_ix, 1577132720Skan _S_iX, 1578132720Skan _S_izero, 1579132720Skan _S_ie = _S_izero + 14, 1580132720Skan _S_iE = _S_izero + 20, 1581132720Skan _S_iend = 26 158297403Sobrien }; 158397403Sobrien 158497403Sobrien // num_put 158597403Sobrien // Construct and return valid scanf format for floating point types. 1586117397Skan static void 1587132720Skan _S_format_float(const ios_base& __io, char* __fptr, char __mod); 158897403Sobrien }; 158997403Sobrien 1590132720Skan template<typename _CharT> 1591132720Skan struct __numpunct_cache : public locale::facet 1592132720Skan { 1593132720Skan const char* _M_grouping; 1594132720Skan size_t _M_grouping_size; 1595132720Skan bool _M_use_grouping; 1596132720Skan const _CharT* _M_truename; 1597132720Skan size_t _M_truename_size; 1598132720Skan const _CharT* _M_falsename; 1599132720Skan size_t _M_falsename_size; 1600132720Skan _CharT _M_decimal_point; 1601132720Skan _CharT _M_thousands_sep; 160297403Sobrien 1603132720Skan // A list of valid numeric literals for output: in the standard 1604132720Skan // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". 1605132720Skan // This array contains the chars after having been passed 1606132720Skan // through the current locale's ctype<_CharT>.widen(). 1607132720Skan _CharT _M_atoms_out[__num_base::_S_oend]; 1608132720Skan 1609132720Skan // A list of valid numeric literals for input: in the standard 1610132720Skan // "C" locale, this is "-+xX0123456789abcdefABCDEF" 1611132720Skan // This array contains the chars after having been passed 1612132720Skan // through the current locale's ctype<_CharT>.widen(). 1613132720Skan _CharT _M_atoms_in[__num_base::_S_iend]; 1614132720Skan 1615132720Skan bool _M_allocated; 1616132720Skan 1617132720Skan __numpunct_cache(size_t __refs = 0) : facet(__refs), 1618132720Skan _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), 1619132720Skan _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL), 1620132720Skan _M_falsename_size(0), _M_decimal_point(_CharT()), 1621132720Skan _M_thousands_sep(_CharT()), _M_allocated(false) 1622132720Skan { } 1623132720Skan 1624132720Skan ~__numpunct_cache(); 1625132720Skan 1626132720Skan void 1627132720Skan _M_cache(const locale& __loc); 1628132720Skan 1629132720Skan private: 1630132720Skan __numpunct_cache& 1631132720Skan operator=(const __numpunct_cache&); 1632132720Skan 1633132720Skan explicit 1634132720Skan __numpunct_cache(const __numpunct_cache&); 1635132720Skan }; 1636132720Skan 163797403Sobrien template<typename _CharT> 1638132720Skan __numpunct_cache<_CharT>::~__numpunct_cache() 1639132720Skan { 1640132720Skan if (_M_allocated) 1641132720Skan { 1642132720Skan delete [] _M_grouping; 1643132720Skan delete [] _M_truename; 1644132720Skan delete [] _M_falsename; 1645132720Skan } 1646132720Skan } 1647117397Skan 1648132720Skan /** 1649132720Skan * @brief Numpunct facet. 1650132720Skan * 1651132720Skan * This facet stores several pieces of information related to printing and 1652132720Skan * scanning numbers, such as the decimal point character. It takes a 1653132720Skan * template parameter specifying the char type. The numpunct facet is 1654132720Skan * used by streams for many I/O operations involving numbers. 1655132720Skan * 1656132720Skan * The numpunct template uses protected virtual functions to provide the 1657132720Skan * actual results. The public accessors forward the call to the virtual 1658132720Skan * functions. These virtual functions are hooks for developers to 1659132720Skan * implement the behavior they require from a numpunct facet. 1660132720Skan */ 1661117397Skan template<typename _CharT> 166297403Sobrien class numpunct : public locale::facet 166397403Sobrien { 166497403Sobrien public: 166597403Sobrien // Types: 1666132720Skan //@{ 1667132720Skan /// Public typedefs 1668132720Skan typedef _CharT char_type; 1669132720Skan typedef basic_string<_CharT> string_type; 1670132720Skan //@} 1671132720Skan typedef __numpunct_cache<_CharT> __cache_type; 167297403Sobrien 1673132720Skan protected: 1674132720Skan __cache_type* _M_data; 1675117397Skan 1676132720Skan public: 1677132720Skan /// Numpunct facet id. 1678132720Skan static locale::id id; 167997403Sobrien 1680132720Skan /** 1681132720Skan * @brief Numpunct constructor. 1682132720Skan * 1683132720Skan * @param refs Refcount to pass to the base class. 1684132720Skan */ 1685132720Skan explicit 1686132720Skan numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) 1687132720Skan { _M_initialize_numpunct(); } 168897403Sobrien 1689132720Skan /** 1690132720Skan * @brief Internal constructor. Not for general use. 1691132720Skan * 1692132720Skan * This is a constructor for use by the library itself to set up the 1693132720Skan * predefined locale facets. 1694132720Skan * 1695132720Skan * @param cache __numpunct_cache object. 1696132720Skan * @param refs Refcount to pass to the base class. 1697132720Skan */ 1698132720Skan explicit 1699132720Skan numpunct(__cache_type* __cache, size_t __refs = 0) 1700132720Skan : facet(__refs), _M_data(__cache) 170197403Sobrien { _M_initialize_numpunct(); } 170297403Sobrien 1703132720Skan /** 1704132720Skan * @brief Internal constructor. Not for general use. 1705132720Skan * 1706132720Skan * This is a constructor for use by the library itself to set up new 1707132720Skan * locales. 1708132720Skan * 1709132720Skan * @param cloc The "C" locale. 1710132720Skan * @param refs Refcount to pass to the base class. 1711132720Skan */ 1712132720Skan explicit 1713132720Skan numpunct(__c_locale __cloc, size_t __refs = 0) 1714132720Skan : facet(__refs), _M_data(NULL) 171597403Sobrien { _M_initialize_numpunct(__cloc); } 171697403Sobrien 1717132720Skan /** 1718132720Skan * @brief Return decimal point character. 1719132720Skan * 1720132720Skan * This function returns a char_type to use as a decimal point. It 1721132720Skan * does so by returning returning 1722132720Skan * numpunct<char_type>::do_decimal_point(). 1723132720Skan * 1724132720Skan * @return @a char_type representing a decimal point. 1725132720Skan */ 1726132720Skan char_type 172797403Sobrien decimal_point() const 172897403Sobrien { return this->do_decimal_point(); } 172997403Sobrien 1730132720Skan /** 1731132720Skan * @brief Return thousands separator character. 1732132720Skan * 1733132720Skan * This function returns a char_type to use as a thousands 1734132720Skan * separator. It does so by returning returning 1735132720Skan * numpunct<char_type>::do_thousands_sep(). 1736132720Skan * 1737132720Skan * @return char_type representing a thousands separator. 1738132720Skan */ 1739132720Skan char_type 174097403Sobrien thousands_sep() const 174197403Sobrien { return this->do_thousands_sep(); } 174297403Sobrien 1743132720Skan /** 1744132720Skan * @brief Return grouping specification. 1745132720Skan * 1746132720Skan * This function returns a string representing groupings for the 1747132720Skan * integer part of a number. Groupings indicate where thousands 1748132720Skan * separators should be inserted in the integer part of a number. 1749132720Skan * 1750132720Skan * Each char in the return string is interpret as an integer 1751132720Skan * rather than a character. These numbers represent the number 1752132720Skan * of digits in a group. The first char in the string 1753132720Skan * represents the number of digits in the least significant 1754132720Skan * group. If a char is negative, it indicates an unlimited 1755132720Skan * number of digits for the group. If more chars from the 1756132720Skan * string are required to group a number, the last char is used 1757132720Skan * repeatedly. 1758132720Skan * 1759132720Skan * For example, if the grouping() returns "\003\002" and is 1760132720Skan * applied to the number 123456789, this corresponds to 1761132720Skan * 12,34,56,789. Note that if the string was "32", this would 1762132720Skan * put more than 50 digits into the least significant group if 1763132720Skan * the character set is ASCII. 1764132720Skan * 1765132720Skan * The string is returned by calling 1766132720Skan * numpunct<char_type>::do_grouping(). 1767132720Skan * 1768132720Skan * @return string representing grouping specification. 1769132720Skan */ 1770132720Skan string 177197403Sobrien grouping() const 177297403Sobrien { return this->do_grouping(); } 177397403Sobrien 1774132720Skan /** 1775132720Skan * @brief Return string representation of bool true. 1776132720Skan * 1777132720Skan * This function returns a string_type containing the text 1778132720Skan * representation for true bool variables. It does so by calling 1779132720Skan * numpunct<char_type>::do_truename(). 1780132720Skan * 1781132720Skan * @return string_type representing printed form of true. 1782132720Skan */ 1783132720Skan string_type 178497403Sobrien truename() const 178597403Sobrien { return this->do_truename(); } 178697403Sobrien 1787132720Skan /** 1788132720Skan * @brief Return string representation of bool false. 1789132720Skan * 1790132720Skan * This function returns a string_type containing the text 1791132720Skan * representation for false bool variables. It does so by calling 1792132720Skan * numpunct<char_type>::do_falsename(). 1793132720Skan * 1794132720Skan * @return string_type representing printed form of false. 1795132720Skan */ 1796132720Skan string_type 179797403Sobrien falsename() const 179897403Sobrien { return this->do_falsename(); } 179997403Sobrien 180097403Sobrien protected: 1801132720Skan /// Destructor. 1802132720Skan virtual 180397403Sobrien ~numpunct(); 180497403Sobrien 1805132720Skan /** 1806132720Skan * @brief Return decimal point character. 1807132720Skan * 1808132720Skan * Returns a char_type to use as a decimal point. This function is a 1809132720Skan * hook for derived classes to change the value returned. 1810132720Skan * 1811132720Skan * @return @a char_type representing a decimal point. 1812132720Skan */ 1813132720Skan virtual char_type 181497403Sobrien do_decimal_point() const 1815132720Skan { return _M_data->_M_decimal_point; } 181697403Sobrien 1817132720Skan /** 1818132720Skan * @brief Return thousands separator character. 1819132720Skan * 1820132720Skan * Returns a char_type to use as a thousands separator. This function 1821132720Skan * is a hook for derived classes to change the value returned. 1822132720Skan * 1823132720Skan * @return @a char_type representing a thousands separator. 1824132720Skan */ 1825132720Skan virtual char_type 182697403Sobrien do_thousands_sep() const 1827132720Skan { return _M_data->_M_thousands_sep; } 182897403Sobrien 1829132720Skan /** 1830132720Skan * @brief Return grouping specification. 1831132720Skan * 1832132720Skan * Returns a string representing groupings for the integer part of a 1833132720Skan * number. This function is a hook for derived classes to change the 1834132720Skan * value returned. @see grouping() for details. 1835132720Skan * 1836132720Skan * @return String representing grouping specification. 1837132720Skan */ 183897403Sobrien virtual string 183997403Sobrien do_grouping() const 1840132720Skan { return _M_data->_M_grouping; } 184197403Sobrien 1842132720Skan /** 1843132720Skan * @brief Return string representation of bool true. 1844132720Skan * 1845132720Skan * Returns a string_type containing the text representation for true 1846132720Skan * bool variables. This function is a hook for derived classes to 1847132720Skan * change the value returned. 1848132720Skan * 1849132720Skan * @return string_type representing printed form of true. 1850132720Skan */ 1851132720Skan virtual string_type 185297403Sobrien do_truename() const 1853132720Skan { return _M_data->_M_truename; } 185497403Sobrien 1855132720Skan /** 1856132720Skan * @brief Return string representation of bool false. 1857132720Skan * 1858132720Skan * Returns a string_type containing the text representation for false 1859132720Skan * bool variables. This function is a hook for derived classes to 1860132720Skan * change the value returned. 1861132720Skan * 1862132720Skan * @return string_type representing printed form of false. 1863132720Skan */ 1864132720Skan virtual string_type 186597403Sobrien do_falsename() const 1866132720Skan { return _M_data->_M_falsename; } 186797403Sobrien 186897403Sobrien // For use at construction time only. 1869132720Skan void 1870107606Sobrien _M_initialize_numpunct(__c_locale __cloc = NULL); 187197403Sobrien }; 187297403Sobrien 187397403Sobrien template<typename _CharT> 187497403Sobrien locale::id numpunct<_CharT>::id; 187597403Sobrien 1876132720Skan template<> 187797403Sobrien numpunct<char>::~numpunct(); 187897403Sobrien 1879132720Skan template<> 188097403Sobrien void 188197403Sobrien numpunct<char>::_M_initialize_numpunct(__c_locale __cloc); 188297403Sobrien 1883132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 1884132720Skan template<> 188597403Sobrien numpunct<wchar_t>::~numpunct(); 188697403Sobrien 1887132720Skan template<> 188897403Sobrien void 188997403Sobrien numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc); 189097403Sobrien#endif 189197403Sobrien 1892169691Skan /// @brief class numpunct_byname [22.2.3.2]. 189397403Sobrien template<typename _CharT> 189497403Sobrien class numpunct_byname : public numpunct<_CharT> 189597403Sobrien { 189697403Sobrien public: 1897132720Skan typedef _CharT char_type; 1898132720Skan typedef basic_string<_CharT> string_type; 189997403Sobrien 1900132720Skan explicit 190197403Sobrien numpunct_byname(const char* __s, size_t __refs = 0) 190297403Sobrien : numpunct<_CharT>(__refs) 190397403Sobrien { 1904132720Skan if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 1905132720Skan { 1906132720Skan __c_locale __tmp; 1907132720Skan this->_S_create_c_locale(__tmp, __s); 1908132720Skan this->_M_initialize_numpunct(__tmp); 1909132720Skan this->_S_destroy_c_locale(__tmp); 1910132720Skan } 191197403Sobrien } 191297403Sobrien 191397403Sobrien protected: 1914132720Skan virtual 1915132720Skan ~numpunct_byname() { } 191697403Sobrien }; 191797403Sobrien 1918169691Skan_GLIBCXX_BEGIN_LDBL_NAMESPACE 1919132720Skan /** 1920132720Skan * @brief Facet for parsing number strings. 1921132720Skan * 1922132720Skan * This facet encapsulates the code to parse and return a number 1923132720Skan * from a string. It is used by the istream numeric extraction 1924132720Skan * operators. 1925132720Skan * 1926132720Skan * The num_get template uses protected virtual functions to provide the 1927132720Skan * actual results. The public accessors forward the call to the virtual 1928132720Skan * functions. These virtual functions are hooks for developers to 1929132720Skan * implement the behavior they require from the num_get facet. 1930132720Skan */ 193197403Sobrien template<typename _CharT, typename _InIter> 1932132720Skan class num_get : public locale::facet 193397403Sobrien { 193497403Sobrien public: 193597403Sobrien // Types: 1936132720Skan //@{ 1937132720Skan /// Public typedefs 1938132720Skan typedef _CharT char_type; 1939132720Skan typedef _InIter iter_type; 1940132720Skan //@} 194197403Sobrien 1942132720Skan /// Numpunct facet id. 1943132720Skan static locale::id id; 194497403Sobrien 1945132720Skan /** 1946132720Skan * @brief Constructor performs initialization. 1947132720Skan * 1948132720Skan * This is the constructor provided by the standard. 1949132720Skan * 1950132720Skan * @param refs Passed to the base facet class. 1951132720Skan */ 1952132720Skan explicit 1953132720Skan num_get(size_t __refs = 0) : facet(__refs) { } 195497403Sobrien 1955132720Skan /** 1956132720Skan * @brief Numeric parsing. 1957132720Skan * 1958132720Skan * Parses the input stream into the bool @a v. It does so by calling 1959169691Skan * num_get::do_get(). 1960132720Skan * 1961132720Skan * If ios_base::boolalpha is set, attempts to read 1962132720Skan * ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets 1963132720Skan * @a v to true or false if successful. Sets err to 1964132720Skan * ios_base::failbit if reading the string fails. Sets err to 1965132720Skan * ios_base::eofbit if the stream is emptied. 1966132720Skan * 1967132720Skan * If ios_base::boolalpha is not set, proceeds as with reading a long, 1968132720Skan * except if the value is 1, sets @a v to true, if the value is 0, sets 1969132720Skan * @a v to false, and otherwise set err to ios_base::failbit. 1970132720Skan * 1971132720Skan * @param in Start of input stream. 1972132720Skan * @param end End of input stream. 1973132720Skan * @param io Source of locale and flags. 1974132720Skan * @param err Error flags to set. 1975132720Skan * @param v Value to format and insert. 1976132720Skan * @return Iterator after reading. 1977132720Skan */ 1978132720Skan iter_type 197997403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 198097403Sobrien ios_base::iostate& __err, bool& __v) const 198197403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 198297403Sobrien 1983132720Skan //@{ 1984132720Skan /** 1985132720Skan * @brief Numeric parsing. 1986132720Skan * 1987132720Skan * Parses the input stream into the integral variable @a v. It does so 1988169691Skan * by calling num_get::do_get(). 1989132720Skan * 1990132720Skan * Parsing is affected by the flag settings in @a io. 1991132720Skan * 1992132720Skan * The basic parse is affected by the value of io.flags() & 1993132720Skan * ios_base::basefield. If equal to ios_base::oct, parses like the 1994132720Skan * scanf %o specifier. Else if equal to ios_base::hex, parses like %X 1995132720Skan * specifier. Else if basefield equal to 0, parses like the %i 1996132720Skan * specifier. Otherwise, parses like %d for signed and %u for unsigned 1997132720Skan * types. The matching type length modifier is also used. 1998132720Skan * 1999132720Skan * Digit grouping is intrepreted according to numpunct::grouping() and 2000132720Skan * numpunct::thousands_sep(). If the pattern of digit groups isn't 2001132720Skan * consistent, sets err to ios_base::failbit. 2002132720Skan * 2003132720Skan * If parsing the string yields a valid value for @a v, @a v is set. 2004132720Skan * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 2005132720Skan * Sets err to ios_base::eofbit if the stream is emptied. 2006132720Skan * 2007132720Skan * @param in Start of input stream. 2008132720Skan * @param end End of input stream. 2009132720Skan * @param io Source of locale and flags. 2010132720Skan * @param err Error flags to set. 2011132720Skan * @param v Value to format and insert. 2012132720Skan * @return Iterator after reading. 2013132720Skan */ 201497403Sobrien iter_type 2015132720Skan get(iter_type __in, iter_type __end, ios_base& __io, 201697403Sobrien ios_base::iostate& __err, long& __v) const 201797403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 201897403Sobrien 2019132720Skan iter_type 202097403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 202197403Sobrien ios_base::iostate& __err, unsigned short& __v) const 202297403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 202397403Sobrien 2024132720Skan iter_type 202597403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 202697403Sobrien ios_base::iostate& __err, unsigned int& __v) const 202797403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 202897403Sobrien 2029132720Skan iter_type 203097403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 203197403Sobrien ios_base::iostate& __err, unsigned long& __v) const 203297403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 203397403Sobrien 2034132720Skan#ifdef _GLIBCXX_USE_LONG_LONG 2035132720Skan iter_type 203697403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 203797403Sobrien ios_base::iostate& __err, long long& __v) const 203897403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 203997403Sobrien 2040132720Skan iter_type 204197403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 204297403Sobrien ios_base::iostate& __err, unsigned long long& __v) const 204397403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 204497403Sobrien#endif 2045132720Skan //@} 204697403Sobrien 2047132720Skan //@{ 2048132720Skan /** 2049132720Skan * @brief Numeric parsing. 2050132720Skan * 2051132720Skan * Parses the input stream into the integral variable @a v. It does so 2052169691Skan * by calling num_get::do_get(). 2053132720Skan * 2054132720Skan * The input characters are parsed like the scanf %g specifier. The 2055132720Skan * matching type length modifier is also used. 2056132720Skan * 2057132720Skan * The decimal point character used is numpunct::decimal_point(). 2058132720Skan * Digit grouping is intrepreted according to numpunct::grouping() and 2059132720Skan * numpunct::thousands_sep(). If the pattern of digit groups isn't 2060132720Skan * consistent, sets err to ios_base::failbit. 2061132720Skan * 2062132720Skan * If parsing the string yields a valid value for @a v, @a v is set. 2063132720Skan * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 2064132720Skan * Sets err to ios_base::eofbit if the stream is emptied. 2065132720Skan * 2066132720Skan * @param in Start of input stream. 2067132720Skan * @param end End of input stream. 2068132720Skan * @param io Source of locale and flags. 2069132720Skan * @param err Error flags to set. 2070132720Skan * @param v Value to format and insert. 2071132720Skan * @return Iterator after reading. 2072132720Skan */ 2073132720Skan iter_type 207497403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 207597403Sobrien ios_base::iostate& __err, float& __v) const 207697403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 207797403Sobrien 2078132720Skan iter_type 207997403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 208097403Sobrien ios_base::iostate& __err, double& __v) const 208197403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 208297403Sobrien 2083132720Skan iter_type 208497403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 208597403Sobrien ios_base::iostate& __err, long double& __v) const 208697403Sobrien { return this->do_get(__in, __end, __io, __err, __v); } 2087132720Skan //@} 208897403Sobrien 2089132720Skan /** 2090132720Skan * @brief Numeric parsing. 2091132720Skan * 2092132720Skan * Parses the input stream into the pointer variable @a v. It does so 2093169691Skan * by calling num_get::do_get(). 2094132720Skan * 2095132720Skan * The input characters are parsed like the scanf %p specifier. 2096132720Skan * 2097132720Skan * Digit grouping is intrepreted according to numpunct::grouping() and 2098132720Skan * numpunct::thousands_sep(). If the pattern of digit groups isn't 2099132720Skan * consistent, sets err to ios_base::failbit. 2100132720Skan * 2101132720Skan * Note that the digit grouping effect for pointers is a bit ambiguous 2102132720Skan * in the standard and shouldn't be relied on. See DR 344. 2103132720Skan * 2104132720Skan * If parsing the string yields a valid value for @a v, @a v is set. 2105132720Skan * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 2106132720Skan * Sets err to ios_base::eofbit if the stream is emptied. 2107132720Skan * 2108132720Skan * @param in Start of input stream. 2109132720Skan * @param end End of input stream. 2110132720Skan * @param io Source of locale and flags. 2111132720Skan * @param err Error flags to set. 2112132720Skan * @param v Value to format and insert. 2113132720Skan * @return Iterator after reading. 2114132720Skan */ 2115132720Skan iter_type 211697403Sobrien get(iter_type __in, iter_type __end, ios_base& __io, 211797403Sobrien ios_base::iostate& __err, void*& __v) const 2118132720Skan { return this->do_get(__in, __end, __io, __err, __v); } 211997403Sobrien 212097403Sobrien protected: 2121132720Skan /// Destructor. 212297403Sobrien virtual ~num_get() { } 212397403Sobrien 2124132720Skan iter_type 2125132720Skan _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, 212697403Sobrien string& __xtrc) const; 212797403Sobrien 2128132720Skan template<typename _ValueT> 2129132720Skan iter_type 2130132720Skan _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, 2131132720Skan _ValueT& __v) const; 213297403Sobrien 2133169691Skan template<typename _CharT2> 2134169691Skan typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, int>::__type 2135169691Skan _M_find(const _CharT2*, size_t __len, _CharT2 __c) const 2136169691Skan { 2137169691Skan int __ret = -1; 2138169691Skan if (__len <= 10) 2139169691Skan { 2140169691Skan if (__c >= _CharT2('0') && __c < _CharT2(_CharT2('0') + __len)) 2141169691Skan __ret = __c - _CharT2('0'); 2142169691Skan } 2143169691Skan else 2144169691Skan { 2145169691Skan if (__c >= _CharT2('0') && __c <= _CharT2('9')) 2146169691Skan __ret = __c - _CharT2('0'); 2147169691Skan else if (__c >= _CharT2('a') && __c <= _CharT2('f')) 2148169691Skan __ret = 10 + (__c - _CharT2('a')); 2149169691Skan else if (__c >= _CharT2('A') && __c <= _CharT2('F')) 2150169691Skan __ret = 10 + (__c - _CharT2('A')); 2151169691Skan } 2152169691Skan return __ret; 2153169691Skan } 2154169691Skan 2155169691Skan template<typename _CharT2> 2156169691Skan typename __gnu_cxx::__enable_if<!__is_char<_CharT2>::__value, 2157169691Skan int>::__type 2158169691Skan _M_find(const _CharT2* __zero, size_t __len, _CharT2 __c) const 2159169691Skan { 2160169691Skan int __ret = -1; 2161169691Skan const char_type* __q = char_traits<_CharT2>::find(__zero, __len, __c); 2162169691Skan if (__q) 2163169691Skan { 2164169691Skan __ret = __q - __zero; 2165169691Skan if (__ret > 15) 2166169691Skan __ret -= 6; 2167169691Skan } 2168169691Skan return __ret; 2169169691Skan } 2170169691Skan 2171132720Skan //@{ 2172132720Skan /** 2173132720Skan * @brief Numeric parsing. 2174132720Skan * 2175132720Skan * Parses the input stream into the variable @a v. This function is a 2176132720Skan * hook for derived classes to change the value returned. @see get() 2177132720Skan * for more details. 2178132720Skan * 2179132720Skan * @param in Start of input stream. 2180132720Skan * @param end End of input stream. 2181132720Skan * @param io Source of locale and flags. 2182132720Skan * @param err Error flags to set. 2183132720Skan * @param v Value to format and insert. 2184132720Skan * @return Iterator after reading. 2185132720Skan */ 2186132720Skan virtual iter_type 218797403Sobrien do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; 218897403Sobrien 2189102782Skan 2190132720Skan virtual iter_type 219197403Sobrien do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; 219297403Sobrien 2193132720Skan virtual iter_type 2194132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 219597403Sobrien unsigned short&) const; 219697403Sobrien 2197132720Skan virtual iter_type 2198132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 219997403Sobrien unsigned int&) const; 220097403Sobrien 2201132720Skan virtual iter_type 2202132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 220397403Sobrien unsigned long&) const; 220497403Sobrien 2205132720Skan#ifdef _GLIBCXX_USE_LONG_LONG 2206132720Skan virtual iter_type 2207132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 220897403Sobrien long long&) const; 220997403Sobrien 2210132720Skan virtual iter_type 2211132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 221297403Sobrien unsigned long long&) const; 221397403Sobrien#endif 221497403Sobrien 2215132720Skan virtual iter_type 2216132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 221797403Sobrien float&) const; 221897403Sobrien 2219132720Skan virtual iter_type 2220132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 222197403Sobrien double&) const; 222297403Sobrien 2223169691Skan // XXX GLIBCXX_ABI Deprecated 2224169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 2225132720Skan virtual iter_type 2226169691Skan __do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2227169691Skan double&) const; 2228169691Skan#else 2229169691Skan virtual iter_type 2230132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 223197403Sobrien long double&) const; 2232169691Skan#endif 223397403Sobrien 2234132720Skan virtual iter_type 2235132720Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 223697403Sobrien void*&) const; 2237169691Skan 2238169691Skan // XXX GLIBCXX_ABI Deprecated 2239169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 2240169691Skan virtual iter_type 2241169691Skan do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2242169691Skan long double&) const; 2243169691Skan#endif 2244132720Skan //@} 224597403Sobrien }; 224697403Sobrien 224797403Sobrien template<typename _CharT, typename _InIter> 224897403Sobrien locale::id num_get<_CharT, _InIter>::id; 224997403Sobrien 2250102782Skan 2251132720Skan /** 2252132720Skan * @brief Facet for converting numbers to strings. 2253132720Skan * 2254132720Skan * This facet encapsulates the code to convert a number to a string. It is 2255132720Skan * used by the ostream numeric insertion operators. 2256132720Skan * 2257132720Skan * The num_put template uses protected virtual functions to provide the 2258132720Skan * actual results. The public accessors forward the call to the virtual 2259132720Skan * functions. These virtual functions are hooks for developers to 2260132720Skan * implement the behavior they require from the num_put facet. 2261132720Skan */ 226297403Sobrien template<typename _CharT, typename _OutIter> 2263132720Skan class num_put : public locale::facet 226497403Sobrien { 226597403Sobrien public: 226697403Sobrien // Types: 2267132720Skan //@{ 2268132720Skan /// Public typedefs 2269132720Skan typedef _CharT char_type; 2270132720Skan typedef _OutIter iter_type; 2271132720Skan //@} 2272132720Skan 2273132720Skan /// Numpunct facet id. 227497403Sobrien static locale::id id; 227597403Sobrien 2276132720Skan /** 2277132720Skan * @brief Constructor performs initialization. 2278132720Skan * 2279132720Skan * This is the constructor provided by the standard. 2280132720Skan * 2281132720Skan * @param refs Passed to the base facet class. 2282132720Skan */ 2283132720Skan explicit 2284132720Skan num_put(size_t __refs = 0) : facet(__refs) { } 228597403Sobrien 2286132720Skan /** 2287132720Skan * @brief Numeric formatting. 2288132720Skan * 2289132720Skan * Formats the boolean @a v and inserts it into a stream. It does so 2290132720Skan * by calling num_put::do_put(). 2291132720Skan * 2292132720Skan * If ios_base::boolalpha is set, writes ctype<CharT>::truename() or 2293132720Skan * ctype<CharT>::falsename(). Otherwise formats @a v as an int. 2294132720Skan * 2295132720Skan * @param s Stream to write to. 2296132720Skan * @param io Source of locale and flags. 2297132720Skan * @param fill Char_type to use for filling. 2298132720Skan * @param v Value to format and insert. 2299132720Skan * @return Iterator after writing. 2300132720Skan */ 2301132720Skan iter_type 230297403Sobrien put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const 230397403Sobrien { return this->do_put(__s, __f, __fill, __v); } 230497403Sobrien 2305132720Skan //@{ 2306132720Skan /** 2307132720Skan * @brief Numeric formatting. 2308132720Skan * 2309132720Skan * Formats the integral value @a v and inserts it into a 2310132720Skan * stream. It does so by calling num_put::do_put(). 2311132720Skan * 2312132720Skan * Formatting is affected by the flag settings in @a io. 2313132720Skan * 2314132720Skan * The basic format is affected by the value of io.flags() & 2315132720Skan * ios_base::basefield. If equal to ios_base::oct, formats like the 2316132720Skan * printf %o specifier. Else if equal to ios_base::hex, formats like 2317132720Skan * %x or %X with ios_base::uppercase unset or set respectively. 2318132720Skan * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu 2319132720Skan * for unsigned values. Note that if both oct and hex are set, neither 2320132720Skan * will take effect. 2321132720Skan * 2322132720Skan * If ios_base::showpos is set, '+' is output before positive values. 2323132720Skan * If ios_base::showbase is set, '0' precedes octal values (except 0) 2324132720Skan * and '0[xX]' precedes hex values. 2325132720Skan * 2326132720Skan * Thousands separators are inserted according to numpunct::grouping() 2327132720Skan * and numpunct::thousands_sep(). The decimal point character used is 2328132720Skan * numpunct::decimal_point(). 2329132720Skan * 2330132720Skan * If io.width() is non-zero, enough @a fill characters are inserted to 2331132720Skan * make the result at least that wide. If 2332132720Skan * (io.flags() & ios_base::adjustfield) == ios_base::left, result is 2333132720Skan * padded at the end. If ios_base::internal, then padding occurs 2334132720Skan * immediately after either a '+' or '-' or after '0x' or '0X'. 2335132720Skan * Otherwise, padding occurs at the beginning. 2336132720Skan * 2337132720Skan * @param s Stream to write to. 2338132720Skan * @param io Source of locale and flags. 2339132720Skan * @param fill Char_type to use for filling. 2340132720Skan * @param v Value to format and insert. 2341132720Skan * @return Iterator after writing. 2342132720Skan */ 2343132720Skan iter_type 234497403Sobrien put(iter_type __s, ios_base& __f, char_type __fill, long __v) const 234597403Sobrien { return this->do_put(__s, __f, __fill, __v); } 234697403Sobrien 2347132720Skan iter_type 2348132720Skan put(iter_type __s, ios_base& __f, char_type __fill, 234997403Sobrien unsigned long __v) const 235097403Sobrien { return this->do_put(__s, __f, __fill, __v); } 235197403Sobrien 2352132720Skan#ifdef _GLIBCXX_USE_LONG_LONG 2353132720Skan iter_type 235497403Sobrien put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const 235597403Sobrien { return this->do_put(__s, __f, __fill, __v); } 235697403Sobrien 2357132720Skan iter_type 2358132720Skan put(iter_type __s, ios_base& __f, char_type __fill, 235997403Sobrien unsigned long long __v) const 236097403Sobrien { return this->do_put(__s, __f, __fill, __v); } 236197403Sobrien#endif 2362132720Skan //@} 236397403Sobrien 2364132720Skan //@{ 2365132720Skan /** 2366132720Skan * @brief Numeric formatting. 2367132720Skan * 2368132720Skan * Formats the floating point value @a v and inserts it into a stream. 2369132720Skan * It does so by calling num_put::do_put(). 2370132720Skan * 2371132720Skan * Formatting is affected by the flag settings in @a io. 2372132720Skan * 2373132720Skan * The basic format is affected by the value of io.flags() & 2374132720Skan * ios_base::floatfield. If equal to ios_base::fixed, formats like the 2375132720Skan * printf %f specifier. Else if equal to ios_base::scientific, formats 2376132720Skan * like %e or %E with ios_base::uppercase unset or set respectively. 2377132720Skan * Otherwise, formats like %g or %G depending on uppercase. Note that 2378132720Skan * if both fixed and scientific are set, the effect will also be like 2379132720Skan * %g or %G. 2380132720Skan * 2381132720Skan * The output precision is given by io.precision(). This precision is 2382132720Skan * capped at numeric_limits::digits10 + 2 (different for double and 2383132720Skan * long double). The default precision is 6. 2384132720Skan * 2385132720Skan * If ios_base::showpos is set, '+' is output before positive values. 2386132720Skan * If ios_base::showpoint is set, a decimal point will always be 2387132720Skan * output. 2388132720Skan * 2389132720Skan * Thousands separators are inserted according to numpunct::grouping() 2390132720Skan * and numpunct::thousands_sep(). The decimal point character used is 2391132720Skan * numpunct::decimal_point(). 2392132720Skan * 2393132720Skan * If io.width() is non-zero, enough @a fill characters are inserted to 2394132720Skan * make the result at least that wide. If 2395132720Skan * (io.flags() & ios_base::adjustfield) == ios_base::left, result is 2396132720Skan * padded at the end. If ios_base::internal, then padding occurs 2397132720Skan * immediately after either a '+' or '-' or after '0x' or '0X'. 2398132720Skan * Otherwise, padding occurs at the beginning. 2399132720Skan * 2400132720Skan * @param s Stream to write to. 2401132720Skan * @param io Source of locale and flags. 2402132720Skan * @param fill Char_type to use for filling. 2403132720Skan * @param v Value to format and insert. 2404132720Skan * @return Iterator after writing. 2405132720Skan */ 2406132720Skan iter_type 240797403Sobrien put(iter_type __s, ios_base& __f, char_type __fill, double __v) const 240897403Sobrien { return this->do_put(__s, __f, __fill, __v); } 240997403Sobrien 2410132720Skan iter_type 2411132720Skan put(iter_type __s, ios_base& __f, char_type __fill, 241297403Sobrien long double __v) const 241397403Sobrien { return this->do_put(__s, __f, __fill, __v); } 2414132720Skan //@} 241597403Sobrien 2416132720Skan /** 2417132720Skan * @brief Numeric formatting. 2418132720Skan * 2419132720Skan * Formats the pointer value @a v and inserts it into a stream. It 2420132720Skan * does so by calling num_put::do_put(). 2421132720Skan * 2422132720Skan * This function formats @a v as an unsigned long with ios_base::hex 2423132720Skan * and ios_base::showbase set. 2424132720Skan * 2425132720Skan * @param s Stream to write to. 2426132720Skan * @param io Source of locale and flags. 2427132720Skan * @param fill Char_type to use for filling. 2428132720Skan * @param v Value to format and insert. 2429132720Skan * @return Iterator after writing. 2430132720Skan */ 2431132720Skan iter_type 2432132720Skan put(iter_type __s, ios_base& __f, char_type __fill, 243397403Sobrien const void* __v) const 243497403Sobrien { return this->do_put(__s, __f, __fill, __v); } 243597403Sobrien 243697403Sobrien protected: 243797403Sobrien template<typename _ValueT> 243897403Sobrien iter_type 2439132720Skan _M_insert_float(iter_type, ios_base& __io, char_type __fill, 2440132720Skan char __mod, _ValueT __v) const; 244197403Sobrien 2442117397Skan void 2443132720Skan _M_group_float(const char* __grouping, size_t __grouping_size, 2444132720Skan char_type __sep, const char_type* __p, char_type* __new, 2445132720Skan char_type* __cs, int& __len) const; 2446117397Skan 244797403Sobrien template<typename _ValueT> 244897403Sobrien iter_type 2449132720Skan _M_insert_int(iter_type, ios_base& __io, char_type __fill, 2450132720Skan _ValueT __v) const; 2451117397Skan 2452117397Skan void 2453132720Skan _M_group_int(const char* __grouping, size_t __grouping_size, 2454132720Skan char_type __sep, ios_base& __io, char_type* __new, 2455132720Skan char_type* __cs, int& __len) const; 2456117397Skan 2457117397Skan void 2458132720Skan _M_pad(char_type __fill, streamsize __w, ios_base& __io, 2459117397Skan char_type* __new, const char_type* __cs, int& __len) const; 2460117397Skan 2461132720Skan /// Destructor. 2462132720Skan virtual 246397403Sobrien ~num_put() { }; 246497403Sobrien 2465132720Skan //@{ 2466132720Skan /** 2467132720Skan * @brief Numeric formatting. 2468132720Skan * 2469132720Skan * These functions do the work of formatting numeric values and 2470132720Skan * inserting them into a stream. This function is a hook for derived 2471132720Skan * classes to change the value returned. 2472132720Skan * 2473132720Skan * @param s Stream to write to. 2474132720Skan * @param io Source of locale and flags. 2475132720Skan * @param fill Char_type to use for filling. 2476132720Skan * @param v Value to format and insert. 2477132720Skan * @return Iterator after writing. 2478132720Skan */ 2479132720Skan virtual iter_type 248097403Sobrien do_put(iter_type, ios_base&, char_type __fill, bool __v) const; 248197403Sobrien 2482132720Skan virtual iter_type 248397403Sobrien do_put(iter_type, ios_base&, char_type __fill, long __v) const; 248497403Sobrien 2485132720Skan virtual iter_type 248697403Sobrien do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; 248797403Sobrien 2488132720Skan#ifdef _GLIBCXX_USE_LONG_LONG 2489132720Skan virtual iter_type 249097403Sobrien do_put(iter_type, ios_base&, char_type __fill, long long __v) const; 249197403Sobrien 249297403Sobrien virtual iter_type 249397403Sobrien do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; 249497403Sobrien#endif 249597403Sobrien 2496132720Skan virtual iter_type 249797403Sobrien do_put(iter_type, ios_base&, char_type __fill, double __v) const; 249897403Sobrien 2499169691Skan // XXX GLIBCXX_ABI Deprecated 2500169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 2501132720Skan virtual iter_type 2502169691Skan __do_put(iter_type, ios_base&, char_type __fill, double __v) const; 2503169691Skan#else 2504169691Skan virtual iter_type 250597403Sobrien do_put(iter_type, ios_base&, char_type __fill, long double __v) const; 2506169691Skan#endif 250797403Sobrien 2508132720Skan virtual iter_type 250997403Sobrien do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; 2510169691Skan 2511169691Skan // XXX GLIBCXX_ABI Deprecated 2512169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 2513169691Skan virtual iter_type 2514169691Skan do_put(iter_type, ios_base&, char_type __fill, long double __v) const; 2515169691Skan#endif 2516132720Skan //@} 251797403Sobrien }; 251897403Sobrien 251997403Sobrien template <typename _CharT, typename _OutIter> 252097403Sobrien locale::id num_put<_CharT, _OutIter>::id; 252197403Sobrien 2522169691Skan_GLIBCXX_END_LDBL_NAMESPACE 252397403Sobrien 2524132720Skan /** 2525132720Skan * @brief Facet for localized string comparison. 2526132720Skan * 2527132720Skan * This facet encapsulates the code to compare strings in a localized 2528132720Skan * manner. 2529132720Skan * 2530132720Skan * The collate template uses protected virtual functions to provide 2531132720Skan * the actual results. The public accessors forward the call to 2532132720Skan * the virtual functions. These virtual functions are hooks for 2533132720Skan * developers to implement the behavior they require from the 2534132720Skan * collate facet. 2535132720Skan */ 253697403Sobrien template<typename _CharT> 253797403Sobrien class collate : public locale::facet 253897403Sobrien { 253997403Sobrien public: 254097403Sobrien // Types: 2541132720Skan //@{ 2542132720Skan /// Public typedefs 2543132720Skan typedef _CharT char_type; 2544132720Skan typedef basic_string<_CharT> string_type; 2545132720Skan //@} 254697403Sobrien 254797403Sobrien protected: 254897403Sobrien // Underlying "C" library locale information saved from 254997403Sobrien // initialization, needed by collate_byname as well. 255097403Sobrien __c_locale _M_c_locale_collate; 2551132720Skan 255297403Sobrien public: 2553132720Skan /// Numpunct facet id. 2554132720Skan static locale::id id; 255597403Sobrien 2556132720Skan /** 2557132720Skan * @brief Constructor performs initialization. 2558132720Skan * 2559132720Skan * This is the constructor provided by the standard. 2560132720Skan * 2561132720Skan * @param refs Passed to the base facet class. 2562132720Skan */ 2563132720Skan explicit 256497403Sobrien collate(size_t __refs = 0) 2565132720Skan : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) 2566132720Skan { } 256797403Sobrien 2568132720Skan /** 2569132720Skan * @brief Internal constructor. Not for general use. 2570132720Skan * 2571132720Skan * This is a constructor for use by the library itself to set up new 2572132720Skan * locales. 2573132720Skan * 2574132720Skan * @param cloc The "C" locale. 2575132720Skan * @param refs Passed to the base facet class. 2576132720Skan */ 2577132720Skan explicit 2578132720Skan collate(__c_locale __cloc, size_t __refs = 0) 2579132720Skan : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) 2580132720Skan { } 258197403Sobrien 2582132720Skan /** 2583132720Skan * @brief Compare two strings. 2584132720Skan * 2585132720Skan * This function compares two strings and returns the result by calling 2586132720Skan * collate::do_compare(). 2587132720Skan * 2588132720Skan * @param lo1 Start of string 1. 2589132720Skan * @param hi1 End of string 1. 2590132720Skan * @param lo2 Start of string 2. 2591132720Skan * @param hi2 End of string 2. 2592132720Skan * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 2593132720Skan */ 2594132720Skan int 259597403Sobrien compare(const _CharT* __lo1, const _CharT* __hi1, 259697403Sobrien const _CharT* __lo2, const _CharT* __hi2) const 259797403Sobrien { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } 259897403Sobrien 2599132720Skan /** 2600132720Skan * @brief Transform string to comparable form. 2601132720Skan * 2602132720Skan * This function is a wrapper for strxfrm functionality. It takes the 2603132720Skan * input string and returns a modified string that can be directly 2604132720Skan * compared to other transformed strings. In the "C" locale, this 2605132720Skan * function just returns a copy of the input string. In some other 2606132720Skan * locales, it may replace two chars with one, change a char for 2607132720Skan * another, etc. It does so by returning collate::do_transform(). 2608132720Skan * 2609132720Skan * @param lo Start of string. 2610132720Skan * @param hi End of string. 2611132720Skan * @return Transformed string_type. 2612132720Skan */ 2613132720Skan string_type 261497403Sobrien transform(const _CharT* __lo, const _CharT* __hi) const 261597403Sobrien { return this->do_transform(__lo, __hi); } 261697403Sobrien 2617132720Skan /** 2618132720Skan * @brief Return hash of a string. 2619132720Skan * 2620132720Skan * This function computes and returns a hash on the input string. It 2621132720Skan * does so by returning collate::do_hash(). 2622132720Skan * 2623132720Skan * @param lo Start of string. 2624132720Skan * @param hi End of string. 2625132720Skan * @return Hash value. 2626132720Skan */ 2627132720Skan long 262897403Sobrien hash(const _CharT* __lo, const _CharT* __hi) const 262997403Sobrien { return this->do_hash(__lo, __hi); } 2630132720Skan 263197403Sobrien // Used to abstract out _CharT bits in virtual member functions, below. 263297403Sobrien int 263397403Sobrien _M_compare(const _CharT*, const _CharT*) const; 263497403Sobrien 263597403Sobrien size_t 263697403Sobrien _M_transform(_CharT*, const _CharT*, size_t) const; 263797403Sobrien 263897403Sobrien protected: 2639132720Skan /// Destructor. 264097403Sobrien virtual 2641132720Skan ~collate() 2642107606Sobrien { _S_destroy_c_locale(_M_c_locale_collate); } 264397403Sobrien 2644132720Skan /** 2645132720Skan * @brief Compare two strings. 2646132720Skan * 2647132720Skan * This function is a hook for derived classes to change the value 2648132720Skan * returned. @see compare(). 2649132720Skan * 2650132720Skan * @param lo1 Start of string 1. 2651132720Skan * @param hi1 End of string 1. 2652132720Skan * @param lo2 Start of string 2. 2653132720Skan * @param hi2 End of string 2. 2654132720Skan * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 2655132720Skan */ 2656132720Skan virtual int 265797403Sobrien do_compare(const _CharT* __lo1, const _CharT* __hi1, 265897403Sobrien const _CharT* __lo2, const _CharT* __hi2) const; 265997403Sobrien 2660132720Skan /** 2661132720Skan * @brief Transform string to comparable form. 2662132720Skan * 2663132720Skan * This function is a hook for derived classes to change the value 2664132720Skan * returned. 2665132720Skan * 2666132720Skan * @param lo1 Start of string 1. 2667132720Skan * @param hi1 End of string 1. 2668132720Skan * @param lo2 Start of string 2. 2669132720Skan * @param hi2 End of string 2. 2670132720Skan * @return 1 if string1 > string2, -1 if string1 < string2, else 0. 2671132720Skan */ 2672132720Skan virtual string_type 267397403Sobrien do_transform(const _CharT* __lo, const _CharT* __hi) const; 267497403Sobrien 2675132720Skan /** 2676132720Skan * @brief Return hash of a string. 2677132720Skan * 2678132720Skan * This function computes and returns a hash on the input string. This 2679132720Skan * function is a hook for derived classes to change the value returned. 2680132720Skan * 2681132720Skan * @param lo Start of string. 2682132720Skan * @param hi End of string. 2683132720Skan * @return Hash value. 2684132720Skan */ 2685132720Skan virtual long 268697403Sobrien do_hash(const _CharT* __lo, const _CharT* __hi) const; 268797403Sobrien }; 268897403Sobrien 268997403Sobrien template<typename _CharT> 269097403Sobrien locale::id collate<_CharT>::id; 269197403Sobrien 269297403Sobrien // Specializations. 269397403Sobrien template<> 2694132720Skan int 269597403Sobrien collate<char>::_M_compare(const char*, const char*) const; 269697403Sobrien 269797403Sobrien template<> 269897403Sobrien size_t 269997403Sobrien collate<char>::_M_transform(char*, const char*, size_t) const; 270097403Sobrien 2701132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 270297403Sobrien template<> 2703132720Skan int 270497403Sobrien collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const; 270597403Sobrien 270697403Sobrien template<> 270797403Sobrien size_t 270897403Sobrien collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const; 270997403Sobrien#endif 271097403Sobrien 2711169691Skan /// @brief class collate_byname [22.2.4.2]. 271297403Sobrien template<typename _CharT> 271397403Sobrien class collate_byname : public collate<_CharT> 271497403Sobrien { 271597403Sobrien public: 2716132720Skan //@{ 2717132720Skan /// Public typedefs 271897403Sobrien typedef _CharT char_type; 271997403Sobrien typedef basic_string<_CharT> string_type; 2720132720Skan //@} 272197403Sobrien 2722132720Skan explicit 272397403Sobrien collate_byname(const char* __s, size_t __refs = 0) 2724132720Skan : collate<_CharT>(__refs) 2725132720Skan { 2726132720Skan if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 2727132720Skan { 2728132720Skan this->_S_destroy_c_locale(this->_M_c_locale_collate); 2729132720Skan this->_S_create_c_locale(this->_M_c_locale_collate, __s); 2730132720Skan } 273197403Sobrien } 273297403Sobrien 273397403Sobrien protected: 2734132720Skan virtual 273597403Sobrien ~collate_byname() { } 273697403Sobrien }; 273797403Sobrien 273897403Sobrien 2739132720Skan /** 2740132720Skan * @brief Time format ordering data. 2741132720Skan * 2742132720Skan * This class provides an enum representing different orderings of day, 2743132720Skan * month, and year. 2744132720Skan */ 274597403Sobrien class time_base 274697403Sobrien { 274797403Sobrien public: 274897403Sobrien enum dateorder { no_order, dmy, mdy, ymd, ydm }; 274997403Sobrien }; 275097403Sobrien 275197403Sobrien template<typename _CharT> 2752132720Skan struct __timepunct_cache : public locale::facet 275397403Sobrien { 275497403Sobrien // List of all known timezones, with GMT first. 2755132720Skan static const _CharT* _S_timezones[14]; 275697403Sobrien 2757132720Skan const _CharT* _M_date_format; 2758132720Skan const _CharT* _M_date_era_format; 2759132720Skan const _CharT* _M_time_format; 2760132720Skan const _CharT* _M_time_era_format; 276197403Sobrien const _CharT* _M_date_time_format; 276297403Sobrien const _CharT* _M_date_time_era_format; 2763132720Skan const _CharT* _M_am; 2764132720Skan const _CharT* _M_pm; 276597403Sobrien const _CharT* _M_am_pm_format; 276697403Sobrien 276797403Sobrien // Day names, starting with "C"'s Sunday. 2768132720Skan const _CharT* _M_day1; 2769132720Skan const _CharT* _M_day2; 2770132720Skan const _CharT* _M_day3; 2771132720Skan const _CharT* _M_day4; 2772132720Skan const _CharT* _M_day5; 2773132720Skan const _CharT* _M_day6; 2774132720Skan const _CharT* _M_day7; 277597403Sobrien 277697403Sobrien // Abbreviated day names, starting with "C"'s Sun. 2777132720Skan const _CharT* _M_aday1; 2778132720Skan const _CharT* _M_aday2; 2779132720Skan const _CharT* _M_aday3; 2780132720Skan const _CharT* _M_aday4; 2781132720Skan const _CharT* _M_aday5; 2782132720Skan const _CharT* _M_aday6; 2783132720Skan const _CharT* _M_aday7; 278497403Sobrien 278597403Sobrien // Month names, starting with "C"'s January. 2786132720Skan const _CharT* _M_month01; 2787132720Skan const _CharT* _M_month02; 2788132720Skan const _CharT* _M_month03; 2789132720Skan const _CharT* _M_month04; 2790132720Skan const _CharT* _M_month05; 2791132720Skan const _CharT* _M_month06; 2792132720Skan const _CharT* _M_month07; 2793132720Skan const _CharT* _M_month08; 2794132720Skan const _CharT* _M_month09; 2795132720Skan const _CharT* _M_month10; 2796132720Skan const _CharT* _M_month11; 2797132720Skan const _CharT* _M_month12; 279897403Sobrien 279997403Sobrien // Abbreviated month names, starting with "C"'s Jan. 2800132720Skan const _CharT* _M_amonth01; 2801132720Skan const _CharT* _M_amonth02; 2802132720Skan const _CharT* _M_amonth03; 2803132720Skan const _CharT* _M_amonth04; 2804132720Skan const _CharT* _M_amonth05; 2805132720Skan const _CharT* _M_amonth06; 2806132720Skan const _CharT* _M_amonth07; 2807132720Skan const _CharT* _M_amonth08; 2808132720Skan const _CharT* _M_amonth09; 2809132720Skan const _CharT* _M_amonth10; 2810132720Skan const _CharT* _M_amonth11; 2811132720Skan const _CharT* _M_amonth12; 281297403Sobrien 2813132720Skan bool _M_allocated; 2814132720Skan 2815132720Skan __timepunct_cache(size_t __refs = 0) : facet(__refs), 2816132720Skan _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), 2817132720Skan _M_time_era_format(NULL), _M_date_time_format(NULL), 2818132720Skan _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), 2819132720Skan _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), 2820132720Skan _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), 2821132720Skan _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), 2822132720Skan _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), 2823132720Skan _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), 2824132720Skan _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), 2825132720Skan _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), 2826132720Skan _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), 2827132720Skan _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), 2828132720Skan _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), 2829132720Skan _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) 2830132720Skan { } 2831132720Skan 2832132720Skan ~__timepunct_cache(); 2833132720Skan 2834132720Skan void 2835132720Skan _M_cache(const locale& __loc); 2836132720Skan 2837132720Skan private: 2838132720Skan __timepunct_cache& 2839132720Skan operator=(const __timepunct_cache&); 2840132720Skan 2841132720Skan explicit 2842132720Skan __timepunct_cache(const __timepunct_cache&); 2843132720Skan }; 2844132720Skan 2845132720Skan template<typename _CharT> 2846132720Skan __timepunct_cache<_CharT>::~__timepunct_cache() 2847132720Skan { 2848132720Skan if (_M_allocated) 2849132720Skan { 2850132720Skan // Unused. 2851132720Skan } 2852132720Skan } 2853132720Skan 2854132720Skan // Specializations. 2855132720Skan template<> 2856132720Skan const char* 2857132720Skan __timepunct_cache<char>::_S_timezones[14]; 2858132720Skan 2859132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 2860132720Skan template<> 2861132720Skan const wchar_t* 2862132720Skan __timepunct_cache<wchar_t>::_S_timezones[14]; 2863132720Skan#endif 2864132720Skan 2865132720Skan // Generic. 2866132720Skan template<typename _CharT> 2867132720Skan const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; 2868132720Skan 2869132720Skan template<typename _CharT> 2870132720Skan class __timepunct : public locale::facet 2871132720Skan { 287297403Sobrien public: 2873132720Skan // Types: 2874132720Skan typedef _CharT __char_type; 2875132720Skan typedef basic_string<_CharT> __string_type; 2876132720Skan typedef __timepunct_cache<_CharT> __cache_type; 2877132720Skan 2878132720Skan protected: 2879132720Skan __cache_type* _M_data; 2880132720Skan __c_locale _M_c_locale_timepunct; 2881132720Skan const char* _M_name_timepunct; 2882132720Skan 2883132720Skan public: 2884132720Skan /// Numpunct facet id. 2885132720Skan static locale::id id; 2886132720Skan 2887132720Skan explicit 2888110614Skan __timepunct(size_t __refs = 0); 288997403Sobrien 2890132720Skan explicit 2891132720Skan __timepunct(__cache_type* __cache, size_t __refs = 0); 2892132720Skan 2893132720Skan /** 2894132720Skan * @brief Internal constructor. Not for general use. 2895132720Skan * 2896132720Skan * This is a constructor for use by the library itself to set up new 2897132720Skan * locales. 2898132720Skan * 2899132720Skan * @param cloc The "C" locale. 2900132720Skan * @param s The name of a locale. 2901132720Skan * @param refs Passed to the base facet class. 2902132720Skan */ 2903132720Skan explicit 2904110614Skan __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); 290597403Sobrien 2906169691Skan // FIXME: for error checking purposes _M_put should return the return 2907169691Skan // value of strftime/wcsftime. 290897403Sobrien void 2909132720Skan _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, 291097403Sobrien const tm* __tm) const; 291197403Sobrien 291297403Sobrien void 291397403Sobrien _M_date_formats(const _CharT** __date) const 291497403Sobrien { 291597403Sobrien // Always have default first. 2916132720Skan __date[0] = _M_data->_M_date_format; 2917132720Skan __date[1] = _M_data->_M_date_era_format; 291897403Sobrien } 291997403Sobrien 292097403Sobrien void 292197403Sobrien _M_time_formats(const _CharT** __time) const 292297403Sobrien { 292397403Sobrien // Always have default first. 2924132720Skan __time[0] = _M_data->_M_time_format; 2925132720Skan __time[1] = _M_data->_M_time_era_format; 292697403Sobrien } 292797403Sobrien 292897403Sobrien void 292997403Sobrien _M_date_time_formats(const _CharT** __dt) const 293097403Sobrien { 293197403Sobrien // Always have default first. 2932132720Skan __dt[0] = _M_data->_M_date_time_format; 2933132720Skan __dt[1] = _M_data->_M_date_time_era_format; 293497403Sobrien } 293597403Sobrien 293697403Sobrien void 2937132720Skan _M_am_pm_format(const _CharT* __ampm) const 2938132720Skan { __ampm = _M_data->_M_am_pm_format; } 2939132720Skan 2940132720Skan void 2941132720Skan _M_am_pm(const _CharT** __ampm) const 2942132720Skan { 2943132720Skan __ampm[0] = _M_data->_M_am; 2944132720Skan __ampm[1] = _M_data->_M_pm; 2945132720Skan } 2946132720Skan 2947132720Skan void 294897403Sobrien _M_days(const _CharT** __days) const 2949132720Skan { 2950132720Skan __days[0] = _M_data->_M_day1; 2951132720Skan __days[1] = _M_data->_M_day2; 2952132720Skan __days[2] = _M_data->_M_day3; 2953132720Skan __days[3] = _M_data->_M_day4; 2954132720Skan __days[4] = _M_data->_M_day5; 2955132720Skan __days[5] = _M_data->_M_day6; 2956132720Skan __days[6] = _M_data->_M_day7; 295797403Sobrien } 295897403Sobrien 295997403Sobrien void 296097403Sobrien _M_days_abbreviated(const _CharT** __days) const 2961132720Skan { 2962132720Skan __days[0] = _M_data->_M_aday1; 2963132720Skan __days[1] = _M_data->_M_aday2; 2964132720Skan __days[2] = _M_data->_M_aday3; 2965132720Skan __days[3] = _M_data->_M_aday4; 2966132720Skan __days[4] = _M_data->_M_aday5; 2967132720Skan __days[5] = _M_data->_M_aday6; 2968132720Skan __days[6] = _M_data->_M_aday7; 296997403Sobrien } 297097403Sobrien 297197403Sobrien void 297297403Sobrien _M_months(const _CharT** __months) const 2973132720Skan { 2974132720Skan __months[0] = _M_data->_M_month01; 2975132720Skan __months[1] = _M_data->_M_month02; 2976132720Skan __months[2] = _M_data->_M_month03; 2977132720Skan __months[3] = _M_data->_M_month04; 2978132720Skan __months[4] = _M_data->_M_month05; 2979132720Skan __months[5] = _M_data->_M_month06; 2980132720Skan __months[6] = _M_data->_M_month07; 2981132720Skan __months[7] = _M_data->_M_month08; 2982132720Skan __months[8] = _M_data->_M_month09; 2983132720Skan __months[9] = _M_data->_M_month10; 2984132720Skan __months[10] = _M_data->_M_month11; 2985132720Skan __months[11] = _M_data->_M_month12; 298697403Sobrien } 298797403Sobrien 298897403Sobrien void 298997403Sobrien _M_months_abbreviated(const _CharT** __months) const 2990132720Skan { 2991132720Skan __months[0] = _M_data->_M_amonth01; 2992132720Skan __months[1] = _M_data->_M_amonth02; 2993132720Skan __months[2] = _M_data->_M_amonth03; 2994132720Skan __months[3] = _M_data->_M_amonth04; 2995132720Skan __months[4] = _M_data->_M_amonth05; 2996132720Skan __months[5] = _M_data->_M_amonth06; 2997132720Skan __months[6] = _M_data->_M_amonth07; 2998132720Skan __months[7] = _M_data->_M_amonth08; 2999132720Skan __months[8] = _M_data->_M_amonth09; 3000132720Skan __months[9] = _M_data->_M_amonth10; 3001132720Skan __months[10] = _M_data->_M_amonth11; 3002132720Skan __months[11] = _M_data->_M_amonth12; 300397403Sobrien } 300497403Sobrien 300597403Sobrien protected: 3006132720Skan virtual 3007110614Skan ~__timepunct(); 300897403Sobrien 300997403Sobrien // For use at construction time only. 3010132720Skan void 3011107606Sobrien _M_initialize_timepunct(__c_locale __cloc = NULL); 301297403Sobrien }; 301397403Sobrien 301497403Sobrien template<typename _CharT> 301597403Sobrien locale::id __timepunct<_CharT>::id; 301697403Sobrien 301797403Sobrien // Specializations. 3018132720Skan template<> 301997403Sobrien void 302097403Sobrien __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc); 302197403Sobrien 302297403Sobrien template<> 302397403Sobrien void 302497403Sobrien __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const; 302597403Sobrien 3026132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 3027132720Skan template<> 302897403Sobrien void 302997403Sobrien __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc); 303097403Sobrien 303197403Sobrien template<> 303297403Sobrien void 3033132720Skan __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*, 303497403Sobrien const tm*) const; 303597403Sobrien#endif 303697403Sobrien 3037169691Skan_GLIBCXX_END_NAMESPACE 3038169691Skan 3039110614Skan // Include host and configuration specific timepunct functions. 3040110614Skan #include <bits/time_members.h> 304197403Sobrien 3042169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 3043169691Skan 3044132720Skan /** 3045132720Skan * @brief Facet for parsing dates and times. 3046132720Skan * 3047132720Skan * This facet encapsulates the code to parse and return a date or 3048132720Skan * time from a string. It is used by the istream numeric 3049132720Skan * extraction operators. 3050132720Skan * 3051132720Skan * The time_get template uses protected virtual functions to provide the 3052132720Skan * actual results. The public accessors forward the call to the virtual 3053132720Skan * functions. These virtual functions are hooks for developers to 3054132720Skan * implement the behavior they require from the time_get facet. 3055132720Skan */ 305697403Sobrien template<typename _CharT, typename _InIter> 305797403Sobrien class time_get : public locale::facet, public time_base 305897403Sobrien { 305997403Sobrien public: 306097403Sobrien // Types: 3061132720Skan //@{ 3062132720Skan /// Public typedefs 3063132720Skan typedef _CharT char_type; 3064132720Skan typedef _InIter iter_type; 3065132720Skan //@} 3066132720Skan typedef basic_string<_CharT> __string_type; 306797403Sobrien 3068132720Skan /// Numpunct facet id. 3069132720Skan static locale::id id; 307097403Sobrien 3071132720Skan /** 3072132720Skan * @brief Constructor performs initialization. 3073132720Skan * 3074132720Skan * This is the constructor provided by the standard. 3075132720Skan * 3076132720Skan * @param refs Passed to the base facet class. 3077132720Skan */ 3078132720Skan explicit 3079132720Skan time_get(size_t __refs = 0) 3080132720Skan : facet (__refs) { } 308197403Sobrien 3082132720Skan /** 3083132720Skan * @brief Return preferred order of month, day, and year. 3084132720Skan * 3085132720Skan * This function returns an enum from timebase::dateorder giving the 3086132720Skan * preferred ordering if the format "x" given to time_put::put() only 3087132720Skan * uses month, day, and year. If the format "x" for the associated 3088132720Skan * locale uses other fields, this function returns 3089132720Skan * timebase::dateorder::noorder. 3090132720Skan * 3091132720Skan * NOTE: The library always returns noorder at the moment. 3092132720Skan * 3093132720Skan * @return A member of timebase::dateorder. 3094132720Skan */ 3095132720Skan dateorder 309697403Sobrien date_order() const 309797403Sobrien { return this->do_date_order(); } 309897403Sobrien 3099132720Skan /** 3100132720Skan * @brief Parse input time string. 3101132720Skan * 3102132720Skan * This function parses a time according to the format "x" and puts the 3103132720Skan * results into a user-supplied struct tm. The result is returned by 3104132720Skan * calling time_get::do_get_time(). 3105132720Skan * 3106132720Skan * If there is a valid time string according to format "x", @a tm will 3107132720Skan * be filled in accordingly and the returned iterator will point to the 3108132720Skan * first character beyond the time string. If an error occurs before 3109132720Skan * the end, err |= ios_base::failbit. If parsing reads all the 3110132720Skan * characters, err |= ios_base::eofbit. 3111132720Skan * 3112132720Skan * @param beg Start of string to parse. 3113132720Skan * @param end End of string to parse. 3114132720Skan * @param io Source of the locale. 3115132720Skan * @param err Error flags to set. 3116132720Skan * @param tm Pointer to struct tm to fill in. 3117132720Skan * @return Iterator to first char beyond time string. 3118132720Skan */ 3119132720Skan iter_type 3120132720Skan get_time(iter_type __beg, iter_type __end, ios_base& __io, 312197403Sobrien ios_base::iostate& __err, tm* __tm) const 312297403Sobrien { return this->do_get_time(__beg, __end, __io, __err, __tm); } 312397403Sobrien 3124132720Skan /** 3125132720Skan * @brief Parse input date string. 3126132720Skan * 3127132720Skan * This function parses a date according to the format "X" and puts the 3128132720Skan * results into a user-supplied struct tm. The result is returned by 3129132720Skan * calling time_get::do_get_date(). 3130132720Skan * 3131132720Skan * If there is a valid date string according to format "X", @a tm will 3132132720Skan * be filled in accordingly and the returned iterator will point to the 3133132720Skan * first character beyond the date string. If an error occurs before 3134132720Skan * the end, err |= ios_base::failbit. If parsing reads all the 3135132720Skan * characters, err |= ios_base::eofbit. 3136132720Skan * 3137132720Skan * @param beg Start of string to parse. 3138132720Skan * @param end End of string to parse. 3139132720Skan * @param io Source of the locale. 3140132720Skan * @param err Error flags to set. 3141132720Skan * @param tm Pointer to struct tm to fill in. 3142132720Skan * @return Iterator to first char beyond date string. 3143132720Skan */ 3144132720Skan iter_type 314597403Sobrien get_date(iter_type __beg, iter_type __end, ios_base& __io, 314697403Sobrien ios_base::iostate& __err, tm* __tm) const 314797403Sobrien { return this->do_get_date(__beg, __end, __io, __err, __tm); } 314897403Sobrien 3149132720Skan /** 3150132720Skan * @brief Parse input weekday string. 3151132720Skan * 3152132720Skan * This function parses a weekday name and puts the results into a 3153132720Skan * user-supplied struct tm. The result is returned by calling 3154132720Skan * time_get::do_get_weekday(). 3155132720Skan * 3156132720Skan * Parsing starts by parsing an abbreviated weekday name. If a valid 3157132720Skan * abbreviation is followed by a character that would lead to the full 3158132720Skan * weekday name, parsing continues until the full name is found or an 3159132720Skan * error occurs. Otherwise parsing finishes at the end of the 3160132720Skan * abbreviated name. 3161132720Skan * 3162132720Skan * If an error occurs before the end, err |= ios_base::failbit. If 3163132720Skan * parsing reads all the characters, err |= ios_base::eofbit. 3164132720Skan * 3165132720Skan * @param beg Start of string to parse. 3166132720Skan * @param end End of string to parse. 3167132720Skan * @param io Source of the locale. 3168132720Skan * @param err Error flags to set. 3169132720Skan * @param tm Pointer to struct tm to fill in. 3170132720Skan * @return Iterator to first char beyond weekday name. 3171132720Skan */ 3172132720Skan iter_type 317397403Sobrien get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 317497403Sobrien ios_base::iostate& __err, tm* __tm) const 317597403Sobrien { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } 317697403Sobrien 3177132720Skan /** 3178132720Skan * @brief Parse input month string. 3179132720Skan * 3180132720Skan * This function parses a month name and puts the results into a 3181132720Skan * user-supplied struct tm. The result is returned by calling 3182132720Skan * time_get::do_get_monthname(). 3183132720Skan * 3184132720Skan * Parsing starts by parsing an abbreviated month name. If a valid 3185132720Skan * abbreviation is followed by a character that would lead to the full 3186132720Skan * month name, parsing continues until the full name is found or an 3187132720Skan * error occurs. Otherwise parsing finishes at the end of the 3188132720Skan * abbreviated name. 3189132720Skan * 3190132720Skan * If an error occurs before the end, err |= ios_base::failbit. If 3191132720Skan * parsing reads all the characters, err |= 3192132720Skan * ios_base::eofbit. 3193132720Skan * 3194132720Skan * @param beg Start of string to parse. 3195132720Skan * @param end End of string to parse. 3196132720Skan * @param io Source of the locale. 3197132720Skan * @param err Error flags to set. 3198132720Skan * @param tm Pointer to struct tm to fill in. 3199132720Skan * @return Iterator to first char beyond month name. 3200132720Skan */ 3201132720Skan iter_type 3202132720Skan get_monthname(iter_type __beg, iter_type __end, ios_base& __io, 320397403Sobrien ios_base::iostate& __err, tm* __tm) const 320497403Sobrien { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } 320597403Sobrien 3206132720Skan /** 3207132720Skan * @brief Parse input year string. 3208132720Skan * 3209132720Skan * This function reads up to 4 characters to parse a year string and 3210132720Skan * puts the results into a user-supplied struct tm. The result is 3211132720Skan * returned by calling time_get::do_get_year(). 3212132720Skan * 3213132720Skan * 4 consecutive digits are interpreted as a full year. If there are 3214132720Skan * exactly 2 consecutive digits, the library interprets this as the 3215132720Skan * number of years since 1900. 3216132720Skan * 3217132720Skan * If an error occurs before the end, err |= ios_base::failbit. If 3218132720Skan * parsing reads all the characters, err |= ios_base::eofbit. 3219132720Skan * 3220132720Skan * @param beg Start of string to parse. 3221132720Skan * @param end End of string to parse. 3222132720Skan * @param io Source of the locale. 3223132720Skan * @param err Error flags to set. 3224132720Skan * @param tm Pointer to struct tm to fill in. 3225132720Skan * @return Iterator to first char beyond year. 3226132720Skan */ 3227132720Skan iter_type 322897403Sobrien get_year(iter_type __beg, iter_type __end, ios_base& __io, 322997403Sobrien ios_base::iostate& __err, tm* __tm) const 323097403Sobrien { return this->do_get_year(__beg, __end, __io, __err, __tm); } 323197403Sobrien 323297403Sobrien protected: 3233132720Skan /// Destructor. 3234132720Skan virtual 323597403Sobrien ~time_get() { } 323697403Sobrien 3237132720Skan /** 3238132720Skan * @brief Return preferred order of month, day, and year. 3239132720Skan * 3240132720Skan * This function returns an enum from timebase::dateorder giving the 3241132720Skan * preferred ordering if the format "x" given to time_put::put() only 3242132720Skan * uses month, day, and year. This function is a hook for derived 3243132720Skan * classes to change the value returned. 3244132720Skan * 3245132720Skan * @return A member of timebase::dateorder. 3246132720Skan */ 3247132720Skan virtual dateorder 324897403Sobrien do_date_order() const; 324997403Sobrien 3250132720Skan /** 3251132720Skan * @brief Parse input time string. 3252132720Skan * 3253132720Skan * This function parses a time according to the format "x" and puts the 3254132720Skan * results into a user-supplied struct tm. This function is a hook for 3255132720Skan * derived classes to change the value returned. @see get_time() for 3256132720Skan * details. 3257132720Skan * 3258132720Skan * @param beg Start of string to parse. 3259132720Skan * @param end End of string to parse. 3260132720Skan * @param io Source of the locale. 3261132720Skan * @param err Error flags to set. 3262132720Skan * @param tm Pointer to struct tm to fill in. 3263132720Skan * @return Iterator to first char beyond time string. 3264132720Skan */ 3265132720Skan virtual iter_type 326697403Sobrien do_get_time(iter_type __beg, iter_type __end, ios_base& __io, 326797403Sobrien ios_base::iostate& __err, tm* __tm) const; 326897403Sobrien 3269132720Skan /** 3270132720Skan * @brief Parse input date string. 3271132720Skan * 3272132720Skan * This function parses a date according to the format "X" and puts the 3273132720Skan * results into a user-supplied struct tm. This function is a hook for 3274132720Skan * derived classes to change the value returned. @see get_date() for 3275132720Skan * details. 3276132720Skan * 3277132720Skan * @param beg Start of string to parse. 3278132720Skan * @param end End of string to parse. 3279132720Skan * @param io Source of the locale. 3280132720Skan * @param err Error flags to set. 3281132720Skan * @param tm Pointer to struct tm to fill in. 3282132720Skan * @return Iterator to first char beyond date string. 3283132720Skan */ 3284132720Skan virtual iter_type 328597403Sobrien do_get_date(iter_type __beg, iter_type __end, ios_base& __io, 328697403Sobrien ios_base::iostate& __err, tm* __tm) const; 328797403Sobrien 3288132720Skan /** 3289132720Skan * @brief Parse input weekday string. 3290132720Skan * 3291132720Skan * This function parses a weekday name and puts the results into a 3292132720Skan * user-supplied struct tm. This function is a hook for derived 3293132720Skan * classes to change the value returned. @see get_weekday() for 3294132720Skan * details. 3295132720Skan * 3296132720Skan * @param beg Start of string to parse. 3297132720Skan * @param end End of string to parse. 3298132720Skan * @param io Source of the locale. 3299132720Skan * @param err Error flags to set. 3300132720Skan * @param tm Pointer to struct tm to fill in. 3301132720Skan * @return Iterator to first char beyond weekday name. 3302132720Skan */ 3303132720Skan virtual iter_type 330497403Sobrien do_get_weekday(iter_type __beg, iter_type __end, ios_base&, 330597403Sobrien ios_base::iostate& __err, tm* __tm) const; 330697403Sobrien 3307132720Skan /** 3308132720Skan * @brief Parse input month string. 3309132720Skan * 3310132720Skan * This function parses a month name and puts the results into a 3311132720Skan * user-supplied struct tm. This function is a hook for derived 3312132720Skan * classes to change the value returned. @see get_monthname() for 3313132720Skan * details. 3314132720Skan * 3315132720Skan * @param beg Start of string to parse. 3316132720Skan * @param end End of string to parse. 3317132720Skan * @param io Source of the locale. 3318132720Skan * @param err Error flags to set. 3319132720Skan * @param tm Pointer to struct tm to fill in. 3320132720Skan * @return Iterator to first char beyond month name. 3321132720Skan */ 3322132720Skan virtual iter_type 3323132720Skan do_get_monthname(iter_type __beg, iter_type __end, ios_base&, 332497403Sobrien ios_base::iostate& __err, tm* __tm) const; 332597403Sobrien 3326132720Skan /** 3327132720Skan * @brief Parse input year string. 3328132720Skan * 3329132720Skan * This function reads up to 4 characters to parse a year string and 3330132720Skan * puts the results into a user-supplied struct tm. This function is a 3331132720Skan * hook for derived classes to change the value returned. @see 3332132720Skan * get_year() for details. 3333132720Skan * 3334132720Skan * @param beg Start of string to parse. 3335132720Skan * @param end End of string to parse. 3336132720Skan * @param io Source of the locale. 3337132720Skan * @param err Error flags to set. 3338132720Skan * @param tm Pointer to struct tm to fill in. 3339132720Skan * @return Iterator to first char beyond year. 3340132720Skan */ 3341132720Skan virtual iter_type 334297403Sobrien do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 334397403Sobrien ios_base::iostate& __err, tm* __tm) const; 334497403Sobrien 334597403Sobrien // Extract numeric component of length __len. 3346132720Skan iter_type 3347132720Skan _M_extract_num(iter_type __beg, iter_type __end, int& __member, 334897403Sobrien int __min, int __max, size_t __len, 3349132720Skan ios_base& __io, ios_base::iostate& __err) const; 3350132720Skan 335197403Sobrien // Extract day or month name, or any unique array of string 335297403Sobrien // literals in a const _CharT* array. 3353132720Skan iter_type 3354132720Skan _M_extract_name(iter_type __beg, iter_type __end, int& __member, 3355132720Skan const _CharT** __names, size_t __indexlen, 3356132720Skan ios_base& __io, ios_base::iostate& __err) const; 335797403Sobrien 335897403Sobrien // Extract on a component-by-component basis, via __format argument. 3359132720Skan iter_type 3360132720Skan _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 3361132720Skan ios_base::iostate& __err, tm* __tm, 336297403Sobrien const _CharT* __format) const; 336397403Sobrien }; 336497403Sobrien 336597403Sobrien template<typename _CharT, typename _InIter> 336697403Sobrien locale::id time_get<_CharT, _InIter>::id; 336797403Sobrien 3368169691Skan /// @brief class time_get_byname [22.2.5.2]. 336997403Sobrien template<typename _CharT, typename _InIter> 337097403Sobrien class time_get_byname : public time_get<_CharT, _InIter> 337197403Sobrien { 337297403Sobrien public: 337397403Sobrien // Types: 3374132720Skan typedef _CharT char_type; 3375132720Skan typedef _InIter iter_type; 337697403Sobrien 3377132720Skan explicit 3378132720Skan time_get_byname(const char*, size_t __refs = 0) 337997403Sobrien : time_get<_CharT, _InIter>(__refs) { } 338097403Sobrien 338197403Sobrien protected: 3382132720Skan virtual 338397403Sobrien ~time_get_byname() { } 338497403Sobrien }; 338597403Sobrien 3386132720Skan /** 3387132720Skan * @brief Facet for outputting dates and times. 3388132720Skan * 3389132720Skan * This facet encapsulates the code to format and output dates and times 3390132720Skan * according to formats used by strftime(). 3391132720Skan * 3392132720Skan * The time_put template uses protected virtual functions to provide the 3393132720Skan * actual results. The public accessors forward the call to the virtual 3394132720Skan * functions. These virtual functions are hooks for developers to 3395132720Skan * implement the behavior they require from the time_put facet. 3396132720Skan */ 339797403Sobrien template<typename _CharT, typename _OutIter> 3398132720Skan class time_put : public locale::facet 339997403Sobrien { 340097403Sobrien public: 340197403Sobrien // Types: 3402132720Skan //@{ 3403132720Skan /// Public typedefs 3404132720Skan typedef _CharT char_type; 3405132720Skan typedef _OutIter iter_type; 3406132720Skan //@} 340797403Sobrien 3408132720Skan /// Numpunct facet id. 3409132720Skan static locale::id id; 341097403Sobrien 3411132720Skan /** 3412132720Skan * @brief Constructor performs initialization. 3413132720Skan * 3414132720Skan * This is the constructor provided by the standard. 3415132720Skan * 3416132720Skan * @param refs Passed to the base facet class. 3417132720Skan */ 3418132720Skan explicit 3419132720Skan time_put(size_t __refs = 0) 3420132720Skan : facet(__refs) { } 342197403Sobrien 3422132720Skan /** 3423132720Skan * @brief Format and output a time or date. 3424132720Skan * 3425132720Skan * This function formats the data in struct tm according to the 3426132720Skan * provided format string. The format string is interpreted as by 3427132720Skan * strftime(). 3428132720Skan * 3429132720Skan * @param s The stream to write to. 3430132720Skan * @param io Source of locale. 3431132720Skan * @param fill char_type to use for padding. 3432132720Skan * @param tm Struct tm with date and time info to format. 3433132720Skan * @param beg Start of format string. 3434132720Skan * @param end End of format string. 3435132720Skan * @return Iterator after writing. 3436132720Skan */ 3437132720Skan iter_type 3438132720Skan put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 343997403Sobrien const _CharT* __beg, const _CharT* __end) const; 344097403Sobrien 3441132720Skan /** 3442132720Skan * @brief Format and output a time or date. 3443132720Skan * 3444132720Skan * This function formats the data in struct tm according to the 3445132720Skan * provided format char and optional modifier. The format and modifier 3446132720Skan * are interpreted as by strftime(). It does so by returning 3447132720Skan * time_put::do_put(). 3448132720Skan * 3449132720Skan * @param s The stream to write to. 3450132720Skan * @param io Source of locale. 3451132720Skan * @param fill char_type to use for padding. 3452132720Skan * @param tm Struct tm with date and time info to format. 3453132720Skan * @param format Format char. 3454132720Skan * @param mod Optional modifier char. 3455132720Skan * @return Iterator after writing. 3456132720Skan */ 3457132720Skan iter_type 345897403Sobrien put(iter_type __s, ios_base& __io, char_type __fill, 345997403Sobrien const tm* __tm, char __format, char __mod = 0) const 346097403Sobrien { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } 346197403Sobrien 346297403Sobrien protected: 3463132720Skan /// Destructor. 3464132720Skan virtual 346597403Sobrien ~time_put() 346697403Sobrien { } 346797403Sobrien 3468132720Skan /** 3469132720Skan * @brief Format and output a time or date. 3470132720Skan * 3471132720Skan * This function formats the data in struct tm according to the 3472132720Skan * provided format char and optional modifier. This function is a hook 3473132720Skan * for derived classes to change the value returned. @see put() for 3474132720Skan * more details. 3475132720Skan * 3476132720Skan * @param s The stream to write to. 3477132720Skan * @param io Source of locale. 3478132720Skan * @param fill char_type to use for padding. 3479132720Skan * @param tm Struct tm with date and time info to format. 3480132720Skan * @param format Format char. 3481132720Skan * @param mod Optional modifier char. 3482132720Skan * @return Iterator after writing. 3483132720Skan */ 3484132720Skan virtual iter_type 3485132720Skan do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 348697403Sobrien char __format, char __mod) const; 348797403Sobrien }; 348897403Sobrien 348997403Sobrien template<typename _CharT, typename _OutIter> 349097403Sobrien locale::id time_put<_CharT, _OutIter>::id; 349197403Sobrien 3492169691Skan /// @brief class time_put_byname [22.2.5.4]. 349397403Sobrien template<typename _CharT, typename _OutIter> 349497403Sobrien class time_put_byname : public time_put<_CharT, _OutIter> 349597403Sobrien { 349697403Sobrien public: 349797403Sobrien // Types: 3498132720Skan typedef _CharT char_type; 3499132720Skan typedef _OutIter iter_type; 350097403Sobrien 3501132720Skan explicit 3502132720Skan time_put_byname(const char*, size_t __refs = 0) 3503132720Skan : time_put<_CharT, _OutIter>(__refs) 350497403Sobrien { }; 350597403Sobrien 350697403Sobrien protected: 3507132720Skan virtual 350897403Sobrien ~time_put_byname() { } 350997403Sobrien }; 351097403Sobrien 351197403Sobrien 3512132720Skan /** 3513132720Skan * @brief Money format ordering data. 3514132720Skan * 3515132720Skan * This class contains an ordered array of 4 fields to represent the 3516132720Skan * pattern for formatting a money amount. Each field may contain one entry 3517132720Skan * from the part enum. symbol, sign, and value must be present and the 3518132720Skan * remaining field must contain either none or space. @see 3519132720Skan * moneypunct::pos_format() and moneypunct::neg_format() for details of how 3520132720Skan * these fields are interpreted. 3521132720Skan */ 352297403Sobrien class money_base 352397403Sobrien { 352497403Sobrien public: 352597403Sobrien enum part { none, space, symbol, sign, value }; 352697403Sobrien struct pattern { char field[4]; }; 352797403Sobrien 352897403Sobrien static const pattern _S_default_pattern; 352997403Sobrien 3530132720Skan enum 3531132720Skan { 3532132720Skan _S_minus, 3533132720Skan _S_zero, 3534132720Skan _S_end = 11 3535132720Skan }; 3536132720Skan 3537132720Skan // String literal of acceptable (narrow) input/output, for 3538132720Skan // money_get/money_put. "-0123456789" 3539132720Skan static const char* _S_atoms; 3540132720Skan 354197403Sobrien // Construct and return valid pattern consisting of some combination of: 354297403Sobrien // space none symbol sign value 3543132720Skan static pattern 354497403Sobrien _S_construct_pattern(char __precedes, char __space, char __posn); 354597403Sobrien }; 354697403Sobrien 354797403Sobrien template<typename _CharT, bool _Intl> 3548132720Skan struct __moneypunct_cache : public locale::facet 3549132720Skan { 3550132720Skan const char* _M_grouping; 3551132720Skan size_t _M_grouping_size; 3552132720Skan bool _M_use_grouping; 3553132720Skan _CharT _M_decimal_point; 3554132720Skan _CharT _M_thousands_sep; 3555132720Skan const _CharT* _M_curr_symbol; 3556132720Skan size_t _M_curr_symbol_size; 3557132720Skan const _CharT* _M_positive_sign; 3558132720Skan size_t _M_positive_sign_size; 3559132720Skan const _CharT* _M_negative_sign; 3560132720Skan size_t _M_negative_sign_size; 3561132720Skan int _M_frac_digits; 3562132720Skan money_base::pattern _M_pos_format; 3563132720Skan money_base::pattern _M_neg_format; 3564132720Skan 3565132720Skan // A list of valid numeric literals for input and output: in the standard 3566132720Skan // "C" locale, this is "-0123456789". This array contains the chars after 3567132720Skan // having been passed through the current locale's ctype<_CharT>.widen(). 3568132720Skan _CharT _M_atoms[money_base::_S_end]; 3569132720Skan 3570132720Skan bool _M_allocated; 3571132720Skan 3572132720Skan __moneypunct_cache(size_t __refs = 0) : facet(__refs), 3573132720Skan _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), 3574132720Skan _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), 3575132720Skan _M_curr_symbol(NULL), _M_curr_symbol_size(0), 3576132720Skan _M_positive_sign(NULL), _M_positive_sign_size(0), 3577132720Skan _M_negative_sign(NULL), _M_negative_sign_size(0), 3578132720Skan _M_frac_digits(0), 3579132720Skan _M_pos_format(money_base::pattern()), 3580132720Skan _M_neg_format(money_base::pattern()), _M_allocated(false) 3581132720Skan { } 3582132720Skan 3583132720Skan ~__moneypunct_cache(); 3584132720Skan 3585132720Skan void 3586132720Skan _M_cache(const locale& __loc); 3587132720Skan 3588132720Skan private: 3589132720Skan __moneypunct_cache& 3590132720Skan operator=(const __moneypunct_cache&); 3591132720Skan 3592132720Skan explicit 3593132720Skan __moneypunct_cache(const __moneypunct_cache&); 3594132720Skan }; 3595132720Skan 3596132720Skan template<typename _CharT, bool _Intl> 3597132720Skan __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() 3598132720Skan { 3599132720Skan if (_M_allocated) 3600132720Skan { 3601132720Skan delete [] _M_grouping; 3602132720Skan delete [] _M_curr_symbol; 3603132720Skan delete [] _M_positive_sign; 3604132720Skan delete [] _M_negative_sign; 3605132720Skan } 3606132720Skan } 3607132720Skan 3608132720Skan /** 3609132720Skan * @brief Facet for formatting data for money amounts. 3610132720Skan * 3611132720Skan * This facet encapsulates the punctuation, grouping and other formatting 3612132720Skan * features of money amount string representations. 3613132720Skan */ 3614132720Skan template<typename _CharT, bool _Intl> 361597403Sobrien class moneypunct : public locale::facet, public money_base 361697403Sobrien { 361797403Sobrien public: 361897403Sobrien // Types: 3619132720Skan //@{ 3620132720Skan /// Public typedefs 3621132720Skan typedef _CharT char_type; 3622132720Skan typedef basic_string<_CharT> string_type; 3623132720Skan //@} 3624132720Skan typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 362597403Sobrien 362697403Sobrien private: 3627132720Skan __cache_type* _M_data; 362897403Sobrien 362997403Sobrien public: 3630132720Skan /// This value is provided by the standard, but no reason for its 3631132720Skan /// existence. 3632132720Skan static const bool intl = _Intl; 3633132720Skan /// Numpunct facet id. 3634132720Skan static locale::id id; 3635132720Skan 3636132720Skan /** 3637132720Skan * @brief Constructor performs initialization. 3638132720Skan * 3639132720Skan * This is the constructor provided by the standard. 3640132720Skan * 3641132720Skan * @param refs Passed to the base facet class. 3642132720Skan */ 3643132720Skan explicit 3644132720Skan moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) 364597403Sobrien { _M_initialize_moneypunct(); } 364697403Sobrien 3647132720Skan /** 3648132720Skan * @brief Constructor performs initialization. 3649132720Skan * 3650132720Skan * This is an internal constructor. 3651132720Skan * 3652132720Skan * @param cache Cache for optimization. 3653132720Skan * @param refs Passed to the base facet class. 3654132720Skan */ 3655132720Skan explicit 3656132720Skan moneypunct(__cache_type* __cache, size_t __refs = 0) 3657132720Skan : facet(__refs), _M_data(__cache) 3658132720Skan { _M_initialize_moneypunct(); } 3659132720Skan 3660132720Skan /** 3661132720Skan * @brief Internal constructor. Not for general use. 3662132720Skan * 3663132720Skan * This is a constructor for use by the library itself to set up new 3664132720Skan * locales. 3665132720Skan * 3666132720Skan * @param cloc The "C" locale. 3667132720Skan * @param s The name of a locale. 3668132720Skan * @param refs Passed to the base facet class. 3669132720Skan */ 3670132720Skan explicit 3671132720Skan moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) 3672132720Skan : facet(__refs), _M_data(NULL) 3673102782Skan { _M_initialize_moneypunct(__cloc, __s); } 367497403Sobrien 3675132720Skan /** 3676132720Skan * @brief Return decimal point character. 3677132720Skan * 3678132720Skan * This function returns a char_type to use as a decimal point. It 3679132720Skan * does so by returning returning 3680132720Skan * moneypunct<char_type>::do_decimal_point(). 3681132720Skan * 3682132720Skan * @return @a char_type representing a decimal point. 3683132720Skan */ 368497403Sobrien char_type 368597403Sobrien decimal_point() const 368697403Sobrien { return this->do_decimal_point(); } 3687132720Skan 3688132720Skan /** 3689132720Skan * @brief Return thousands separator character. 3690132720Skan * 3691132720Skan * This function returns a char_type to use as a thousands 3692132720Skan * separator. It does so by returning returning 3693132720Skan * moneypunct<char_type>::do_thousands_sep(). 3694132720Skan * 3695132720Skan * @return char_type representing a thousands separator. 3696132720Skan */ 369797403Sobrien char_type 369897403Sobrien thousands_sep() const 369997403Sobrien { return this->do_thousands_sep(); } 3700132720Skan 3701132720Skan /** 3702132720Skan * @brief Return grouping specification. 3703132720Skan * 3704132720Skan * This function returns a string representing groupings for the 3705132720Skan * integer part of an amount. Groupings indicate where thousands 3706132720Skan * separators should be inserted. 3707132720Skan * 3708132720Skan * Each char in the return string is interpret as an integer rather 3709132720Skan * than a character. These numbers represent the number of digits in a 3710132720Skan * group. The first char in the string represents the number of digits 3711132720Skan * in the least significant group. If a char is negative, it indicates 3712132720Skan * an unlimited number of digits for the group. If more chars from the 3713132720Skan * string are required to group a number, the last char is used 3714132720Skan * repeatedly. 3715132720Skan * 3716132720Skan * For example, if the grouping() returns "\003\002" and is applied to 3717132720Skan * the number 123456789, this corresponds to 12,34,56,789. Note that 3718132720Skan * if the string was "32", this would put more than 50 digits into the 3719132720Skan * least significant group if the character set is ASCII. 3720132720Skan * 3721132720Skan * The string is returned by calling 3722132720Skan * moneypunct<char_type>::do_grouping(). 3723132720Skan * 3724132720Skan * @return string representing grouping specification. 3725132720Skan */ 3726132720Skan string 372797403Sobrien grouping() const 372897403Sobrien { return this->do_grouping(); } 372997403Sobrien 3730132720Skan /** 3731132720Skan * @brief Return currency symbol string. 3732132720Skan * 3733132720Skan * This function returns a string_type to use as a currency symbol. It 3734132720Skan * does so by returning returning 3735132720Skan * moneypunct<char_type>::do_curr_symbol(). 3736132720Skan * 3737132720Skan * @return @a string_type representing a currency symbol. 3738132720Skan */ 3739132720Skan string_type 374097403Sobrien curr_symbol() const 374197403Sobrien { return this->do_curr_symbol(); } 374297403Sobrien 3743132720Skan /** 3744132720Skan * @brief Return positive sign string. 3745132720Skan * 3746132720Skan * This function returns a string_type to use as a sign for positive 3747132720Skan * amounts. It does so by returning returning 3748132720Skan * moneypunct<char_type>::do_positive_sign(). 3749132720Skan * 3750132720Skan * If the return value contains more than one character, the first 3751132720Skan * character appears in the position indicated by pos_format() and the 3752132720Skan * remainder appear at the end of the formatted string. 3753132720Skan * 3754132720Skan * @return @a string_type representing a positive sign. 3755132720Skan */ 3756132720Skan string_type 375797403Sobrien positive_sign() const 375897403Sobrien { return this->do_positive_sign(); } 375997403Sobrien 3760132720Skan /** 3761132720Skan * @brief Return negative sign string. 3762132720Skan * 3763132720Skan * This function returns a string_type to use as a sign for negative 3764132720Skan * amounts. It does so by returning returning 3765132720Skan * moneypunct<char_type>::do_negative_sign(). 3766132720Skan * 3767132720Skan * If the return value contains more than one character, the first 3768132720Skan * character appears in the position indicated by neg_format() and the 3769132720Skan * remainder appear at the end of the formatted string. 3770132720Skan * 3771132720Skan * @return @a string_type representing a negative sign. 3772132720Skan */ 3773132720Skan string_type 377497403Sobrien negative_sign() const 377597403Sobrien { return this->do_negative_sign(); } 377697403Sobrien 3777132720Skan /** 3778132720Skan * @brief Return number of digits in fraction. 3779132720Skan * 3780132720Skan * This function returns the exact number of digits that make up the 3781132720Skan * fractional part of a money amount. It does so by returning 3782132720Skan * returning moneypunct<char_type>::do_frac_digits(). 3783132720Skan * 3784132720Skan * The fractional part of a money amount is optional. But if it is 3785132720Skan * present, there must be frac_digits() digits. 3786132720Skan * 3787132720Skan * @return Number of digits in amount fraction. 3788132720Skan */ 3789132720Skan int 379097403Sobrien frac_digits() const 379197403Sobrien { return this->do_frac_digits(); } 379297403Sobrien 3793132720Skan //@{ 3794132720Skan /** 3795132720Skan * @brief Return pattern for money values. 3796132720Skan * 3797132720Skan * This function returns a pattern describing the formatting of a 3798132720Skan * positive or negative valued money amount. It does so by returning 3799132720Skan * returning moneypunct<char_type>::do_pos_format() or 3800132720Skan * moneypunct<char_type>::do_neg_format(). 3801132720Skan * 3802132720Skan * The pattern has 4 fields describing the ordering of symbol, sign, 3803132720Skan * value, and none or space. There must be one of each in the pattern. 3804132720Skan * The none and space enums may not appear in the first field and space 3805132720Skan * may not appear in the final field. 3806132720Skan * 3807132720Skan * The parts of a money string must appear in the order indicated by 3808132720Skan * the fields of the pattern. The symbol field indicates that the 3809132720Skan * value of curr_symbol() may be present. The sign field indicates 3810132720Skan * that the value of positive_sign() or negative_sign() must be 3811132720Skan * present. The value field indicates that the absolute value of the 3812132720Skan * money amount is present. none indicates 0 or more whitespace 3813132720Skan * characters, except at the end, where it permits no whitespace. 3814132720Skan * space indicates that 1 or more whitespace characters must be 3815132720Skan * present. 3816132720Skan * 3817132720Skan * For example, for the US locale and pos_format() pattern 3818132720Skan * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == 3819132720Skan * '+', and value 10.01, and options set to force the symbol, the 3820132720Skan * corresponding string is "$+10.01". 3821132720Skan * 3822132720Skan * @return Pattern for money values. 3823132720Skan */ 3824132720Skan pattern 382597403Sobrien pos_format() const 382697403Sobrien { return this->do_pos_format(); } 382797403Sobrien 3828132720Skan pattern 382997403Sobrien neg_format() const 383097403Sobrien { return this->do_neg_format(); } 3831132720Skan //@} 383297403Sobrien 383397403Sobrien protected: 3834132720Skan /// Destructor. 3835132720Skan virtual 383697403Sobrien ~moneypunct(); 383797403Sobrien 3838132720Skan /** 3839132720Skan * @brief Return decimal point character. 3840132720Skan * 3841132720Skan * Returns a char_type to use as a decimal point. This function is a 3842132720Skan * hook for derived classes to change the value returned. 3843132720Skan * 3844132720Skan * @return @a char_type representing a decimal point. 3845132720Skan */ 384697403Sobrien virtual char_type 384797403Sobrien do_decimal_point() const 3848132720Skan { return _M_data->_M_decimal_point; } 3849132720Skan 3850132720Skan /** 3851132720Skan * @brief Return thousands separator character. 3852132720Skan * 3853132720Skan * Returns a char_type to use as a thousands separator. This function 3854132720Skan * is a hook for derived classes to change the value returned. 3855132720Skan * 3856132720Skan * @return @a char_type representing a thousands separator. 3857132720Skan */ 385897403Sobrien virtual char_type 385997403Sobrien do_thousands_sep() const 3860132720Skan { return _M_data->_M_thousands_sep; } 3861132720Skan 3862132720Skan /** 3863132720Skan * @brief Return grouping specification. 3864132720Skan * 3865132720Skan * Returns a string representing groupings for the integer part of a 3866132720Skan * number. This function is a hook for derived classes to change the 3867132720Skan * value returned. @see grouping() for details. 3868132720Skan * 3869132720Skan * @return String representing grouping specification. 3870132720Skan */ 3871132720Skan virtual string 387297403Sobrien do_grouping() const 3873132720Skan { return _M_data->_M_grouping; } 387497403Sobrien 3875132720Skan /** 3876132720Skan * @brief Return currency symbol string. 3877132720Skan * 3878132720Skan * This function returns a string_type to use as a currency symbol. 3879132720Skan * This function is a hook for derived classes to change the value 3880132720Skan * returned. @see curr_symbol() for details. 3881132720Skan * 3882132720Skan * @return @a string_type representing a currency symbol. 3883132720Skan */ 3884132720Skan virtual string_type 388597403Sobrien do_curr_symbol() const 3886132720Skan { return _M_data->_M_curr_symbol; } 388797403Sobrien 3888132720Skan /** 3889132720Skan * @brief Return positive sign string. 3890132720Skan * 3891132720Skan * This function returns a string_type to use as a sign for positive 3892132720Skan * amounts. This function is a hook for derived classes to change the 3893132720Skan * value returned. @see positive_sign() for details. 3894132720Skan * 3895132720Skan * @return @a string_type representing a positive sign. 3896132720Skan */ 3897132720Skan virtual string_type 389897403Sobrien do_positive_sign() const 3899132720Skan { return _M_data->_M_positive_sign; } 390097403Sobrien 3901132720Skan /** 3902132720Skan * @brief Return negative sign string. 3903132720Skan * 3904132720Skan * This function returns a string_type to use as a sign for negative 3905132720Skan * amounts. This function is a hook for derived classes to change the 3906132720Skan * value returned. @see negative_sign() for details. 3907132720Skan * 3908132720Skan * @return @a string_type representing a negative sign. 3909132720Skan */ 3910132720Skan virtual string_type 391197403Sobrien do_negative_sign() const 3912132720Skan { return _M_data->_M_negative_sign; } 391397403Sobrien 3914132720Skan /** 3915132720Skan * @brief Return number of digits in fraction. 3916132720Skan * 3917132720Skan * This function returns the exact number of digits that make up the 3918132720Skan * fractional part of a money amount. This function is a hook for 3919132720Skan * derived classes to change the value returned. @see frac_digits() 3920132720Skan * for details. 3921132720Skan * 3922132720Skan * @return Number of digits in amount fraction. 3923132720Skan */ 3924132720Skan virtual int 392597403Sobrien do_frac_digits() const 3926132720Skan { return _M_data->_M_frac_digits; } 392797403Sobrien 3928132720Skan /** 3929132720Skan * @brief Return pattern for money values. 3930132720Skan * 3931132720Skan * This function returns a pattern describing the formatting of a 3932132720Skan * positive valued money amount. This function is a hook for derived 3933132720Skan * classes to change the value returned. @see pos_format() for 3934132720Skan * details. 3935132720Skan * 3936132720Skan * @return Pattern for money values. 3937132720Skan */ 3938132720Skan virtual pattern 393997403Sobrien do_pos_format() const 3940132720Skan { return _M_data->_M_pos_format; } 394197403Sobrien 3942132720Skan /** 3943132720Skan * @brief Return pattern for money values. 3944132720Skan * 3945132720Skan * This function returns a pattern describing the formatting of a 3946132720Skan * negative valued money amount. This function is a hook for derived 3947132720Skan * classes to change the value returned. @see neg_format() for 3948132720Skan * details. 3949132720Skan * 3950132720Skan * @return Pattern for money values. 3951132720Skan */ 3952132720Skan virtual pattern 395397403Sobrien do_neg_format() const 3954132720Skan { return _M_data->_M_neg_format; } 395597403Sobrien 395697403Sobrien // For use at construction time only. 3957132720Skan void 3958132720Skan _M_initialize_moneypunct(__c_locale __cloc = NULL, 3959102782Skan const char* __name = NULL); 396097403Sobrien }; 396197403Sobrien 396297403Sobrien template<typename _CharT, bool _Intl> 396397403Sobrien locale::id moneypunct<_CharT, _Intl>::id; 396497403Sobrien 396597403Sobrien template<typename _CharT, bool _Intl> 396697403Sobrien const bool moneypunct<_CharT, _Intl>::intl; 396797403Sobrien 396897403Sobrien template<> 396997403Sobrien moneypunct<char, true>::~moneypunct(); 397097403Sobrien 397197403Sobrien template<> 397297403Sobrien moneypunct<char, false>::~moneypunct(); 397397403Sobrien 3974132720Skan template<> 397597403Sobrien void 3976102782Skan moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*); 397797403Sobrien 3978132720Skan template<> 397997403Sobrien void 3980102782Skan moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*); 398197403Sobrien 3982132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 398397403Sobrien template<> 398497403Sobrien moneypunct<wchar_t, true>::~moneypunct(); 398597403Sobrien 398697403Sobrien template<> 398797403Sobrien moneypunct<wchar_t, false>::~moneypunct(); 398897403Sobrien 3989132720Skan template<> 399097403Sobrien void 3991132720Skan moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale, 3992102782Skan const char*); 399397403Sobrien 3994132720Skan template<> 399597403Sobrien void 3996132720Skan moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale, 3997102782Skan const char*); 399897403Sobrien#endif 399997403Sobrien 4000169691Skan /// @brief class moneypunct_byname [22.2.6.4]. 400197403Sobrien template<typename _CharT, bool _Intl> 400297403Sobrien class moneypunct_byname : public moneypunct<_CharT, _Intl> 400397403Sobrien { 400497403Sobrien public: 4005132720Skan typedef _CharT char_type; 4006132720Skan typedef basic_string<_CharT> string_type; 400797403Sobrien 400897403Sobrien static const bool intl = _Intl; 400997403Sobrien 4010132720Skan explicit 401197403Sobrien moneypunct_byname(const char* __s, size_t __refs = 0) 401297403Sobrien : moneypunct<_CharT, _Intl>(__refs) 401397403Sobrien { 4014132720Skan if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 4015132720Skan { 4016132720Skan __c_locale __tmp; 4017132720Skan this->_S_create_c_locale(__tmp, __s); 4018132720Skan this->_M_initialize_moneypunct(__tmp); 4019132720Skan this->_S_destroy_c_locale(__tmp); 4020132720Skan } 402197403Sobrien } 402297403Sobrien 402397403Sobrien protected: 4024132720Skan virtual 4025132720Skan ~moneypunct_byname() { } 402697403Sobrien }; 402797403Sobrien 402897403Sobrien template<typename _CharT, bool _Intl> 402997403Sobrien const bool moneypunct_byname<_CharT, _Intl>::intl; 403097403Sobrien 4031169691Skan_GLIBCXX_BEGIN_LDBL_NAMESPACE 4032132720Skan /** 4033132720Skan * @brief Facet for parsing monetary amounts. 4034132720Skan * 4035132720Skan * This facet encapsulates the code to parse and return a monetary 4036132720Skan * amount from a string. 4037132720Skan * 4038132720Skan * The money_get template uses protected virtual functions to 4039132720Skan * provide the actual results. The public accessors forward the 4040132720Skan * call to the virtual functions. These virtual functions are 4041132720Skan * hooks for developers to implement the behavior they require from 4042132720Skan * the money_get facet. 4043132720Skan */ 404497403Sobrien template<typename _CharT, typename _InIter> 404597403Sobrien class money_get : public locale::facet 404697403Sobrien { 404797403Sobrien public: 404897403Sobrien // Types: 4049132720Skan //@{ 4050132720Skan /// Public typedefs 4051132720Skan typedef _CharT char_type; 4052132720Skan typedef _InIter iter_type; 4053132720Skan typedef basic_string<_CharT> string_type; 4054132720Skan //@} 405597403Sobrien 4056132720Skan /// Numpunct facet id. 4057132720Skan static locale::id id; 405897403Sobrien 4059132720Skan /** 4060132720Skan * @brief Constructor performs initialization. 4061132720Skan * 4062132720Skan * This is the constructor provided by the standard. 4063132720Skan * 4064132720Skan * @param refs Passed to the base facet class. 4065132720Skan */ 4066132720Skan explicit 4067132720Skan money_get(size_t __refs = 0) : facet(__refs) { } 406897403Sobrien 4069132720Skan /** 4070132720Skan * @brief Read and parse a monetary value. 4071132720Skan * 4072132720Skan * This function reads characters from @a s, interprets them as a 4073132720Skan * monetary value according to moneypunct and ctype facets retrieved 4074132720Skan * from io.getloc(), and returns the result in @a units as an integral 4075132720Skan * value moneypunct::frac_digits() * the actual amount. For example, 4076132720Skan * the string $10.01 in a US locale would store 1001 in @a units. 4077132720Skan * 4078132720Skan * Any characters not part of a valid money amount are not consumed. 4079132720Skan * 4080132720Skan * If a money value cannot be parsed from the input stream, sets 4081132720Skan * err=(err|io.failbit). If the stream is consumed before finishing 4082132720Skan * parsing, sets err=(err|io.failbit|io.eofbit). @a units is 4083132720Skan * unchanged if parsing fails. 4084132720Skan * 4085132720Skan * This function works by returning the result of do_get(). 4086132720Skan * 4087132720Skan * @param s Start of characters to parse. 4088132720Skan * @param end End of characters to parse. 4089132720Skan * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 4090132720Skan * @param io Source of facets and io state. 4091132720Skan * @param err Error field to set if parsing fails. 4092132720Skan * @param units Place to store result of parsing. 4093132720Skan * @return Iterator referencing first character beyond valid money 4094132720Skan * amount. 4095132720Skan */ 4096132720Skan iter_type 4097132720Skan get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 409897403Sobrien ios_base::iostate& __err, long double& __units) const 409997403Sobrien { return this->do_get(__s, __end, __intl, __io, __err, __units); } 410097403Sobrien 4101132720Skan /** 4102132720Skan * @brief Read and parse a monetary value. 4103132720Skan * 4104132720Skan * This function reads characters from @a s, interprets them as a 4105132720Skan * monetary value according to moneypunct and ctype facets retrieved 4106132720Skan * from io.getloc(), and returns the result in @a digits. For example, 4107132720Skan * the string $10.01 in a US locale would store "1001" in @a digits. 4108132720Skan * 4109132720Skan * Any characters not part of a valid money amount are not consumed. 4110132720Skan * 4111132720Skan * If a money value cannot be parsed from the input stream, sets 4112132720Skan * err=(err|io.failbit). If the stream is consumed before finishing 4113132720Skan * parsing, sets err=(err|io.failbit|io.eofbit). 4114132720Skan * 4115132720Skan * This function works by returning the result of do_get(). 4116132720Skan * 4117132720Skan * @param s Start of characters to parse. 4118132720Skan * @param end End of characters to parse. 4119132720Skan * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 4120132720Skan * @param io Source of facets and io state. 4121132720Skan * @param err Error field to set if parsing fails. 4122132720Skan * @param digits Place to store result of parsing. 4123132720Skan * @return Iterator referencing first character beyond valid money 4124132720Skan * amount. 4125132720Skan */ 4126132720Skan iter_type 4127132720Skan get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 412897403Sobrien ios_base::iostate& __err, string_type& __digits) const 412997403Sobrien { return this->do_get(__s, __end, __intl, __io, __err, __digits); } 413097403Sobrien 413197403Sobrien protected: 4132132720Skan /// Destructor. 4133132720Skan virtual 413497403Sobrien ~money_get() { } 413597403Sobrien 4136132720Skan /** 4137132720Skan * @brief Read and parse a monetary value. 4138132720Skan * 4139132720Skan * This function reads and parses characters representing a monetary 4140132720Skan * value. This function is a hook for derived classes to change the 4141132720Skan * value returned. @see get() for details. 4142132720Skan */ 4143169691Skan // XXX GLIBCXX_ABI Deprecated 4144169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 4145132720Skan virtual iter_type 4146169691Skan __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 4147169691Skan ios_base::iostate& __err, double& __units) const; 4148169691Skan#else 4149169691Skan virtual iter_type 4150132720Skan do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 415197403Sobrien ios_base::iostate& __err, long double& __units) const; 4152169691Skan#endif 415397403Sobrien 4154132720Skan /** 4155132720Skan * @brief Read and parse a monetary value. 4156132720Skan * 4157132720Skan * This function reads and parses characters representing a monetary 4158132720Skan * value. This function is a hook for derived classes to change the 4159132720Skan * value returned. @see get() for details. 4160132720Skan */ 4161132720Skan virtual iter_type 4162132720Skan do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 416397403Sobrien ios_base::iostate& __err, string_type& __digits) const; 4164132720Skan 4165169691Skan // XXX GLIBCXX_ABI Deprecated 4166169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 4167169691Skan virtual iter_type 4168169691Skan do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, 4169169691Skan ios_base::iostate& __err, long double& __units) const; 4170169691Skan#endif 4171169691Skan 4172132720Skan template<bool _Intl> 4173132720Skan iter_type 4174132720Skan _M_extract(iter_type __s, iter_type __end, ios_base& __io, 4175132720Skan ios_base::iostate& __err, string& __digits) const; 417697403Sobrien }; 417797403Sobrien 417897403Sobrien template<typename _CharT, typename _InIter> 417997403Sobrien locale::id money_get<_CharT, _InIter>::id; 418097403Sobrien 4181132720Skan /** 4182132720Skan * @brief Facet for outputting monetary amounts. 4183132720Skan * 4184132720Skan * This facet encapsulates the code to format and output a monetary 4185132720Skan * amount. 4186132720Skan * 4187132720Skan * The money_put template uses protected virtual functions to 4188132720Skan * provide the actual results. The public accessors forward the 4189132720Skan * call to the virtual functions. These virtual functions are 4190132720Skan * hooks for developers to implement the behavior they require from 4191132720Skan * the money_put facet. 4192132720Skan */ 419397403Sobrien template<typename _CharT, typename _OutIter> 419497403Sobrien class money_put : public locale::facet 419597403Sobrien { 419697403Sobrien public: 4197132720Skan //@{ 4198132720Skan /// Public typedefs 4199132720Skan typedef _CharT char_type; 4200132720Skan typedef _OutIter iter_type; 420197403Sobrien typedef basic_string<_CharT> string_type; 4202132720Skan //@} 420397403Sobrien 4204132720Skan /// Numpunct facet id. 4205132720Skan static locale::id id; 420697403Sobrien 4207132720Skan /** 4208132720Skan * @brief Constructor performs initialization. 4209132720Skan * 4210132720Skan * This is the constructor provided by the standard. 4211132720Skan * 4212132720Skan * @param refs Passed to the base facet class. 4213132720Skan */ 4214132720Skan explicit 4215132720Skan money_put(size_t __refs = 0) : facet(__refs) { } 421697403Sobrien 4217132720Skan /** 4218132720Skan * @brief Format and output a monetary value. 4219132720Skan * 4220132720Skan * This function formats @a units as a monetary value according to 4221132720Skan * moneypunct and ctype facets retrieved from io.getloc(), and writes 4222132720Skan * the resulting characters to @a s. For example, the value 1001 in a 4223132720Skan * US locale would write "$10.01" to @a s. 4224132720Skan * 4225132720Skan * This function works by returning the result of do_put(). 4226132720Skan * 4227132720Skan * @param s The stream to write to. 4228132720Skan * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 4229132720Skan * @param io Source of facets and io state. 4230132720Skan * @param fill char_type to use for padding. 4231132720Skan * @param units Place to store result of parsing. 4232132720Skan * @return Iterator after writing. 4233132720Skan */ 4234132720Skan iter_type 423597403Sobrien put(iter_type __s, bool __intl, ios_base& __io, 423697403Sobrien char_type __fill, long double __units) const 423797403Sobrien { return this->do_put(__s, __intl, __io, __fill, __units); } 423897403Sobrien 4239132720Skan /** 4240132720Skan * @brief Format and output a monetary value. 4241132720Skan * 4242132720Skan * This function formats @a digits as a monetary value according to 4243132720Skan * moneypunct and ctype facets retrieved from io.getloc(), and writes 4244132720Skan * the resulting characters to @a s. For example, the string "1001" in 4245132720Skan * a US locale would write "$10.01" to @a s. 4246132720Skan * 4247132720Skan * This function works by returning the result of do_put(). 4248132720Skan * 4249132720Skan * @param s The stream to write to. 4250132720Skan * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 4251132720Skan * @param io Source of facets and io state. 4252132720Skan * @param fill char_type to use for padding. 4253132720Skan * @param units Place to store result of parsing. 4254132720Skan * @return Iterator after writing. 4255132720Skan */ 4256132720Skan iter_type 425797403Sobrien put(iter_type __s, bool __intl, ios_base& __io, 425897403Sobrien char_type __fill, const string_type& __digits) const 425997403Sobrien { return this->do_put(__s, __intl, __io, __fill, __digits); } 426097403Sobrien 426197403Sobrien protected: 4262132720Skan /// Destructor. 4263132720Skan virtual 426497403Sobrien ~money_put() { } 426597403Sobrien 4266132720Skan /** 4267132720Skan * @brief Format and output a monetary value. 4268132720Skan * 4269132720Skan * This function formats @a units as a monetary value according to 4270132720Skan * moneypunct and ctype facets retrieved from io.getloc(), and writes 4271132720Skan * the resulting characters to @a s. For example, the value 1001 in a 4272132720Skan * US locale would write "$10.01" to @a s. 4273132720Skan * 4274132720Skan * This function is a hook for derived classes to change the value 4275132720Skan * returned. @see put(). 4276132720Skan * 4277132720Skan * @param s The stream to write to. 4278132720Skan * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 4279132720Skan * @param io Source of facets and io state. 4280132720Skan * @param fill char_type to use for padding. 4281132720Skan * @param units Place to store result of parsing. 4282132720Skan * @return Iterator after writing. 4283132720Skan */ 4284169691Skan // XXX GLIBCXX_ABI Deprecated 4285169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 428697403Sobrien virtual iter_type 4287169691Skan __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 4288169691Skan double __units) const; 4289169691Skan#else 4290169691Skan virtual iter_type 429197403Sobrien do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 429297403Sobrien long double __units) const; 4293169691Skan#endif 429497403Sobrien 4295132720Skan /** 4296132720Skan * @brief Format and output a monetary value. 4297132720Skan * 4298132720Skan * This function formats @a digits as a monetary value according to 4299132720Skan * moneypunct and ctype facets retrieved from io.getloc(), and writes 4300132720Skan * the resulting characters to @a s. For example, the string "1001" in 4301132720Skan * a US locale would write "$10.01" to @a s. 4302132720Skan * 4303132720Skan * This function is a hook for derived classes to change the value 4304132720Skan * returned. @see put(). 4305132720Skan * 4306132720Skan * @param s The stream to write to. 4307132720Skan * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. 4308132720Skan * @param io Source of facets and io state. 4309132720Skan * @param fill char_type to use for padding. 4310132720Skan * @param units Place to store result of parsing. 4311132720Skan * @return Iterator after writing. 4312132720Skan */ 431397403Sobrien virtual iter_type 431497403Sobrien do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 431597403Sobrien const string_type& __digits) const; 4316132720Skan 4317169691Skan // XXX GLIBCXX_ABI Deprecated 4318169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 4319169691Skan virtual iter_type 4320169691Skan do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 4321169691Skan long double __units) const; 4322169691Skan#endif 4323169691Skan 4324132720Skan template<bool _Intl> 4325132720Skan iter_type 4326132720Skan _M_insert(iter_type __s, ios_base& __io, char_type __fill, 4327132720Skan const string_type& __digits) const; 432897403Sobrien }; 432997403Sobrien 433097403Sobrien template<typename _CharT, typename _OutIter> 433197403Sobrien locale::id money_put<_CharT, _OutIter>::id; 433297403Sobrien 4333169691Skan_GLIBCXX_END_LDBL_NAMESPACE 4334169691Skan 4335132720Skan /** 4336132720Skan * @brief Messages facet base class providing catalog typedef. 4337132720Skan */ 4338241957Sdim class messages_base 433997403Sobrien { 4340241957Sdim public: 434197403Sobrien typedef int catalog; 434297403Sobrien }; 434397403Sobrien 4344132720Skan /** 4345132720Skan * @brief Facet for handling message catalogs 4346132720Skan * 4347132720Skan * This facet encapsulates the code to retrieve messages from 4348132720Skan * message catalogs. The only thing defined by the standard for this facet 4349132720Skan * is the interface. All underlying functionality is 4350132720Skan * implementation-defined. 4351132720Skan * 4352132720Skan * This library currently implements 3 versions of the message facet. The 4353132720Skan * first version (gnu) is a wrapper around gettext, provided by libintl. 4354132720Skan * The second version (ieee) is a wrapper around catgets. The final 4355132720Skan * version (default) does no actual translation. These implementations are 4356132720Skan * only provided for char and wchar_t instantiations. 4357132720Skan * 4358132720Skan * The messages template uses protected virtual functions to 4359132720Skan * provide the actual results. The public accessors forward the 4360132720Skan * call to the virtual functions. These virtual functions are 4361132720Skan * hooks for developers to implement the behavior they require from 4362132720Skan * the messages facet. 4363132720Skan */ 436497403Sobrien template<typename _CharT> 436597403Sobrien class messages : public locale::facet, public messages_base 436697403Sobrien { 436797403Sobrien public: 436897403Sobrien // Types: 4369132720Skan //@{ 4370132720Skan /// Public typedefs 4371132720Skan typedef _CharT char_type; 4372132720Skan typedef basic_string<_CharT> string_type; 4373132720Skan //@} 437497403Sobrien 437597403Sobrien protected: 437697403Sobrien // Underlying "C" library locale information saved from 437797403Sobrien // initialization, needed by messages_byname as well. 437897403Sobrien __c_locale _M_c_locale_messages; 4379132720Skan const char* _M_name_messages; 438097403Sobrien 438197403Sobrien public: 4382132720Skan /// Numpunct facet id. 4383132720Skan static locale::id id; 438497403Sobrien 4385132720Skan /** 4386132720Skan * @brief Constructor performs initialization. 4387132720Skan * 4388132720Skan * This is the constructor provided by the standard. 4389132720Skan * 4390132720Skan * @param refs Passed to the base facet class. 4391132720Skan */ 4392132720Skan explicit 4393110614Skan messages(size_t __refs = 0); 439497403Sobrien 439597403Sobrien // Non-standard. 4396132720Skan /** 4397132720Skan * @brief Internal constructor. Not for general use. 4398132720Skan * 4399132720Skan * This is a constructor for use by the library itself to set up new 4400132720Skan * locales. 4401132720Skan * 4402132720Skan * @param cloc The "C" locale. 4403132720Skan * @param s The name of a locale. 4404132720Skan * @param refs Refcount to pass to the base class. 4405132720Skan */ 4406132720Skan explicit 4407110614Skan messages(__c_locale __cloc, const char* __s, size_t __refs = 0); 440897403Sobrien 4409132720Skan /* 4410132720Skan * @brief Open a message catalog. 4411132720Skan * 4412132720Skan * This function opens and returns a handle to a message catalog by 4413132720Skan * returning do_open(s, loc). 4414132720Skan * 4415132720Skan * @param s The catalog to open. 4416132720Skan * @param loc Locale to use for character set conversions. 4417132720Skan * @return Handle to the catalog or value < 0 if open fails. 4418132720Skan */ 4419132720Skan catalog 442097403Sobrien open(const basic_string<char>& __s, const locale& __loc) const 442197403Sobrien { return this->do_open(__s, __loc); } 442297403Sobrien 442397403Sobrien // Non-standard and unorthodox, yet effective. 4424132720Skan /* 4425132720Skan * @brief Open a message catalog. 4426132720Skan * 4427132720Skan * This non-standard function opens and returns a handle to a message 4428132720Skan * catalog by returning do_open(s, loc). The third argument provides a 4429132720Skan * message catalog root directory for gnu gettext and is ignored 4430132720Skan * otherwise. 4431132720Skan * 4432132720Skan * @param s The catalog to open. 4433132720Skan * @param loc Locale to use for character set conversions. 4434132720Skan * @param dir Message catalog root directory. 4435132720Skan * @return Handle to the catalog or value < 0 if open fails. 4436132720Skan */ 4437132720Skan catalog 443897403Sobrien open(const basic_string<char>&, const locale&, const char*) const; 443997403Sobrien 4440132720Skan /* 4441132720Skan * @brief Look up a string in a message catalog. 4442132720Skan * 4443132720Skan * This function retrieves and returns a message from a catalog by 4444132720Skan * returning do_get(c, set, msgid, s). 4445132720Skan * 4446132720Skan * For gnu, @a set and @a msgid are ignored. Returns gettext(s). 4447132720Skan * For default, returns s. For ieee, returns catgets(c,set,msgid,s). 4448132720Skan * 4449132720Skan * @param c The catalog to access. 4450132720Skan * @param set Implementation-defined. 4451132720Skan * @param msgid Implementation-defined. 4452132720Skan * @param s Default return value if retrieval fails. 4453132720Skan * @return Retrieved message or @a s if get fails. 4454132720Skan */ 4455132720Skan string_type 445697403Sobrien get(catalog __c, int __set, int __msgid, const string_type& __s) const 445797403Sobrien { return this->do_get(__c, __set, __msgid, __s); } 445897403Sobrien 4459132720Skan /* 4460132720Skan * @brief Close a message catalog. 4461132720Skan * 4462132720Skan * Closes catalog @a c by calling do_close(c). 4463132720Skan * 4464132720Skan * @param c The catalog to close. 4465132720Skan */ 4466132720Skan void 446797403Sobrien close(catalog __c) const 446897403Sobrien { return this->do_close(__c); } 446997403Sobrien 447097403Sobrien protected: 4471132720Skan /// Destructor. 4472132720Skan virtual 4473110614Skan ~messages(); 447497403Sobrien 4475132720Skan /* 4476132720Skan * @brief Open a message catalog. 4477132720Skan * 4478132720Skan * This function opens and returns a handle to a message catalog in an 4479132720Skan * implementation-defined manner. This function is a hook for derived 4480132720Skan * classes to change the value returned. 4481132720Skan * 4482132720Skan * @param s The catalog to open. 4483132720Skan * @param loc Locale to use for character set conversions. 4484132720Skan * @return Handle to the opened catalog, value < 0 if open failed. 4485132720Skan */ 4486132720Skan virtual catalog 448797403Sobrien do_open(const basic_string<char>&, const locale&) const; 448897403Sobrien 4489132720Skan /* 4490132720Skan * @brief Look up a string in a message catalog. 4491132720Skan * 4492132720Skan * This function retrieves and returns a message from a catalog in an 4493132720Skan * implementation-defined manner. This function is a hook for derived 4494132720Skan * classes to change the value returned. 4495132720Skan * 4496132720Skan * For gnu, @a set and @a msgid are ignored. Returns gettext(s). 4497132720Skan * For default, returns s. For ieee, returns catgets(c,set,msgid,s). 4498132720Skan * 4499132720Skan * @param c The catalog to access. 4500132720Skan * @param set Implementation-defined. 4501132720Skan * @param msgid Implementation-defined. 4502132720Skan * @param s Default return value if retrieval fails. 4503132720Skan * @return Retrieved message or @a s if get fails. 4504132720Skan */ 4505132720Skan virtual string_type 450697403Sobrien do_get(catalog, int, int, const string_type& __dfault) const; 450797403Sobrien 4508132720Skan /* 4509132720Skan * @brief Close a message catalog. 4510132720Skan * 4511132720Skan * @param c The catalog to close. 4512132720Skan */ 4513132720Skan virtual void 451497403Sobrien do_close(catalog) const; 451597403Sobrien 451697403Sobrien // Returns a locale and codeset-converted string, given a char* message. 451797403Sobrien char* 451897403Sobrien _M_convert_to_char(const string_type& __msg) const 451997403Sobrien { 452097403Sobrien // XXX 452197403Sobrien return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str())); 452297403Sobrien } 452397403Sobrien 452497403Sobrien // Returns a locale and codeset-converted string, given a char* message. 452597403Sobrien string_type 4526132720Skan _M_convert_from_char(char*) const 452797403Sobrien { 4528132720Skan#if 0 452997403Sobrien // Length of message string without terminating null. 453097403Sobrien size_t __len = char_traits<char>::length(__msg) - 1; 453197403Sobrien 453297403Sobrien // "everybody can easily convert the string using 453397403Sobrien // mbsrtowcs/wcsrtombs or with iconv()" 4534132720Skan 453597403Sobrien // Convert char* to _CharT in locale used to open catalog. 453697403Sobrien // XXX need additional template parameter on messages class for this.. 453797403Sobrien // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type; 4538132720Skan typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type; 453997403Sobrien 454097403Sobrien __codecvt_type::state_type __state; 454197403Sobrien // XXX may need to initialize state. 454297403Sobrien //initialize_state(__state._M_init()); 4543132720Skan 454497403Sobrien char* __from_next; 454597403Sobrien // XXX what size for this string? 454697403Sobrien _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); 454797403Sobrien const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv); 454897403Sobrien __cvt.out(__state, __msg, __msg + __len, __from_next, 454997403Sobrien __to, __to + __len + 1, __to_next); 455097403Sobrien return string_type(__to); 455197403Sobrien#endif 455297403Sobrien#if 0 455397403Sobrien typedef ctype<_CharT> __ctype_type; 455497403Sobrien // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg); 455597403Sobrien const __ctype_type& __cvt = use_facet<__ctype_type>(locale()); 455697403Sobrien // XXX Again, proper length of converted string an issue here. 455797403Sobrien // For now, assume the converted length is not larger. 455897403Sobrien _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1)); 455997403Sobrien __cvt.widen(__msg, __msg + __len, __dest); 456097403Sobrien return basic_string<_CharT>(__dest); 456197403Sobrien#endif 456297403Sobrien return string_type(); 456397403Sobrien } 456497403Sobrien }; 456597403Sobrien 456697403Sobrien template<typename _CharT> 456797403Sobrien locale::id messages<_CharT>::id; 456897403Sobrien 456997403Sobrien // Specializations for required instantiations. 457097403Sobrien template<> 457197403Sobrien string 457297403Sobrien messages<char>::do_get(catalog, int, int, const string&) const; 457397403Sobrien 4574132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 4575103447Skan template<> 4576103447Skan wstring 4577103447Skan messages<wchar_t>::do_get(catalog, int, int, const wstring&) const; 4578103447Skan#endif 4579103447Skan 4580169691Skan /// @brief class messages_byname [22.2.7.2]. 4581169691Skan template<typename _CharT> 458297403Sobrien class messages_byname : public messages<_CharT> 458397403Sobrien { 458497403Sobrien public: 4585132720Skan typedef _CharT char_type; 4586132720Skan typedef basic_string<_CharT> string_type; 458797403Sobrien 4588132720Skan explicit 4589110614Skan messages_byname(const char* __s, size_t __refs = 0); 459097403Sobrien 459197403Sobrien protected: 4592132720Skan virtual 4593132720Skan ~messages_byname() 459497403Sobrien { } 459597403Sobrien }; 459697403Sobrien 4597169691Skan_GLIBCXX_END_NAMESPACE 4598169691Skan 4599110614Skan // Include host and configuration specific messages functions. 4600110614Skan #include <bits/messages_members.h> 460197403Sobrien 4602169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 4603110614Skan 460497403Sobrien // Subclause convenience interfaces, inlines. 460597403Sobrien // NB: These are inline because, when used in a loop, some compilers 460697403Sobrien // can hoist the body out of the loop; then it's just as fast as the 460797403Sobrien // C is*() function. 4608169691Skan 4609169691Skan /// Convenience interface to ctype.is(ctype_base::space, __c). 461097403Sobrien template<typename _CharT> 4611132720Skan inline bool 461297403Sobrien isspace(_CharT __c, const locale& __loc) 461397403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); } 461497403Sobrien 4615169691Skan /// Convenience interface to ctype.is(ctype_base::print, __c). 461697403Sobrien template<typename _CharT> 4617132720Skan inline bool 461897403Sobrien isprint(_CharT __c, const locale& __loc) 461997403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); } 462097403Sobrien 4621169691Skan /// Convenience interface to ctype.is(ctype_base::cntrl, __c). 462297403Sobrien template<typename _CharT> 4623132720Skan inline bool 462497403Sobrien iscntrl(_CharT __c, const locale& __loc) 462597403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); } 462697403Sobrien 4627169691Skan /// Convenience interface to ctype.is(ctype_base::upper, __c). 462897403Sobrien template<typename _CharT> 4629132720Skan inline bool 463097403Sobrien isupper(_CharT __c, const locale& __loc) 463197403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); } 463297403Sobrien 4633169691Skan /// Convenience interface to ctype.is(ctype_base::lower, __c). 463497403Sobrien template<typename _CharT> 4635169691Skan inline bool 4636169691Skan islower(_CharT __c, const locale& __loc) 463797403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); } 463897403Sobrien 4639169691Skan /// Convenience interface to ctype.is(ctype_base::alpha, __c). 464097403Sobrien template<typename _CharT> 4641132720Skan inline bool 464297403Sobrien isalpha(_CharT __c, const locale& __loc) 464397403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); } 464497403Sobrien 4645169691Skan /// Convenience interface to ctype.is(ctype_base::digit, __c). 464697403Sobrien template<typename _CharT> 4647132720Skan inline bool 464897403Sobrien isdigit(_CharT __c, const locale& __loc) 464997403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); } 465097403Sobrien 4651169691Skan /// Convenience interface to ctype.is(ctype_base::punct, __c). 465297403Sobrien template<typename _CharT> 4653132720Skan inline bool 465497403Sobrien ispunct(_CharT __c, const locale& __loc) 465597403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); } 465697403Sobrien 4657169691Skan /// Convenience interface to ctype.is(ctype_base::xdigit, __c). 465897403Sobrien template<typename _CharT> 4659132720Skan inline bool 466097403Sobrien isxdigit(_CharT __c, const locale& __loc) 466197403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); } 466297403Sobrien 4663169691Skan /// Convenience interface to ctype.is(ctype_base::alnum, __c). 466497403Sobrien template<typename _CharT> 4665132720Skan inline bool 466697403Sobrien isalnum(_CharT __c, const locale& __loc) 466797403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); } 466897403Sobrien 4669169691Skan /// Convenience interface to ctype.is(ctype_base::graph, __c). 467097403Sobrien template<typename _CharT> 4671132720Skan inline bool 467297403Sobrien isgraph(_CharT __c, const locale& __loc) 467397403Sobrien { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); } 467497403Sobrien 4675169691Skan /// Convenience interface to ctype.toupper(__c). 467697403Sobrien template<typename _CharT> 4677132720Skan inline _CharT 467897403Sobrien toupper(_CharT __c, const locale& __loc) 467997403Sobrien { return use_facet<ctype<_CharT> >(__loc).toupper(__c); } 468097403Sobrien 4681169691Skan /// Convenience interface to ctype.tolower(__c). 468297403Sobrien template<typename _CharT> 4683132720Skan inline _CharT 468497403Sobrien tolower(_CharT __c, const locale& __loc) 468597403Sobrien { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } 468697403Sobrien 4687169691Skan_GLIBCXX_END_NAMESPACE 4688169691Skan 468997403Sobrien#endif 4690