-1- This clause describes components that C++ programs may use to encapsulate (and therefore be more portable when confronting) cultural differences. The locale facility includes internationalization support for character classification and string collation, numeric, monetary, and date/time formatting and parsing, and message retrieval.
-2- The following subclauses describe components for locales themselves, the standard facets, and facilities from the ISO C library, as summarized in Table ??:
Subclause | Header(s) |
lib.locales Locales | <locale> |
lib.locale.categories Standard locale Categories | |
lib.c.locales C library locales | <clocale> |
Header <locale> synopsis
namespace std { //lib.locale, locale: class locale; template <class Facet> const Facet& use_facet(const locale&); template <class Facet> bool has_facet(const locale&) throw();
//lib.locale.convenience, convenience interfaces: template <class charT> bool isspace (charT c, const locale& loc); template <class charT> bool isprint (charT c, const locale& loc); template <class charT> bool iscntrl (charT c, const locale& loc); template <class charT> bool isupper (charT c, const locale& loc); template <class charT> bool islower (charT c, const locale& loc); template <class charT> bool isalpha (charT c, const locale& loc); template <class charT> bool isdigit (charT c, const locale& loc); template <class charT> bool ispunct (charT c, const locale& loc); template <class charT> bool isxdigit(charT c, const locale& loc); template <class charT> bool isalnum (charT c, const locale& loc); template <class charT> bool isgraph (charT c, const locale& loc); template <class charT> charT toupper(charT c, const locale& loc); template <class charT> charT tolower(charT c, const locale& loc);
//lib.category.ctype and lib.facet.ctype.special, ctype: class ctype_base; template <class charT> class ctype; template <> class ctype<char>; // specialization template <class charT> class ctype_byname; template <> class ctype_byname<char>; // specialization class codecvt_base; template <class internT, class externT, class stateT> class codecvt; template <class internT, class externT, class stateT> class codecvt_byname;
//lib.category.numeric and lib.facet.numpunct, numeric: template <class charT, class InputIterator> class num_get; template <class charT, class OutputIterator> class num_put; template <class charT> class numpunct; template <class charT> class numpunct_byname;
//lib.category.collate, collation: template <class charT> class collate; template <class charT> class collate_byname;
//lib.category.time, date and time: class time_base; template <class charT, class InputIterator> class time_get; template <class charT, class InputIterator> class time_get_byname; template <class charT, class OutputIterator> class time_put; template <class charT, class OutputIterator> class time_put_byname;
//lib.category.monetary, money: class money_base; template <class charT, class InputIterator> class money_get; template <class charT, class OutputIterator> class money_put; template <class charT, bool Intl> class moneypunct; template <class charT, bool Intl> class moneypunct_byname;
//lib.category.messages, message retrieval: class messages_base; template <class charT> class messages; template <class charT> class messages_byname; }
-1- The header <locale> defines classes and declares functions that encapsulate and manipulate the information peculiar to a locale.*
[Footnote: In this subclause, the type name struct tm is an incomplete type that is defined in <ctime>. --- end foonote]
namespace std { class locale { public: //types: class facet; class id; typedef int category; static const category // values assigned here are for exposition only none = 0, collate = 0x010, ctype = 0x020, monetary = 0x040, numeric = 0x080, time = 0x100, messages = 0x200, all = collate | ctype | monetary | numeric | time | messages;
//construct/copy/destroy: locale() throw() locale(const locale& other) throw() explicit locale(const char* std_name); locale(const locale& other, const char* std_name, category); template <class Facet> locale(const locale& other, Facet* f); locale(const locale& other, const locale& one, category); ~locale() throw(); // non-virtual const locale& operator=(const locale& other) throw(); template <class Facet> locale combine(const locale& other);
//locale operations: basic_string<char> name() const;
bool operator==(const locale& other) const; bool operator!=(const locale& other) const;
template <class charT, class Traits, class Allocator> bool operator()(const basic_string<charT,Traits,Allocator>& s1, const basic_string<charT,Traits,Allocator>& s2) const;
//global locale objects: static locale global(const locale&); static const locale& classic(); }; }
-1- Class locale implements a type-safe polymorphic set of facets, indexed by facet type. In other words, a facet has a dual role: in one sense, it's just a class interface; at the same time, it's an index into a locale's set of facets.
-2- Access to the facets of a locale is via two function templates, use_facet<> and has_facet<>.
-3- [Example: An iostream operator<< might be implemented as:*
[Footnote: Notice that, in the call to put, the stream is implicitly converted to an ostreambuf_iterator<charT,traits>. --- end foonote]
template <class charT, class traits> basic_ostream<charT,traits>& operator<< (basic_ostream<charT,traits>& s, Date d) { typename basic_ostream<charT,traits>::sentry cerberos(s); if (cerberos) { ios_base::iostate err = 0; tm tmbuf; d.extract(tmbuf); use_facet< time_put<charT,ostreambuf_iterator<charT,traits> > >( s.getloc()).put(s, s, s.fill(), err, &tmbuf, 'x'); s.setstate(err); //might throw } return s; }
-4- In the call to use_facet<Facet>(loc), the type argument chooses a facet, making available all members of the named type. If Facet is not present in a locale (or, failing that, in the global locale), it throws the standard exception bad_cast. A C++ program can check if a locale implements a particular facet with the template function has_facet<Facet>(). User-defined facets may be installed in a locale, and used identically as may standard facets (lib.facets.examples).
-5- [Note: All locale semantics are accessed via use_facet<> and has_facet<>, except that:
-6- An instance of locale is immutable; once a facet reference is obtained from it, that reference remains usable as long as the locale value itself exists.
-7-
In successive calls to a locale facet member function during a call
to an iostream inserter or extractor or a streambuf member function,
the returned result shall be identical.
[Note:
This implies that such results may safely be reused without
calling the locale facet member function again, and
that member functions of iostream classes cannot safely call
imbue()
themselves, except as specified elsewhere.
--- end note]
-8-
A
locale
constructed from a name string (such as "POSIX"), or from parts of
two named locales, has a name; all others do not.
Named locales may be compared for equality; an unnamed locale is equal
only to (copies of) itself.
For an unnamed locale,
locale::name()
returns the string
``*''.
22.1.1.1 - locale types [lib.locale.types]
22.1.1.1.1 - Type locale::category [lib.locale.category]
typedef int category;
-1- Valid category values include the locale member bitmask elements none, collate, ctype, monetary, numeric, time, and messages. In addition, locale member all is defined such that the expression
is true. Further, the result of applying operators | and & to any two valid values is valid, and results in the setwise union and intersection, respectively, of the argument categories.(collate | ctype | monetary | numeric | time | messages | all) == all
-2- locale member functions expecting a category argument require either a valid category value or one of the constants LC_CTYPE etc., defined in <cctype>. Such a category value identifies a set of locale categories. Each locale category, in turn, identifies a set of locale facets, including at least those shown in Table ??:
Category | Includes Facets |
collate | collate<char>, collate<wchar_t> |
ctype | ctype<char>, ctype<wchar_t> |
codecvt<char,char,mbstate_t>, | |
codecvt<wchar_t,char,mbstate_t> | |
monetary | moneypunct<char>, moneypunct<wchar_t> |
moneypunct<char,true>, moneypunct<wchar_t,true>, | |
money_get<char>, money_get<wchar_t> | |
money_put<char>, money_put<wchar_t> | |
numeric | numpunct<char>, numpunct<wchar_t>, |
num_get<char>, num_get<wchar_t> | |
num_put<char>, num_put<wchar_t> | |
time | time_get<char>, time_get<wchar_t>, |
time_put<char>, time_put<wchar_t> | |
messages | messages<char>, messages<wchar_t> |
-3- For any locale loc either constructed, or returned by locale::classic(), and any facet Facet that is a member of a standard category, has_facet<Facet>(loc) is true. Each locale member function which takes a locale::category argument operates on the corresponding set of facets.
-4- An implementation is required to provide those instantiations for facet templates identified as members of a category, and for those shown in Table ??:
Category | Includes Facets |
collate | collate_byname<char>, collate_byname<wchar_t> |
ctype | ctype_byname<char>, ctype_byname<wchar_t> |
monetary | moneypunct_byname<char,International>, |
moneypunct_byname<wchar_t,International>, | |
money_get<C,InputIterator>, | |
money_put<C,OutputIterator> | |
numeric | numpunct_byname<char>, numpunct_byname<wchar_t> |
num_get<C,InputIterator>, num_put<C,OutputIterator> | |
time | time_get<char,InputIterator>, |
time_get_byname<char,InputIterator>, | |
time_get<wchar_t,OutputIterator>, | |
time_get_byname<wchar_t,OutputIterator>, | |
time_put<char,OutputIterator>, | |
time_put_byname<char,OutputIterator>, | |
time_put<wchar_t,OutputIterator> | |
time_put_byname<wchar_t,OutputIterator> | |
messages | messages_byname<char>, messages_byname<wchar_t> |
-5- The provided implementation of members of facets num_get<charT> and num_put<charT> calls use_facet<F>(l) only for facet F of types numpunct<charT> and ctype<charT>, and for locale l the value obtained by calling member getloc() on the ios_base& argument to these functions.
-6-
In declarations of facets, a template formal parameter with name
InputIterator
or
OutputIterator
indicates the set of
all possible instantiations on parameters that satisfy the
requirements of an Input Iterator or an Output Iterator, respectively
(lib.iterator.requirements).
A template formal parameter with name
C
represents the set of all possible instantiations on a parameter that
satisfies the requirements for a character on which any of the iostream
components can be instantiated.
A template formal parameter with name
International
represents the set of all possible instantiations on a bool parameter.
22.1.1.1.2 - Class locale::facet [lib.locale.facet]
namespace std { class locale::facet { protected: explicit facet(size_t refs = 0); virtual ~facet(); private: facet(const facet&); //not defined void operator=(const facet&); // not defined }; }
-1- Class facet is the base class for locale feature sets. A class is a facet if it is publicly derived from another facet, or if it is a class derived from locale::facet and containing a publicly-accessible declaration as follows:*
[Footnote: This is a complete list of requirements; there are no other requirements. Thus, a facet class need not have a public copy constructor, assignment, default constructor, destructor, etc. --- end foonote]
Template parameters in this clause which are required to be facets are those named Facet in declarations. A program that passes a type that is not a facet, as an (explicit or deduced) template parameter to a locale function expecting a facet, is ill-formed.static ::std::locale::id id;
-2- The refs argument to the constructor is used for lifetime management.
-3- Constructors of all facets defined in this clause take such an argument and pass it along to their facet base class constructor. All one-argument constructors defined in this clause are explicit, preventing their participation in automatic conversions.
-4-
For some standard facets a standard
``..._byname''
class, derived from it, implements the virtual function semantics
equivalent to that facet of the locale constructed by
locale(const char*)
with the same name.
Each such facet provides a constructor that takes a
const char*
argument, which names the locale, and a refs
argument, which is passed to the base class constructor.
If there is no
``..._byname''
version of a facet, the base class implements named locale
semantics itself by reference to other facets.
22.1.1.1.3 - Class locale::id [lib.locale.id]
namespace std { class locale::id { public: id(); private: void operator=(const id&); //not defined id(const id&); // not defined }; }
-1- The class locale::id provides identification of a locale facet interfaces, used as an index for lookup and to encapsulate initialization.
-2-
[Note:
Because facets are used by iostreams, potentially while static constructors are
running, their initialization cannot depend on programmed static
initialization.
One initialization strategy is for
locale
to initialize each facet's
id
member the first time an instance of the facet is installed into a locale.
This depends only on static storage being zero before constructors run
(basic.start.init).
--- end note]
22.1.1.2 - locale constructors and destructor [lib.locale.cons]
locale() throw();
-1- Default constructor: a snapshot of the current global locale.
-2- Effects:
Constructs a copy of the argument last passed to
locale::global(locale&),
if it has been called; else, the resulting facets have virtual
function semantics identical to those of
locale::classic().
[Note:
This constructor is commonly used as the default value for arguments
of functions that take a
const locale&
argument.
--- end note]
locale(const locale& other) throw();
-3- Effects:
Constructs a locale which is a copy of other.
const locale& operator=(const locale& other) throw();
-4- Effects: Creates a copy of other, replacing the current value.
-5- Returns:
*this
explicit locale(const char* std_name);
-6- Effects: Constructs a locale using standard C locale names, e.g. "POSIX". The resulting locale implements semantics defined to be associated with that name.
-7- Throws: runtime_error if the argument is not valid, or is null.
-8- Notes:
The set of valid string argument values is "C", "",
and any implementation-defined values.
locale(const locale& other, const char* std_name, category);
-9- Effects: Constructs a locale as a copy of other except for the facets identified by the category argument, which instead implement the same semantics as locale(std_name ).
-10- Throws: runtime_error if the argument is not valid, or is null.
-11- Notes:
The locale has a name if and only if
other
has a name.
template <class Facet> locale(const locale& other, Facet* f);
-12- Effects: Constructs a locale incorporating all facets from the first argument except that of type Facet, and installs the second argument as the remaining facet. If f is null, the resulting object is a copy of other.
-13- Notes:
The resulting locale has no name.
locale(const locale& other, const locale& one, category cats);
-14- Effects: Constructs a locale incorporating all facets from the first argument except those that implement cats, which are instead incorporated from the second argument.
-15- Notes:
The resulting locale has a name if and only if the first two arguments
have names.
~locale() throw();
-16-
A non-virtual destructor that throws no exceptions.
22.1.1.3 - locale members [lib.locale.members]
template <class Facet> locale combine(const locale& other);
-1- Effects: Constructs a locale incorporating all facets from *this except for that one facet of other that is identified by Facet.
-2- Returns: The newly created locale.
-3- Throws: runtime_error if has_facet<Facet>(other) is false.
-4- Notes:
The resulting locale has no name.
basic_string<char> name() const;
-5- Returns:
The name of
*this,
if it has one; otherwise, the string "*".
If
*this
has a name, then
locale(name())
is equivalent to
*this.
Details of
the contents of the resulting string are otherwise implementation-defined.
22.1.1.4 - locale operators [lib.locale.operators]
bool operator==(const locale& other) const;
-1- Returns:
true
if both arguments are the same locale, or one is a copy of the
other, or each has a name and the names are identical;
false
otherwise.
bool operator!=(const locale& other) const;
-2- Returns:
The result of the expression:
!(*this == other)
template <class charT, class Traits, class Allocator>
bool operator()(const basic_string<charT,Traits,Allocator>& s1,
const basic_string<charT,Traits,Allocator>& s2) const;
-3- Effects: Compares two strings according to the collate<charT> facet.
-4- Notes: This member operator template (and therefore locale itself) satisfies requirements for a comparator predicate template argument (clause lib.algorithms) applied to strings.
-5- Returns: The result of the following expression:
use_facet< collate<charT> >(*this).compare (s1.data(), s1.data()+s1.size(), s2.data(), s2.data()+s2.size()) < 0;
-6- [Example: A vector of strings v can be collated according to collation rules in locale loc simply by (lib.alg.sort, lib.vector):
std::sort(v.begin(), v.end(), loc);
static locale global(const locale& loc);
-1- Sets the global locale to its argument.
-2- Effects: Causes future calls to the constructor locale() to return a copy of the argument. If the argument has a name, does
otherwise, the effect on the C locale, if any, is implementation-defined.std::setlocale(LC_ALL, loc.name().c_str());
-3- Returns:
The previous value of
locale().
static const locale& classic();
-4- The "C" locale.
-5- Returns: A locale that implements the classic "C" locale semantics, equivalent to the value locale("C").
-6- Notes:
This locale, its facets, and their member functions, do not change
with time.
22.1.2 - locale globals [lib.locale.global.templates]
template <class Facet> const Facet& use_facet(const locale& loc);
-1- Get a reference to a facet of a locale.
-2- Returns: a reference to the corresponding facet of loc, if present.
-3- Throws: bad_cast if has_facet<Facet>(loc) is false.
-4- Notes:
The reference returned remains valid at least as long as any copy of
loc exists.
template <class Facet> bool has_facet(const locale& loc) throw();
-5- Returns:
true if the facet requested is present in loc; otherwise false
22.1.3 - Convenience interfaces [lib.locale.convenience]
22.1.3.1 - Character classification [lib.classification]
template <class charT> bool isspace (charT c, const locale& loc);
template <class charT> bool isprint (charT c, const locale& loc);
template <class charT> bool iscntrl (charT c, const locale& loc);
template <class charT> bool isupper (charT c, const locale& loc);
template <class charT> bool islower (charT c, const locale& loc);
template <class charT> bool isalpha (charT c, const locale& loc);
template <class charT> bool isdigit (charT c, const locale& loc);
template <class charT> bool ispunct (charT c, const locale& loc);
template <class charT> bool isxdigit(charT c, const locale& loc);
template <class charT> bool isalnum (charT c, const locale& loc);
template <class charT> bool isgraph (charT c, const locale& loc);
-1- Each of these functions isF returns the result of the expression:
where F is the ctype_base::mask value corresponding to that function (lib.category.ctype).*use_facet< ctype<charT> >(loc).is(ctype_base::F, c)
[Footnote: When used in a loop, it is faster to cache the ctype<> facet and use it directly, or use the vector form of ctype<>::is. --- end foonote]
template <class charT> charT toupper(charT c, const locale& loc) const;
-1- Returns:
use_facet<ctype<charT> >(loc).toupper(c).
template <class charT> charT tolower(charT c, const locale& loc) const;
-2- Returns:
use_facet<ctype<charT> >(loc).tolower(c).
22.2 - Standard locale categories [lib.locale.categories]
-1- Each of the standard categories includes a family of facets. Some of these implement formatting or parsing of a datum, for use by standard or users' iostream operators << and >>, as members put() and get(), respectively. Each such member function takes an ios_base& argument whose members flags(), precision(), and width(), specify the format of the corresponding datum. (lib.ios.base). Those functions which need to use other facets call its member getloc() to retrieve the locale imbued there. Formatting facets use the character argument fill to fill out the specified width where necessary.
-2-
The
put()
members make no provision for error reporting.
(Any failures of the
OutputIterator argument must be extracted from the returned iterator.)
The
get()
members take an
ios_base::iostate&
argument whose value they ignore, but set to
ios_base::failbit
in case of a parse error.
22.2.1 - The ctype category [lib.category.ctype]
namespace std { class ctype_base { public: enum mask { //numeric values are for exposition only. space=1<<0, print=1<<1, cntrl=1<<2, upper=1<<3, lower=1<<4, alpha=1<<5, digit=1<<6, punct=1<<7, xdigit=1<<8, alnum=alpha|digit, graph=alnum|punct }; }; }
-1-
The type
mask
is a bitmask type.
22.2.1.1 - Template class ctype [lib.locale.ctype]
template <class charT> class ctype : public locale::facet, public ctype_base { public: typedef charT char_type; explicit ctype(size_t refs = 0);
bool is(mask m, charT c) const; const charT* is(const charT* low, const charT* high, mask* vec) const; const charT* scan_is(mask m, const charT* low, const charT* high) const; const charT* scan_not(mask m, const charT* low, const charT* high) const; charT toupper(charT c) const; const charT* toupper(charT* low, const charT* high) const; charT tolower(charT c) const; const charT* tolower(charT* low, const charT* high) const;
charT widen(char c) const; const char* widen(const char* low, const char* high, charT* to) const; char narrow(charT c, char dfault) const; const charT* narrow(const charT* low, const charT*, char dfault, char* to) const;
static locale::id id;
protected: ~ctype(); //virtual virtual bool do_is(mask m, charT c) const; virtual const charT* do_is(const charT* low, const charT* high, mask* vec) const; virtual const charT* do_scan_is(mask m, const charT* low, const charT* high) const; virtual const charT* do_scan_not(mask m, const charT* low, const charT* high) const; virtual charT do_toupper(charT) const; virtual const charT* do_toupper(charT* low, const charT* high) const; virtual charT do_tolower(charT) const; virtual const charT* do_tolower(charT* low, const charT* high) const; virtual charT do_widen(char) const; virtual const char* do_widen(const char* low, const char* high, charT* dest) const; virtual char do_narrow(charT, char dfault) const; virtual const charT* do_narrow(const charT* low, const charT* high, char dfault, char* dest) const; };
-1- Class ctype encapsulates the C library <cctype> features. istream members are required to use ctype<> for character classing during input parsing.
-2-
The instantiations required in Table ?? (lib.locale.category), namely
ctype<char>
and
ctype<wchar_t>,
implement character classing appropriate
to the implementation's native character set.
22.2.1.1.1 - ctype members [lib.locale.ctype.members]
bool is(mask m, charT c) const;
const charT* is(const charT* low, const charT* high,
mask* vec) const;
-1- Returns:
do_is(m,c)
or
do_is(low,high,vec)
const charT* scan_is(mask m,
const charT* low, const charT* high) const;
-2- Returns:
do_scan_is(m,low,high)
const charT* scan_not(mask m,
const charT* low, const charT* high) const;
-3- Returns:
do_scan_not(m,low,high)
charT toupper(charT) const;
const charT* toupper(charT* low, const charT* high) const;
-4- Returns:
do_toupper(c)
or
do_toupper(low,high)
charT tolower(charT c) const;
const charT* tolower(charT* low, const charT* high) const;
-5- Returns:
do_tolower(c)
or
do_tolower(low,high)
charT widen(char c) const;
const char* widen(const char* low, const char* high, charT* to) const;
-6- Returns:
do_widen(c)
or
do_widen(low,high,to)
char narrow(charT c, char dfault) const;
const charT* narrow(const charT* low, const charT*, char dfault,
char* to) const;
-7- Returns:
do_narrow(c,dfault)
or
do_narrow(low,high,dfault,to)
22.2.1.1.2 - ctype virtual functions [lib.locale.ctype.virtuals]
bool do_is(mask m, charT c) const;
const charT* do_is(const charT* low, const charT* high,
mask* vec) const;
-1- Effects: Classifies a character or sequence of characters. For each argument character, identifies a value M of type ctype_base::mask. The second form identifies a value M of type ctype_base::mask for each *p where (low<=p && p<high), and places it into vec[p-low].
-2- Returns:
The first form returns the result of the expression
(M & m) != 0;
i.e.,
true
if the character has the characteristics specified.
The second form returns high.
const charT* do_scan_is(mask m,
const charT* low, const charT* high) const;
-3- Effects: Locates a character in a buffer that conforms to a classification m.
-4- Returns:
The smallest pointer p in the range
[low, high)
such that
is(*p)
would return
true;
otherwise, returns high.
const charT* do_scan_not(mask m,
const charT* low, const charT* high) const;
-5- Effects: Locates a character in a buffer that fails to conform to a classification m.
-6- Returns:
The smallest pointer p, if any, in the range
[low, high)
such that
is(*p)
would return
false;
otherwise, returns high.
charT do_toupper(charT c) const;
const charT* do_toupper(charT* low, const charT* high) const;
-7- Effects: Converts a character or characters to upper case. The second form replaces each character *p in the range [low, high) for which a corresponding upper-case character exists, with that character.
-8- Returns:
The first form returns the corresponding upper-case character if it
is known to exist, or its argument if not.
The second form returns high.
charT do_tolower(charT c) const;
const charT* do_tolower(charT* low, const charT* high) const;
-9- Effects: Converts a character or characters to lower case. The second form replaces each character *p in the range [low, high) and for which a corresponding lower-case character exists, with that character.
-10- Returns:
The first form returns the corresponding lower-case character if it
is known to exist, or its argument if not.
The second form returns high.
charT do_widen(char c) const;
const char* do_widen(const char* low, const char* high,
charT* dest) const;
-11- Effects: Applies the simplest reasonable transformation from a char value or sequence of char values to the corresponding charT value or values.*
[Footnote: The char argument of do_widen is intended to accept values derived from character literals for conversion the locale's encoding. --- end foonote]The only characters for which unique transformations are required are those in the basic source character set (lex.charset).
[Footnote: In other words, the transformed character is not a member of any character classification that c is not also a member of. --- end foonote]
-12- Returns:
The first form returns the transformed value.
The second form returns high.
char do_narrow(charT c, char dfault) const;
const charT* do_narrow(const charT* low, const charT* high,
char dfault, char* dest) const;
-13- Effects:
Applies the simplest reasonable transformation from a
charT
value or sequence of
charT
values to the corresponding
char
value or values.
For any character c in the basic source character set(lex.charset)
the transformation is such that
do_widen(do_narrow(c),0) == c
is true (unless do_narrow returns dfault). In addition, for any digit character c, the expression (do_narrow(c,dfault)-'0') evaluates to the digit value of the character. The second form transforms each character *p in the range [low, high), placing the result (or dfault if no simple transformation is readly available) in dest[p-low].(is(M,c) || !ctc.is(M, do_narrow(c),dfault) )"
-14- Returns:
The first form returns the transformed value; or dfault
if no mapping is readily available.
The second form returns high.
22.2.1.2 - Template class ctype_byname [lib.locale.ctype.byname]
namespace std { template <class charT> class ctype_byname : public ctype<charT> { public: typedef ctype<charT>::mask mask; explicit ctype_byname(const char*, size_t refs = 0); protected: ~ctype_byname(); //virtual
virtual bool do_is(mask m, charT c) const; virtual const charT* do_is(const charT* low, const charT* high, mask* vec) const; virtual const char* do_scan_is(mask m, const charT* low, const charT* high) const; virtual const char* do_scan_not(mask m, const charT* low, const charT* high) const; virtual charT do_toupper(charT) const; virtual const charT* do_toupper(charT* low, const charT* high) const; virtual charT do_tolower(charT) const; virtual const charT* do_tolower(charT* low, const charT* high) const; virtual charT do_widen(char) const; virtual const char* do_widen(const char* low, const char* high, charT* dest) const; virtual char do_narrow(charT, char dfault) const; virtual const charT* do_narrow(const charT* low, const charT* high, char dfault, char* dest) const; }; }
namespace std { template <> class ctype<char> : public locale::facet, public ctype_base { public: typedef char char_type;
explicit ctype(const mask* tab = 0, bool del = false, size_t refs = 0);
bool is(mask m, char c) const; const char* is(const char* low, const char* high, mask* vec) const; const char* scan_is (mask m, const char* low, const char* high) const; const char* scan_not(mask m, const char* low, const char* high) const;
char toupper(char c) const; const char* toupper(char* low, const char* high) const; char tolower(char c) const; const char* tolower(char* low, const char* high) const;
char widen(char c) const; const char* widen(const char* low, const char* high, char* to) const; char narrow(char c, char dfault) const; const char* narrow(const char* low, const char* high, char dfault, char* to) const;
static locale::id id; static const size_t table_size = IMPLEMENTATION_DEFINED;
protected: const mask* table() const throw(); static const mask* classic_table() throw();
~ctype(); //virtual virtual char do_toupper(char c) const; virtual const char* do_toupper(char* low, const char* high) const; virtual char do_tolower(char c) const; virtual const char* do_tolower(char* low, const char* high) const; virtual char do_widen(char c) const; virtual const char* do_widen(const char* low, const char* high, char* to) const; virtual char do_narrow(char c, char dfault) const; virtual const char* do_narrow(const char* low, const char* high, char dfault, char* to) const; }; }
-1- A specialization ctype<char> is provided so that the member functions on type char can be implemented inline.*
[Footnote: Only the char (not unsigned char and signed char) form is provided. The specialization is specified in the standard, and not left as an implementation detail, because it affects the derivation interface for ctype<char>. --- end foonote]The implementation-defined value of member table_size is at least 256.
~ctype();
-1- Effects:
If the constructor's first argument was nonzero, and its second argument
was true, does
delete [] table().
22.2.1.3.2 - ctype<char> members [lib.facet.ctype.char.members]
-1-
In the following member descriptions, for
unsigned char
values v where (v >= table_size),
table()[v] is assumed to have an
implementation-defined value (possibly different for each
such value v) without performing the array lookup.
explicit ctype(const mask* tbl = 0, bool del = false,
size_t refs = 0);
-2- Precondition: tbl either 0 or an array of at least table_size elements.
-3- Effects:
Passes its refs argument to its base class constructor.
bool is(mask m, char c) const;
const char* is(const char* low, const char* high,
mask* vec) const;
-4- Effects: The second form, for all *p in the range [low, high), assigns vec[p-low] to table()[(unsigned char)*p].
-5- Returns:
The first form returns
table()[(unsigned char)c] & m;
the second form returns high.
const char* scan_is(mask m,
const char* low, const char* high) const;
-6- Returns: The smallest p in the range [low, high) such that
is true.table()[(unsigned char) *p] & m
const char* scan_not(mask m, const char* low, const char* high) const;
-7- Returns: The smallest p in the range [low, high) such that
is false.table()[(unsigned char) *p] & m
char toupper(char c) const; const char* toupper(char* low, const char* high) const;
-8- Returns:
do_toupper(c)
or
do_toupper(low,high)
char tolower(char c) const;
const char* tolower(char* low, const char* high) const;
-9- Returns:
do_tolower(c)
or
do_tolower(low,high)
char widen(char c) const;
const char* widen(const char* low, const char* high,
char* to) const;
-10- Returns:
do_widen(low, high, to).
char narrow(char c, char /*dfault*/) const;
const char* narrow(const char* low, const char* high,
char /*dfault*/, char* to) const;
-11- Returns:
do_narrow(low, high, to).
const mask* table() const throw();
-12- Returns:
The first constructor argument, if it was non-zero, otherwise
classic_table().
22.2.1.3.3 - ctype<char> static members [lib.facet.ctype.char.statics]
static const mask* classic_table() throw();
-1- Returns:
A pointer to the initial element of an array of size
table_size
which represents the classifications of characters in the "C" locale.
22.2.1.3.4 - ctype<char> virtual functions [lib.facet.ctype.char.virtuals]
char do_toupper(char) const; const char* do_toupper(char* low, const char* high) const; char do_tolower(char) const; const char* do_tolower(char* low, const char* high) const;
These functions are described identically as those members of the same name in the ctype class template (lib.locale.ctype.members).virtual char do_widen(char c) const; virtual const char* do_widen(const char* low, const char* high, char* to) const; virtual char do_narrow(char c, char dfault) const; virtual const char* do_narrow(const char* low, const char* high, char dfault, char* to) const;
namespace std { template <> class ctype_byname<char> : public ctype<char> { public: explicit ctype_byname(const char*, size_t refs = 0); protected: ~ctype_byname(); //virtual virtual char do_toupper(char c) const; virtual const char* do_toupper(char* low, const char* high) const; virtual char do_tolower(char c) const; virtual const char* do_tolower(char* low, const char* high) const; virtual char do_widen(char c) const; virtual const char* do_widen(char* low, const char* high, char* to) const; virtual char do_widen(char c) const; virtual const char* do_widen(char* low, const char* high) const; }; }
-1-
22.2.1.5 - Template class codecvt [lib.locale.codecvt]
namespace std { class codecvt_base { public: enum result { ok, partial, error, noconv }; }; template <class internT, class externT, class stateT> class codecvt : public locale::facet, public codecvt_base { public: typedef internT intern_type; typedef externT extern_type; typedef stateT state_type;
explicit codecvt(size_t refs = 0)
result out(stateT& state, const internT* from, const internT* from_end, const internT*& from_next, externT* to, externT* to_limit, externT*& to_next) const; result unshift(stateT& state, externT* to, externT* to_limit, externT*& to_next) const; result in(stateT& state, const externT* from, const externT* from_end, const externT*& from_next, internT* to, internT* to_limit, internT*& to_next) const; int encoding() const throw(); bool always_noconv() const throw(); int length(const stateT&, const externT* from, const externT* end, size_t max) const; int max_length() const throw();
static locale::id id;
protected: ~codecvt(); //virtual virtual result do_out(stateT& state, const internT* from, const internT* from_end, const internT*& from_next, externT* to, externT* to_limit, externT*& to_next) const; virtual result do_in(stateT& state, const externT* from, const externT* from_end, const externT*& from_next, internT* to, internT* to_limit, internT*& to_next) const; virtual result do_unshift(stateT& state, externT* to, externT* to_limit, externT*& to_next) const; virtual int do_encoding() const throw(); virtual bool do_always_noconv() const throw(); virtual int do_length(const stateT&, const externT* from, const externT* end, size_t max) const; virtual int do_max_length() const throw(); }; }
-1- The class codecvt<internT,externT,stateT> is for use when converting from one codeset to another, such as from wide characters to multibyte characters, between wide character encodings such as Unicode and EUC.
-2- The stateT argument selects the pair of codesets being mapped between.
-3-
The instantiations required in the Table ?? (lib.locale.category), namely
codecvt<wchar_t,char,mbstate_t>
and
codecvt<char,char,mbstate_t>,
convert the implementation-defined native character set.
codecvt<char,char,mbstate_t>
implements a degenerate conversion;
it does not convert at all.
codecvt<wchar_t,char,mbstate_t>
converts between the native character sets for tiny and wide characters.
Instantiations on
mbstate_t
perform conversion between encodings known to the library implementor.
Other encodings can be converted by specializing on a user-defined
stateT
type.
The
stateT
object can contain any state that is useful to communicate to or from
the specialized
do_convert
member.
22.2.1.5.1 - codecvt members [lib.locale.codecvt.members]
result out(stateT& state,
const internT* from, const internT* from_end, const internT*& from_next,
externT* to, externT* to_limit, externT*& to_next) const;
-1- Returns:
do_out(state, from, from_end, from_next, to,to_limit, to_next)
result unshift(stateT& state,
externT* to, externT* to_limit, externT*& to_next) const;
-2- Returns:
do_unshift(state, to, to_limit, to_next)
result in(stateT& state,
const externT* from, const externT* from_end, const externT*& from_next,
internT* to, internT* to_limit, internT*& to_next) const;
-3- Returns:
do_in(state, from,from_end,from_next, to,to_limit,to_next)
int encoding() const throw();
-4- Returns:
do_encoding()
bool always_noconv() const throw();
-5- Returns:
do_always_noconv()
int length(stateT& state, const externT* from, const externT* from_end,
size_t max) const;
-6- Returns:
do_length(state, from,from_end,max)
int max_length() const throw();
-7- Returns:
do_max_length()
22.2.1.5.2 - codecvt virtual functions [lib.locale.codecvt.virtuals]
result do_out(stateT& state,
const internT* from, const internT* from_end, const internT*& from_next,
externT* to, externT* to_limit, externT*& to_next) const;
result do_in(stateT& state,
const externT* from, const externT* from_end, const externT*& from_next,
internT* to, internT* to_limit, internT*& to_next) const;
-1- Preconditions: (from<=from_end && to<=to_end) well-defined and true; state initialized, if at the beginning of a sequence, or else equal to the result of converting the preceding characters in the sequence.
-2- Effects:
Translates characters in the source range
[from,from_end),
placing the results in sequential positions starting at destination to.
Converts no more than
(from_end-from)
source elements, and
stores no more than
(to_limit-to)
destination elements.
Stops if it encounters a character it cannot convert.
It always leaves the from_next and to_next pointers
pointing one beyond the last element successfully converted.
[Note:
If no translation is needed (returns
noconv),
sets to_next equal to argument to, and from_next
equal to argument from.
--- end note]
-3- Notes:
Its operations on state are unspecified.
[Note:
This argument can be used, for example, to maintain
shift state, to specify conversion options (such as count only), or to
identify a cache of seek offsets.
--- end note]
-4- Returns: An enumeration value, as summarized in Table ??:
Value | Meaning |
ok | completed the conversion |
partial | not all source characters converted |
error | encountered a from_type character it could not convert |
noconv | no conversion was needed |
A return value of
partial,
if
(from_next==from_end),
indicates that either the destination sequence has not absorbed all the
available destination elements, or that additional source elements are
needed before another destination element can be produced.
result do_unshift(stateT& state,
externT* to, externT* to_limit, externT*& to_next) const;
-5- Effects Places characters starting at to that should be appended to terminate a sequence when the current stateT is given by state.*
[Footnote: Typically these will be characters to return the state to stateT() --- end foonote]The instantiations required in Table ?? (lib.locale.category), namely codecvt<wchar_t,char,mbstate_t> and codecvt<char,char,mbstate_t>, store no characters. Stores no more than (to_limit-to) destination elements. It always leaves the to_next pointer pointing one beyond the last element successfully stored.
-6- Returns An enumeration value, as summarized in Table ??:
Value | Meaning |
ok | completed the sequence |
partial | more characters need to be supplied to complete termination |
error | state has invalid value. |
noconv | no termination is needed for this state_type |
codecvt<char,char,mbstate_t>,
returns
noconv.
int do_encoding() const throw();
-7- Returns: -1 if the encoding of the externT sequence is state-dependent; else the constant number of externT characters needed to produce an internal character; or 0 if this number is not a constant*.
[Footnote: If encoding() yields -1, then more than max_length() externT elements may be consumed when producing a single internT character, and additional externT elements may appear at the end of a sequence after those that yield the final internT character. --- end foonote]
bool do_always_noconv() const throw();
-8- Returns:
true
if
do_convert()
returns
noconv
for all valid argument values.
codecvt<char,char,mbstate_t>
returns
true.
int do_length(stateT& state, const externT* from, const externT* from_end,
size_t max) const;
-9- Preconditions: (from<=from_end) well-defined and true; state initialized, if at the beginning of a sequence, or else equal to the result of converting the preceding characters in the sequence.
-10- Returns:
(from_next-from)
where
from_next
is the largest value in the range
[from,from_end]
such that the sequence of values in the range
[from,from_next)
represents
max
or fewer valid complete characters of type
internT.
The instantiations required in Table ?? (lib.locale.category), namely
codecvt<wchar_t, char, mbstate_t>
and
codecvt<char, char, mbstate_t>,
return the lesser of
max
and
(from_end-from).
int do_max_length() const throw();
-11- Returns:
The maximum value that
1)do_length(state,from,nfrom_end,
can return for any valid range
[from,from_end)
and
stateT
value
state.
codecvt<char, char, mbstate_t>
returns 1.
22.2.1.6 - Template class codecvt_byname [lib.locale.codecvt.byname]
namespace std { template <class internT, class externT, class stateT> class codecvt_byname : public codecvt<internT, externT, stateT> { public: explicit codecvt_byname(const char*, size_t refs = 0); protected: ~codecvt_byname(); //virtual virtual result do_out(stateT& state, const internT* from, const internT* from_end, const internT*& from_next, externT* to, externT* to_limit, externT*& to_next) const; virtual result do_in(stateT& state, const externT* from, const externT* from_end, const externT*& from_next, internT* to, internT* to_limit, internT*& to_next) const; virtual result do_unshift(stateT& state, externT* to, externT* to_limit, externT*& to_next) const; virtual int do_encoding() const throw(); virtual bool do_always_noconv() const throw(); virtual int do_length(const stateT&, const externT* from, const externT* end, size_t max) const; virtual result do_unshift(stateT& state, externT* to, externT* to_limit, externT*& to_next) const; virtual int do_max_length() const throw(); }; }
-1- The classes num_get<> and num_put<> handle numeric formatting and parsing. Virtual functions are provided for several numeric types. Implementations may (but are not required to) delegate extraction of smaller types to extractors for larger types.*
[Footnote: Parsing "-1" correctly into (e.g.) an unsigned short requires that the corresponding member get() at least extract the sign before delegating. --- end foonote]
-2- All specifications of member functions for num_put and num_get in the subclauses of lib.category.numeric only apply to the instantiations required in Tables ?? and ?? (lib.locale.category), namely num_get<char>, num_get<wchar_t>, num_get<C,InputIterator>, num_put<char>, num_put<wchar_t>, and num_put<C,OutputIterator>. These instantiations refer to the ios_base& argument for formatting specifications (lib.locale.categories), and to its imbued locale for the numpunct<> facet to identify all numeric punctuation preferences, and also for the ctype<> facet to perform character classification.
-3-
Extractor and inserter members of the standard iostreams use
num_get<>
and
num_put<>
member functions for formatting and parsing numeric values
(lib.istream.formatted.reqmts, lib.ostream.formatted.reqmts).
22.2.2.1 - Template class num_get [lib.locale.num.get]
namespace std { template <class charT, class InputIterator = istreambuf_iterator<charT> > class num_get : public locale::facet { public: typedef charT char_type; typedef InputIterator iter_type;
explicit num_get(size_t refs = 0);
iter_type get(iter_type in, iter_type end, ios_base&, ios_base::iostate& err, bool& v) const; iter_type get(iter_type in, iter_type end, ios_base& , ios_base::iostate& err, long& v) const; iter_type get(iter_type in, iter_type end, ios_base&, ios_base::iostate& err, unsigned short& v) const; iter_type get(iter_type in, iter_type end, ios_base&, ios_base::iostate& err, unsigned int& v) const; iter_type get(iter_type in, iter_type end, ios_base&, ios_base::iostate& err, unsigned long& v) const; iter_type get(iter_type in, iter_type end, ios_base&, ios_base::iostate& err, float& v) const; iter_type get(iter_type in, iter_type end, ios_base&, ios_base::iostate& err, double& v) const; iter_type get(iter_type in, iter_type end, ios_base&, ios_base::iostate& err, long double& v) const; iter_type get(iter_type in, iter_type end, ios_base&, ios_base::iostate& err, void*& v) const;
static locale::id id;
protected: ~num_get(); //virtual virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, bool& v) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, long& v) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, unsigned short& v) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, unsigned int& v) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, unsigned long& v) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, float& v) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, double& v) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, long double& v) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate& err, void*& v) const; }; }
-1-
The facet
num_get
is used to parse numeric values from an input sequence such as an istream.
22.2.2.1.1 - num_get members [lib.facet.num.get.members]
iter_type get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, long& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned short& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned int& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned long& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, short& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, double& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, long double& val) const;
iter_type get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, void*& val) const;
-1- Returns:
do_get(in, end, str, err, val).
22.2.2.1.2 - num_get virtual functions [lib.facet.num.get.virtuals]
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, long& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned short& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned int& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned long& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, float& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, double& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, long double& val) const;
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, void*& val) const;
-1- Effects: Reads characters from in, interpreting them according to str.flags(), use_facet< ctype<charT> >(loc), and use_facet< numpunct<charT> >(loc), where loc is str.getloc(). If an error occurs, val is unchanged; otherwise it is set to the resulting value.
-2- The details of this operation occur in three stages
-3- Stage 1: The function initializes local variables via
fmtflags flags = str .flags(); fmtflags basefield = (flags & ios_base::basefield); fmtflags uppercase = (flags & ios_base::uppercase); fmtflags boolalpha = (flags & ios_base::boolalpha);
-4- For conversion to an integral type, the function determines the integral conversion specifier as indicated in Table ??. The table is ordered. That is, the first line whose condition is true applies.
State | stdio equivalent |
basefield == oct | %o |
basefield == hex | %X |
basefield == 0 | %i |
signed integral type | %d |
unsigned integral type | %u |
-5- For conversions to a floating type the specifier is %g.
-6- For conversions to void* the specifier is %p.
-7- A length specifier is added to the conversion specification, if needed, as indicated in Table ??.
type | length modifier |
short | h |
unsigned short | h |
long | l |
unsigned long | l |
long double | L |
-8- Stage 2: If in==end then stage 2 terminates. Otherwise a charT is taken from in and local variables are initialized as if by
where the values src and atoms are defined as if by:char_type ct = *in ; char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms]; if ( ct == use_facet<numpunct<charT> >(loc).decimal_point() ) c = '.'; bool discard = ( ct == use_facet<numpunct<charT> >(loc).thousands_sep() && use_facet<numpunct<charT> >(loc).grouping().length() != 0 );
for this value of loc.static const char src[] = "0123456789abcdefABCDEF+-"; char_type atoms[sizeof(src)]; use_facet<ctype<charT> >(loc).widen(src, src + sizeof(src), atoms);
-9- If discard is true then the position of the character is remembered, but the character is otherwise ignored. If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by stage 1. If so it is accumulated.
-10- If the character is either discarded or accumulated then in is advanced by ++in and processing returns to the beginning of stage 2.
-11- Stage 3: The result of stage 2 processing can be one of
-12- Digit grouping is checked. That is, the positions of discarded separators is examined for consistency with use_facet<numpunct<charT> >(loc).grouping(). If they are not consistent then ios_base::failbit is assigned to err.
-13-
In any case, if stage 2 processing was terminated by the test for
in==end
then
err |=ios_base::eofbit
is performed.
iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, bool& val) const;
-14- Effects: If (str.flags()&&ios_base::boolalpha)==0 then input proceeds as it would for a long except that if a value is being stored into val, the value is determined according to the following: If the value to be stored is 0 then false is stored. If the value is 1 then true is stored. Otherwise err|=ios_base::failbit is performed and no value is stored.
-15- Otherwise a target string to be matched is determined by calling either use_facet<ctype<charT> >(loc).truename() or use_facet<ctype<charT> >(loc).falsename() depending on whether val is true or false (respectively).
-16- As long as in!=end and characters continue to match the target string charT's are obtained by doing *in++. A value is assigned to err as follows
-17- Returns:
in.
22.2.2.2 - Template class num_put [lib.locale.nm.put]
namespace std { template <class charT, class OutputIterator = ostreambuf_iterator<charT> > class num_put : public locale::facet { public: typedef charT char_type; typedef OutputIterator iter_type;
explicit num_put(size_t refs = 0);
iter_type put(iter_type s, ios_base& f, char_type fill, bool v) const; iter_type put(iter_type s, ios_base& f, char_type fill, long v) const; iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long v) const; iter_type put(iter_type s, ios_base& f, char_type fill, double v) const; iter_type put(iter_type s, ios_base& f, char_type fill, long double v) const; iter_type put(iter_type s, ios_base& f, char_type fill, const void* v) const;
static locale::id id;
protected: ~num_put(); //virtual virtual iter_type do_put(iter_type, ios_base&, char_type fill, bool v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, long v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, double v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, long double v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, const void* v) const; }; }
-1-
The facet
num_put
is used to format numeric values to a character sequence such as an ostream.
22.2.2.2.1 - num_put members [lib.facet.num.put.members]
iter_type put(iter_type out, ios_base& str, char_type fill,
bool val) const;
iter_type put(iter_type out, ios_base& str, char_type fill,
long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill,
unsigned long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill,
double val) const;
iter_type put(iter_type out, ios_base& str, char_type fill,
long double val) const;
iter_type put(iter_type out, ios_base& str, char_type fill,
const void* val) const;
-1- Returns:
do_put(out, str, fill, val).
22.2.2.2.2 - num_put virtual functions [lib.facet.num.put.virtuals]
iter_type do_put(iter_type out, ios_base& str, char_type fill,
bool val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill,
long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill,
unsigned long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill,
double val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill,
long double val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill,
const void* val) const;
-1- Effects: Writes characters to the sequence out, formatting val as desired. In the following description, a local variable initialized with
locale loc = str.getloc();
-2- The details of this operation occur in several stages:
assuming that the current locale is the "C" locale.printf( spec, val )
-3- Detailed descriptions of each stage follow.
-4- Returns: out.
-5- Stage 1: The first action of stage 1 is to determine a conversion specifier. The tables that describe this determination use the following local variables
fmtflags flags = str.flags() ; fmtflags basefield = (flags & (ios_base::basefield)); fmtflags uppercase = (flags & (ios_base::uppercase)); fmtflags floatfield = (flags & (ios_base::floatfield)); fmtflags showpos = (flags & (ios_base::showpos)); fmtflags showbase = (flags & (ios_base::showbase));
-6- All tables used in describing stage 1 are ordered. That is, the first line whose condition is true applies. A line without a condition is the default behavior when none of the earlier lines apply.
-7- For conversion from an integral type other than a character type, the function determines the integral conversion specifier as indicated in Table ??.
State | stdio equivalent |
basefield == ios_base::oct | %o |
(basefield == ios_base::hex) && !uppercase | %x |
(basefield == ios_base::hex) | %X |
for a signed integral type | %d |
for an unsigned integral type | %u |
-8- For conversion from a floating-point type, the function determines the floating-point conversion specifier as indicated in Table ??:
State | stdio equivalent |
floatfield == ios_base::fixed | %f |
floatfield == ios_base::scientific && !uppercase | %e |
floatfield == ios_base::scientific | %E |
!uppercase | %g |
otherwise | %G |
-9- For conversions from an integral or floating type a length modifier is added to the conversion specifier as indicated in Table ??.
type | length modifier |
long | l |
unsigned long | l |
long double | L |
otherwise | none |
-10- The conversion specifier has the following optional additional qualifiers prepended as indicated in Table ??:
Type(s) | State | stdio equivalent |
an integral type | flags & showpos | + |
flags & showbase | # | |
a floating-point type | flags & showpos | + |
flags & showpoint | # |
-11- For conversion from a floating-point type, if (flags & fixed) != 0 or if str.precision() > 0, then str.precision() is specified in the conversion specification.
-12- For conversion from void* the specifier is %p.
-13- The representations at the end of stage 1 consists of the char's that would be printed by a call of printf( s , val ) where s is the conversion specifier determined above.
-14- Stage 2: Any character c other than a decimal point(.) is converted to a charT via use_facet<ctype<charT> >(loc).widen( c )
-15- A local variable punct is initialized via
numpunct<charT> punct = use_facet< numpunct<charT> >(str.getloc())
-16- For integral types, punct.thousands_sep() characters are inserted into the sequence as determined by the value returned by punct.do_grouping() using the method described in lib.facet.numpunct.virtuals
-17- Decimal point characters(.) are replaced by punct.decimal_point()
-18- Stage 3: A local variable is initialized as
fmtflags adjustfield= (flags & (ios_base::adjustfield));
-19- The location of any padding* is determined according to Table ??:
[Footnote: The conversion specification #o generates a leading 0 which is not a padding character. --- end foonote]
State | Location |
adjustfield == ios_base::left | pad after |
adjustfield == ios_base::right | pad before |
adjustfield == internal and a sign occurs in the representation | pad after the sign |
adjustfield == internal and representation after stage 1 began with 0x 1or 0X | pad after x or X |
otherwise | pad before |
-1-
numpunct<>
specifies numeric punctuation.
The instantiations required in Table ?? (lib.locale.category), namely
numpunct<wchar_t>
and
numpunct<char>,
provide classic
``C''
numeric formats,
i.e. they contain information equivalent to that contained in the
``C''
locale or their wide character counterparts as if obtained by
a call to
widen.
-2-
The syntax for number formats is as follows, where
digit
represents the radix set specified by the
fmtflags
argument value,
whitespace
is as determined by the facet
ctype<charT>
(lib.locale.ctype), and
thousands-sep
and
decimal-point
are the results of corresponding
numpunct<charT>
members.
Integer values have the format:
-1- Returns:
do_decimal_point()
-2- Returns:
do_thousands_sep()
-3- Returns:
do_grouping()
-4- Returns:
do_truename()
or
do_falsename(),
respectively.
-1- Returns:
A character for use as the decimal radix separator.
The required instantiations return '.' or L'.'.
-2- Returns:
A character for use as the digit group separator.
The required instantiations return ',' or L','.
-3- Returns:
A basic_string<char> vec used as a vector of integer values,
in which each element
vec[i]
represents the number of digits*
-4- Returns:
A string representing the name of the boolean value
true
or
false,
respectively.
-1-
The class
collate<charT>
provides features for use in the
collation (comparison) and hashing of strings.
A locale member function template,
operator(),
uses the collate facet to allow a locale to act directly as the predicate
argument for standard algorithms (clause lib.algorithms) and containers operating on strings.
The instantiations required in Table ?? (lib.locale.category), namely
collate<char>
and
collate<wchar_t>,
apply lexicographic ordering (lib.alg.lex.comparison).
-2-
Each function compares a string of characters
*p
in the range
[low,high).
-1- Returns:
do_compare(low1, high1, low2, high2)
-2- Returns:
do_transform(low, high)
-3- Returns:
do_hash(low, high)
-1- Returns:
1
if the first string is greater than the second,
-1
if less, zero otherwise.
The instantiations required in the Table ?? (lib.locale.category), namely
collate<char>
and
collate<wchar_t>,
implement
a lexicographical comparison (lib.alg.lex.comparison).
-2- Returns:
A
basic_string<charT>
value that, compared lexicographically with the result of calling
transform()
on another string, yields the same result as calling
do_compare()
on the same two strings.*
-3- Returns:
An integer value equal to the result of calling
hash()
on any other string for which
do_compare()
returns 0 (equal) when passed the two strings.
[Note:
The probability that the result equals that for another string which does
not compare equal should be very small, approaching
(1.0/numeric_limits<unsigned long>::max()).
-1-
Templates
time_get<charT,InputIterator>
and
time_put<charT,OutputIterator>
provide date and time formatting and parsing.
All specifications of member functions for
time_put
and
time_get
in the subclauses of lib.category.time only apply to the
instantiations required in Tables ?? and ?? (lib.locale.category).
Their members use their
ios_base&,
ios_base::iostate&,
and
fill
arguments as described in (lib.locale.categories), and the
ctype<>
facet, to determine formatting details.
-1-
time_get
is used to
parse a character sequence, extracting components of a time or date
into a
struct tm
record.
Each
get
member parses a format as produced by a corresponding format specifier to
time_put<>::put.
If the sequence being parsed matches the correct format, the corresponding
members of the
struct tm
argument are set to the values used to produce the sequence; otherwise
either an error is reported or unspecified values are assigned.*
-1- Returns:
do_date_order()
-2- Returns:
do_get_time(s, end, str, err, t)
-3- Returns:
do_get_date(s, end, str, err, t)
-4- Returns:
do_get_weekday(s, end, str, err, t)
or
do_get_monthname(s, end, str, err, t)
-5- Returns:
do_get_year(s, end, str, err, t)
-1- Returns:
An enumeration value indicating the preferred order of components for
those date formats that are composed of day, month, and year.*
-2- Effects:
Reads characters starting at s
until it has extracted those
struct tm
members, and remaining format characters, used by
time_put<>::put
to produce the format specified by
'X',
or until it encounters an error or end of sequence.
-3- Returns:
An iterator pointing immediately beyond the last character recognized
as possibly part of a valid time.
-4- Effects:
Reads characters starting at s
until it has extracted those
struct tm
members, and remaining format characters, used by
time_put<>::put
to produce the format specified by
'x',
or until it encounters an error.
-5- Returns:
An iterator pointing immediately beyond the last character recognized
as possibly part of a valid date.
-6- Effects:
Reads characters starting at s
until it has extracted the (perhaps abbreviated) name of a weekday or month.
If it finds an abbreviation that is followed by characters that could
match a full name, it continues reading until it matches the full name or
fails.
It sets the appropriate
struct tm
member accordingly.
-7- Returns:
An iterator pointing immediately beyond the last character recognized
as part of a valid name.
-8- Effects:
Reads characters starting at s
until it has extracted an unambiguous year identifier.
It is
implementation-defined whether two-digit year numbers are accepted,
and (if so) what century they are assumed to lie in.
Sets the
t->tm_year
member accordingly.
-9- Returns:
An iterator pointing immediately beyond the last character recognized
as part of a valid year identifier.
-1- Effects:
The first form steps through the sequence from
pattern
to
end,
identifying characters that are part of a format sequence.
Each character that is not part of a format sequence is written to
s
immediately, and each format sequence, as it is identified, results in
a call to
do_put;
thus, format elements and other characters are interleaved in the output
in the order in which they appear in the pattern.
Format sequences are identified by converting each character
c
to a
char
value as if by
ct.narrow(c, 0),
where
ct
is a reference to
ctype<charT>
obtained from
str.getloc().
The first character of each sequence is equal to
'%',
followed by an optional modifier character
mod*
-2-
The second form calls
do_put(s, str, fill, t, format, modifier).
-3- Returns:
An iterator pointing immediately after the last character produced.
-1- Effects:
Formats the contents of the parameter t
into characters placed on the output sequence s.
Formatting is controlled by the parameters format and modifier,
interpreted identically as the format specifiers in the string
argument to the standard library function
strftime().*
-2- Returns:
An iterator pointing immediately after the last character produced.
-1-
These templates handle monetary formats.
A template parameter indicates whether
local or international monetary formats are to be used.
-2-
All specifications of member functions for
money_put
and
money_get
in the subclauses of lib.category.monetary only apply to the
instantiations required in Tables ?? and ?? (lib.locale.category).
Their members use their
ios_base&,
ios_base::iostate&,
and
fill
arguments as described in (lib.locale.categories), and the
moneypunct<>
and
ctype<>
facets, to determine formatting details.
-1- Returns:
do_get(s, end, intl, f, err, quant)
-1- Effects:
Reads characters from
s
to parse and construct a monetary value according to the
format specified by a
moneypunct<charT, Intl>
facet reference
mp
and the character mapping specified by a
ctype<charT>
facet reference
ct
obtained from the locale returned by
str.getloc(),
and
str.flags().
If a valid sequence is recognized,
does not change err;
otherwise, sets err to
(err|str.failbit),
or
(err|str.failbit|str.eofbit)
if no more characters are available,
and does not change units or digits.
Uses the pattern returned by
mp.neg_format()
to parse all values.
The result is returned as an integral value stored in
units
or as a sequence of digits possibly preceded by a minus sign
(as produced by
ct.widen(c)
where
c
is
'-'
or in the range from
'0'
through
'9',
inclusive)
stored in
digits.
[Example:
The sequence
$1,056.23
in a common United States locale would yield, for
units,
105623,
or, for
digits,
"105623".
-2-
Where
space
or
none
appears in the format pattern, except at the end, optional white space
(as recognized by
ct.is)
is consumed after any required space.
If
(str.flags() & str.showbase)
is false, the currency symbol is optional and is consumed only if
other characters are needed to complete the format;
otherwise, the currency symbol is required.
-3-
If the first character (if any) in the string
pos
returned by
mp.positive_sign()
or the string
neg
returned by
mp.negative_sign()
is recognized in the position indicated by
sign
in the format pattern, it is consumed and any remaining characters
in the string are required after all the other format components.
[Example:
If
showbase
is off, then for a
neg
value of "()" and a currency symbol of "L",
in "(100 L)" the "L" is consumed;
but if
neg
is "-", the "L" in "-100 L" is not consumed.
]
If
pos
or
neg
is empty, the sign component is optional, and if no sign is
detected, the result is given the sign that corresponds to the source
of the empty string.
Otherwise, the character in the indicated position must
match the first character of
pos
or
net,
and the result is given the corresponding sign.
If the first character of
pos
is equal to the first character of
neg,
or if both strings are empty, the result is given a positive sign.
-4-
Digits in the numeric monetary component are extracted and placed in
digits,
or into a character buffer
buf1
for conversion to produce a value for
units,
in the order in which they appear,
preceded by a minus sign if and only if the result is negative.
The value
units
is produced as if by*
-5- Returns:
An iterator pointing immediately beyond the last character recognized
as part of a valid monetary quantity.
-1- Returns:
do_put(s, intl, f, loc, quant)
-1- Effects:
Writes characters to
s
according to the format specified by a
moneypunct<charT, Intl>
facet reference
mp
and the character mapping specified by a
ctype<charT>
facet reference
ct
obtained from the locale returned by
str.getloc(),
and
str.flags().
The argument
units
is transformed into a sequence of wide characters as if by
-2- Notes:
The currency symbol is generated if and only if
(str.flags() & str.showbase)
is nonzero.
If the number of characters generated for the specified format is less than the value
returned by
str.width()
on entry to the function, then copies of
fill
are inserted as necessary to pad to the specified width.
For the value
af
equal to
(str.flags() & str.adjustfield),
if
(af == str.internal)
is true, the fill characters are placed where
none
or
space
appears in the formatting pattern; otherwise if
(af == str.left)
is true, they are placed after the other characters;
otherwise, they are placed before the other characters.
[Note:
It is possible, with some combinations of format patterns and flag values,
to produce output that cannot be parsed using
num_get<>::get.
-3- Returns:
An iterator pointing immediately after the last character produced.
-1-
The
moneypunct<>
facet defines monetary formatting parameters used by
money_get<>
and
money_put<>.
A monetary format is a sequence of four components,
specified by a
pattern
value
p,
such that the
part
value
static_cast<part>(p.field[i])
determines the
ith
component of the format*
-2-
Where
none
or
space
appears, white space is permitted in the format,
except where
none
appears at the end, in which case no white space is permitted.
The value
space
indicates that at least one space is required at that position.
Where
symbol
appears, the sequence of characters returned by
curr_symbol()
is permitted, and can be required.
Where
sign
appears, the first (if any) of the sequence of characters returned by
positive_sign()
or
negative_sign()
(respectively as the monetary value is non-negative or negative) is required.
Any remaining characters of the sign sequence are required after all
other format components.
Where
value
appears, the absolute numeric monetary value is required.
-3-
The format of the numeric monetary value is a decimal number:
-4-
The placement of thousands-separator characters (if any)
is determined by the value returned by
grouping(),
defined identically as the member
numpunct<>::do_grouping().
-1-
Each of these functions F
returns the result of calling the corresponding
virtual member function
do_F().
-1- Returns:
The radix separator to use in case
do_frac_digits()
is greater than zero.*
-2- Returns:
The digit group separator to use in case
do_grouping()
specifies a digit grouping pattern.*
-3- Returns:
A pattern defined identically as the result of
numpunct<charT>::do_grouping().*
-4- Returns:
A string to use as the currency identifier symbol.*
-5- Returns:
do_positive_sign()
returns the string to use to indicate a
positive monetary value;*
-6- Returns:
The number of digits after the decimal radix separator, if any.*
-7- Returns:
The instantiations required in Table ?? (lib.locale.category), namely
moneypunct<char>,
moneypunct<wchar_t>,
moneypunct<char,true>,
and
moneypunct<wchar_t,true>,
return an object of type
pattern
initialized to
{ symbol, sign, none, value }.*
-1-
Class
messages<charT>
implements retrieval of strings from message catalogs.
-1-
Values of type
messages_base::catalog
usable as arguments to members
get
and
close
can be obtained only by calling member
open.
-1- Returns:
do_open(name, loc).
-2- Returns:
do_get(cat, set, msgid, dfault).
-3- Effects:
Calls
do_close(cat).
-1- Returns:
A value that may be passed to
get()
to retrieve a message, from the message catalog identified by the string
name according to an implementation-defined mapping.
The result can be used until it is passed to
close().
-2- Notes:
The locale argument loc
is used for character set code conversion when retrieving
messages, if needed.
-3- Requires:
A catalog cat obtained from
open()
and not yet closed.
-4- Returns:
A message identified by arguments set, msgid, and dfault,
according to an implementation-defined mapping.
If no such message can be found, returns dfault.
-5- Requires:
A catalog cat obtained from
open()
and not yet closed.
-6- Effects:
Releases unspecified resources associated with cat.
-7- Notes:
The limit on such resources, if any, is implementation-defined.
-1-
A C++ program may define facets to be added to a locale and used identically as
the built-in facets.
To create a new facet interface, C++ programs simply derive from
locale::facet
a class containing a static member:
static locale::id id.
-2-
[Note:
The locale member function templates verify its type and storage class.
-3-
This initialization/identification system depends only on the
initialization to 0 of static objects, before static constructors
are called.
When an instance of a facet is installed in a locale,
the locale checks whether an id has been assigned, and if not,
assigns one.
Before this occurs, any attempted
use
of its interface causes the
bad_cast
exception to be thrown.
-4-
[Example:
Traditional global localization is still easy:
-5-
[Example:
Greater flexibility is possible:
-6-
This can be important even for simple programs, which may need to
write a data file in a fixed format, regardless of a user's preference.
-7-
[Example:
Here is an example of the use of locales in a library interface.
-8-
The first is as a default argument in
Date::asString(),
where the
default is the global (presumably user-preferred) locale.
-9-
The second is in the operators
<<
and
>>,
where a locale ``hitchhikes''
on another object, in this case a stream, to the point where it
is needed.
-10-
A locale object may be extended with a new facet simply by constructing
it with an instance of a class derived from
locale::facet.
The only member a C++ program must define is the static member
id,
which identifies your class interface as a new facet.
-11-
[Example:
Classifying Japanese characters:
-12-
The new facet is used exactly like the built-in facets.
-13-
[Example:
Replacing an existing facet is even easier.
Here we do not define a member
id
because we are reusing the
numpunct<charT>
facet interface:
-1-
Header
<clocale>
(Table ??):
-2-
The contents are the same as the Standard C library header
<locale.h>.
See also
ISO C clause 7.4.
*out++ = c
iter_type put(iter_type out, ios_base& str, char_type fill,
bool val) const;
Otherwise do
out = do_put(out , str , fill , (int)val )
and then insert the characters of s into out.
out.
string_type s =
val ? use_facet<ctype<charT> >(loc).truename()
: use_facet<ctype<charT> >(loc).falsename() ;
22.2.3 - The numeric punctuation facet [lib.facet.numpunct]
22.2.3.1 - Template class numpunct [lib.locale.numpunct]
namespace std {
template <class charT>
class numpunct : public locale::facet {
public:
typedef charT char_type;
typedef basic_string<charT> string_type;
explicit numpunct(size_t refs = 0);
char_type decimal_point() const;
char_type thousands_sep() const;
string grouping() const;
string_type truename() const;
string_type falsename() const;
static locale::id id;
protected:
~numpunct(); //
virtual
virtual char_type do_decimal_point() const;
virtual char_type do_thousands_sep() const;
virtual string do_grouping() const;
virtual string_type do_truename() const; // for bool
virtual string_type do_falsename() const; // for bool
};
}
and floating-point values have:
integer ::= [sign] units
sign ::= plusminus [whitespace]
plusminus ::= '+' | '-'
units ::= digits [thousands-sep units]
digits ::= digit [digits]
where the number of digits between
thousands-seps
is as specified by
do_grouping().
For parsing, if the
digits
portion contains no thousands-separators, no grouping constraint
is applied.
floatval ::= [sign] units [decimal-point [digits]] [e [sign] digits] |
[sign] decimal-point digits [e [sign] digits]
e ::= 'e' | 'E'
22.2.3.1.1 - numpunct members [lib.facet.numpunct.members]
char_type decimal_point() const;
char_type thousands_sep() const;
string grouping() const;
string_type truename() const;
string_type falsename() const;
22.2.3.1.2 - numpunct virtual functions [lib.facet.numpunct.virtuals]
char_type do_decimal_point() const;
string_type do_thousands_sep() const;
string do_grouping() const;
[Footnote:
Thus, the string "\003" specifies groups of 3 digits each, and
"3" probably indicates groups of 51 (!) digits each,
because 51 is the ASCII value of "3".
--- end foonote]
in the group at position i, starting with position 0 as the
rightmost group.
If
vec.size() <= i,
the number is the same as group
(i-1);
if
(i<0 || vec[i]<=0 || vec[i]==CHAR_MAX),
the size of the digit group is unlimited.
The required instantiations return the empty string, indicating
no grouping.
string_type do_truename() const;
string_type do_falsename() const;
In the base class implementation these names are
"true" and "false", or L"true" and L"false".
22.2.3.2 - Template class numpunct_byname [lib.locale.numpunct.byname]
namespace std {
template <class charT>
class numpunct_byname : public numpunct<charT> {
//
this class is specialized for char and wchar_t.
public:
typedef charT char_type;
typedef basic_string<charT> string_type;
explicit numpunct_byname(const char*, size_t refs = 0);
protected:
~numpunct_byname(); // virtual
virtual char_type do_decimal_point() const;
virtual char_type do_thousands_sep() const;
virtual string do_grouping() const;
virtual string_type do_truename() const; // for bool
virtual string_type do_falsename() const; // for bool
};
}
22.2.4 - The collate category [lib.category.collate]
22.2.4.1 - Template class collate [lib.locale.collate]
namespace std {
template <class charT>
class collate : public locale::facet {
public:
typedef charT char_type;
typedef basic_string<charT> string_type;
explicit collate(size_t refs = 0);
int compare(const charT* low1, const charT* high1,
const charT* low2, const charT* high2) const;
string_type transform(const charT* low, const charT* high) const;
long hash(const charT* low, const charT* high) const;
static locale::id id;
protected:
~collate(); //
virtual
virtual int do_compare(const charT* low1, const charT* high1,
const charT* low2, const charT* high2) const;
virtual string_type do_transform
(const charT* low, const charT* high) const;
virtual long do_hash (const charT* low, const charT* high) const;
};
}
22.2.4.1.1 - collate members [lib.locale.collate.members]
int compare(const charT* low1, const charT* high1,
const charT* low2, const charT* high2) const;
string_type transform(const charT* low, const charT* high) const;
long hash(const charT* low, const charT* high) const;
22.2.4.1.2 - collate virtual functions [lib.locale.collate.virtuals]
int do_compare(const charT* low1, const charT* high1,
const charT* low2, const charT* high2) const;
string_type do_transform(const charT* low, const charT* high) const;
[Footnote:
This function is useful when one string is being compared to many other strings.
--- end foonote]
long do_hash(const charT* low, const charT* high) const;
--- end note]
22.2.4.2 - Template class collate_byname [lib.locale.collate.byname]
namespace std {
template <class charT>
class collate_byname : public collate<charT> {
public:
typedef basic_string<charT> string_type;
explicit collate_byname(const char*, size_t refs = 0);
protected:
~collate_byname(); //
virtual
virtual int do_compare(const charT* low1, const charT* high1,
const charT* low2, const charT* high2) const;
virtual string_type do_transform
(const charT* low, const charT* high) const;
virtual long do_hash (const charT* low, const charT* high) const;
};
}
22.2.5 - The time category [lib.category.time]
22.2.5.1 - Template class time_get [lib.locale.time.get]
namespace std {
class time_base {
public:
enum dateorder { no_order, dmy, mdy, ymd, ydm };
};
template <class charT, class InputIterator = istreambuf_iterator<charT> >
class time_get : public locale::facet, public time_base {
public:
typedef charT char_type;
typedef InputIterator iter_type;
explicit time_get(size_t refs = 0);
dateorder date_order() const { return do_date_order(); }
iter_type get_time(iter_type s, iter_type end, ios_base& f,
ios_base::iostate& err, tm* t) const;
iter_type get_date(iter_type s, iter_type end, ios_base& f,
ios_base::iostate& err, tm* t) const;
iter_type get_weekday(iter_type s, iter_type end, ios_base& f,
ios_base::iostate& err, tm* t) const;
iter_type get_monthname(iter_type s, iter_type end, ios_base& f,
ios_base::iostate& err, tm* t) const;
iter_type get_year(iter_type s, iter_type end, ios_base& f,
ios_base::iostate& err, tm* t) const;
static locale::id id;
protected:
~time_get(); //
virtual
virtual dateorder do_date_order() const;
virtual iter_type do_get_time(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
virtual iter_type do_get_date(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
virtual iter_type do_get_weekday(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
virtual iter_type do_get_monthname(iter_type s, ios_base&,
ios_base::iostate& err, tm* t) const;
virtual iter_type do_get_year(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
};
}
[Footnote:
In other words, user confirmation is required for reliable parsing of
user-entered dates and times, but machine-generated formats can be
parsed reliably.
This allows parsers to be aggressive about
interpreting user variations on standard formats.
--- end foonote]
22.2.5.1.1 - time_get members [lib.locale.time.get.members]
dateorder date_order() const;
iter_type get_time(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get_date(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get_weekday(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get_monthname(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get_year(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
22.2.5.1.2 - time_get virtual functions [lib.locale.time.get.virtuals]
dateorder do_date_order() const;
[Footnote:
This function is intended as a convenience only, for common
formats, and may return
no_order
in valid locales.
--- end foonote]
Returns
no_order
if the date format specified by
'x'
contains other variable components (e.g. Julian day, week number, week day).
iter_type do_get_time(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type do_get_date(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type do_get_weekday(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type do_get_monthname(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type do_get_year(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
22.2.5.2 - Template class time_get_byname [lib.locale.time.get.byname]
namespace std {
template <class charT, class InputIterator = istreambuf_iterator<charT> >
class time_get_byname : public time_get<charT, InputIterator> {
public:
typedef time_base::dateorder dateorder;
typedef InputIterator iter_type
explicit time_get_byname(const char*, size_t refs = 0);
protected:
~time_get_byname(); //
virtual
virtual dateorder do_date_order() const;
virtual iter_type do_get_time(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
virtual iter_type do_get_date(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
virtual iter_type do_get_weekday(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
virtual iter_type do_get_monthname(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
virtual iter_type do_get_year(iter_type s, iter_type end, ios_base&,
ios_base::iostate& err, tm* t) const;
};
}
22.2.5.3 - Template class time_put [lib.locale.time.put]
namespace std {
template <class charT, class OutputIterator = ostreambuf_iterator<charT> >
class time_put : public locale::facet {
public:
typedef charT char_type;
typedef OutputIterator iter_type;
explicit time_put(size_t refs = 0);
//
the following is implemented in terms of other member functions.
iter_type put(iter_type s, ios_base& f, char_type fill, const tm* tmb,
const charT* pattern, const charT* pat_end) const;
iter_type put(iter_type s, ios_base& f, char_type fill,
const tm* tmb, char format, char modifier = 0) const;
static locale::id id;
protected:
~time_put(); //
virtual
virtual iter_type do_put(iter_type s, ios_base&, char_type, const tm* t,
char format, char modifier) const;
};
}
22.2.5.3.1 - time_put members [lib.locale.time.put.members]
iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t,
const charT* pattern, const charT* pat_end) const;
iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t,
char format, char modifier = 0) const;
[Footnote:
Although the C programming language defines no modifiers,
most vendors do.
--- end foonote]
and a format specifier character
spec
as defined for the function
strftime.
If no modifier character is present,
mod
is zero.
For each valid format sequence identified, calls
do_put(s, str, fill, t, spec, mod).
22.2.5.3.2 - time_put virtual functions [lib.locale.time.put.virtuals]
iter_type do_put(iter_type s, ios_base&, char_type fill, const tm* t,
char format, char modifier) const;
[Footnote:
Interpretation of the modifier
argument is implementation-defined, but should follow POSIX
conventions.
--- end foonote]
except that the sequence of characters produced for those specifiers
that are described as depending on the C locale are instead implementation-defined.*
[Footnote:
Implementations are encouraged to refer to other standards (such as POSIX)
for these definitions.
--- end foonote]
22.2.5.4 - Template class time_put_byname [lib.locale.time.put.byname]
namespace std {
template <class charT, class OutputIterator = ostreambuf_iterator<charT> >
class time_put_byname : public time_put<charT, OutputIterator>
{
public:
typedef charT char_type;
typedef OutputIterator iter_type;
explicit time_put_byname(const char*, size_t refs = 0);
protected:
~time_put_byname(); //
virtual
virtual iter_type do_put(iter_type s, ios_base&, char_type, const tm* t,
char format, char modifier) const;
};
}
22.2.6 - The monetary category [lib.category.monetary]
22.2.6.1 - Template class money_get [lib.locale.money.get]
namespace std {
template <class charT,
class InputIterator = istreambuf_iterator<charT> >
class money_get : public locale::facet {
public:
typedef charT char_type;
typedef InputIterator iter_type;
typedef basic_string<charT> string_type;
explicit money_get(size_t refs = 0);
iter_type get(iter_type s, iter_type end, bool intl,
ios_base& f, ios_base::iostate& err,
long double& units) const;
iter_type get(iter_type s, iter_type end, bool intl,
ios_base& f, ios_base::iostate& err,
string_type& digits) const;
static locale::id id;
protected:
~money_get(); //
virtual
virtual iter_type do_get(iter_type, iter_type, bool, ios_base&,
ios_base::iostate& err, long double& units) const;
virtual iter_type do_get(iter_type, iter_type, bool, ios_base&,
ios_base::iostate& err, string_type& digits) const;
};
}
22.2.6.1.1 - money_get members [lib.locale.money.get.members]
iter_type get(iter_type s, iter_type end, bool intl,
ios_base& f, ios_base::iostate& err,
long double& quant) const;
iter_type get(s, iter_type end, bool intl, ios_base&f,
ios_base::iostate& err, string_type& quant) const;
22.2.6.1.2 - money_get virtual functions [lib.locale.money.get.virtuals]
iter_type do_get(iter_type s, iter_type end, bool intl,
ios_base& str, ios_base::iostate& err,
long double& units) const;
iter_type do_get(iter_type s, iter_type end, bool intl,
ios_base& str, ios_base::iostate& err,
string_type& digits) const;
--- end example]
If
mp.grouping()
indicates that no thousands separators are permitted,
any such characters are not read, and parsing is terminated at the point
where they first appear.
Otherwise, thousands separators are optional;
if present, they are checked for correct placement only after
all format components have been read.
[Footnote:
The semantics here are different from
ct.narrow.
--- end foonote]
where
n
is the number of characters placed in
buf1,
buf2
is a character buffer, and the values
src
and
atoms
are defined as if by
for (int i = 0; i < n; ++i)
buf2[i] = src[find(atoms, atoms+sizeof(src), buf1[i]) - atoms];
buf2[n] = 0;
sscanf(buf2, "%Lf", &units);
static const char src[] = "0123456789-";
charT atoms[sizeof(src)];
ct.widen(src, src + sizeof(src) - 1, atoms);
22.2.6.2 - Template class money_put [lib.locale.money.put]
namespace std {
template <class charT,
class OutputIterator = ostreambuf_iterator<charT> >
class money_put : public locale::facet {
public:
typedef charT char_type;
typedef OutputIterator iter_type;
typedef basic_string<charT> string_type;
explicit money_put(size_t refs = 0);
iter_type put(iter_type s, bool intl, ios_base& f,
char_type fill, long double units) const;
iter_type put(iter_type s, bool intl, ios_base& f,
char_type fill, const string_type& digits) const;
static locale::id id;
protected:
~money_put(); //
virtual
virtual iter_type
do_put(iter_type, bool, ios_base&, char_type fill,
long double units) const;
virtual iter_type
do_put(iter_type, bool, ios_base&, char_type fill,
const string_type& digits) const;
};
}
22.2.6.2.1 - money_put members [lib.locale.money.put.members]
iter_type put(iter_type s, bool intl, ios_base& f, char_type fill,
long double quant) const;
iter_type put(iter_type s, bool intl, ios_base& f, char_type fill,
const string_type& quant) const;
22.2.6.2.2 - money_put virtual functions [lib.locale.money.put.virtuals]
iter_type do_put(iter_type s, bool intl, ios_base& str,
char_type fill, long double units) const;
iter_type do_put(iter_type s, bool intl, ios_base& str,
char_type fill, const string_type& digits) const;
for character buffers
buf1
and
buf2.
If the first character in
digits
or
buf2
is equal to
ct.widen('-'),
then the pattern used for formatting is the result of
mp.neg_format();
otherwise the pattern is the result of
mp.pos_format().
Digit characters are written, interspersed with any thousands separators
and decimal point specified by the format, in the order they appear
(after the optional leading minus sign)
in
digits
or
buf2.
In
digits,
only the optional leading minus sign and the immediately subsequent
digit characters (as classified according to
ct)
are used; any trailing characters (including digits appearing
after a non-digit character) are ignored.
Calls
str.width(0).
ct.widen(buf1, buf1 + sprintf(buf1, "%.01f", units), buf2)
--- end note]
22.2.6.3 - Template class moneypunct [lib.locale.moneypunct]
namespace std {
class money_base {
public:
enum part { none, space, symbol, sign, value };
struct pattern { char field[4]; };
};
template <class charT, bool International = false>
class moneypunct : public locale::facet, public money_base {
public:
typedef charT char_type;
typedef basic_string<charT> string_type;
explicit moneypunct(size_t refs = 0);
charT decimal_point() const;
charT thousands_sep() const;
string grouping() const;
string_type curr_symbol() const;
string_type positive_sign() const;
string_type negative_sign() const;
int frac_digits() const;
pattern pos_format() const;
pattern neg_format() const;
static locale::id id;
static const bool intl = International;
protected:
~moneypunct(); //
virtual
virtual charT do_decimal_point() const;
virtual charT do_thousands_sep() const;
virtual string do_grouping() const;
virtual string_type do_curr_symbol() const;
virtual string_type do_positive_sign() const;
virtual string_type do_negative_sign() const;
virtual int do_frac_digits() const;
virtual pattern do_pos_format() const;
virtual pattern do_neg_format() const;
};
}
[Footnote:
An array of
char,
rather than an array of
part,
is specified for
pattern::field
purely for efficiency.
--- end foonote]
In the
field
member of a
pattern
object, each value
symbol,
sign,
value,
and either
space
or
none
appears exactly once.
The value
none,
if present, is not first;
the value
space,
if present, is neither first nor last.
If
frac_digits()
returns a positive value, or
value ::= units [ decimal-point [ digits]] |
decimal-point digits
otherwise.
The symbol
decimal-point
indicates the character returned by
decimal_point().
The other symbols are defined as follows:
value ::= units
In the syntax specification, the symbol
adigit
is any of the values
ct.widen(c)
for
c
in the range
'0'
through
'9',
inclusive, and
ct
is a reference of type
const ctype<charT>&
obtained as described in the definitions of
money_get<>
and
money_put<>.
The symbol
thousands-sep
is the character returned by
thousands_sep().
The space character used is the value
ct.widen(' ').
White space characters are those characters
c
for which
ci.is(space, c)
returns
true.
The number of digits required after the decimal point (if any)
is exactly the value returned by
frac_digits().
units ::= digits [ thousands-sep units ]
digits ::= adigit [ digits ]
22.2.6.3.1 - moneypunct members [lib.locale.moneypunct.members]
charT decimal_point() const;
charT thousands_sep() const;
string grouping() const;
string_type curr_symbol() const;
string_type positive_sign() const;
string_type negative_sign() const;
int frac_digits() const;
pattern pos_format() const;
pattern neg_format() const;
22.2.6.3.2 - moneypunct virtual functions [lib.locale.moneypunct.virtuals]
charT do_decimal_point() const;
[Footnote:
In common U.S. locales this is
'.'.
--- end foonote]
charT do_thousands_sep() const;
[Footnote:
In common U.S. locales this is
','.
--- end foonote]
string do_grouping() const;
[Footnote:
This is most commonly the value "\003"
(not
"3").
--- end foonote]
string_type do_curr_symbol() const;
[Footnote:
For international instantiations (second template parameter
true)
this is always four characters long, usually three letters and a space.
--- end foonote]
string_type do_positive_sign() const;
string_type do_negative_sign() const;
[Footnote:
This is usually the empty string.
--- end foonote]
do_negative_sign()
returns the string to use to indicate a negative value.
int do_frac_digits() const;
[Footnote:
In common U.S. locales, this is 2.
--- end foonote]
pattern do_pos_format() const;
pattern do_neg_format() const;
[Footnote:
Note that the international symbol returned by
do_curr_sym()
usually contains a space, itself;
for example, "USD ".
--- end foonote]
22.2.6.4 - Template class moneypunct_byname [lib.locale.moneypunct.byname]
namespace std {
template <class charT, bool Intl = false>
class moneypunct_byname : public moneypunct<charT, Intl> {
public:
typedef money_base::pattern pattern;
typedef basic_string<charT> string_type;
explicit moneypunct_byname(const char*, size_t refs = 0);
protected:
~moneypunct_byname(); //
virtual
virtual charT do_decimal_point() const;
virtual charT do_thousands_sep() const;
virtual string do_grouping() const;
virtual string_type do_curr_symbol() const;
virtual string_type do_positive_sign() const;
virtual string_type do_negative_sign() const;
virtual int do_frac_digits() const;
virtual pattern do_pos_format() const;
virtual pattern do_neg_format() const;
};
}
22.2.7 - The message retrieval category [lib.category.messages]
22.2.7.1 - Template class messages [lib.locale.messages]
namespace std {
class messages_base {
public:
typedef int catalog;
};
template <class charT>
class messages : public locale::facet, public messages_base {
public:
typedef charT char_type;
typedef basic_string<charT> string_type;
explicit messages(size_t refs = 0);
catalog open(const basic_string<char>& fn, const locale&) const;
string_type get(catalog c, int set, int msgid,
const string_type& dfault) const;
void close(catalog c) const;
static locale::id id;
protected:
~messages(); //
virtual
virtual catalog do_open(const basic_string<char>&, const locale&) const;
virtual string_type do_get(catalog, int set, int msgid,
const string_type& dfault) const;
virtual void do_close(catalog) const;
};
}
22.2.7.1.1 - messages members [lib.locale.messages.members]
catalog open(const basic_string<char>& name, const locale& loc) const;
string_type get(catalog cat, int set, int msgid,
const string_type& dfault) const;
void close(catalog cat) const;
22.2.7.1.2 - messages virtual functions [lib.locale.messages.virtuals]
catalog do_open(const basic_string<char>& name,
const locale& loc) const;
Returns a value less than 0 if no such catalog can be opened.
string_type do_get(catalog cat, int set, int msgid,
const string_type& dfault) const;
void do_close(catalog cat) const;
22.2.7.2 - Template class messages_byname [lib.locale.messages.byname]
namespace std {
template <class charT>
class messages_byname : public messages<charT> {
public:
typedef messages_base::catalog catalog;
typedef basic_string<charT> string_type;
explicit messages_byname(const char*, size_t refs = 0);
protected:
~messages_byname(); //
virtual
virtual catalog do_open(const basic_string<char>&, const locale&) const;
virtual string_type do_get(catalog, int set, int msgid,
const string_type& dfault) const;
virtual void do_close(catalog) const;
};
}
22.2.8 - Program-defined facets [lib.facets.examples]
--- end note]
#include <iostream>
#include <locale>
int main(int argc, char** argv)
{
using namespace std;
locale::global(locale("")); //
set the global locale
// imbue it on all the std streams
cin.imbue(locale());
cout.imbue(locale());
cerr.imbue(locale());
wcin.imbue(locale());
wcout.imbue(locale());
wcerr.imbue(locale());
return MyObject(argc, argv).doit();
}
--- end example]
In a European locale, with input
3.456,78,
output is
3456.78.
#include <iostream>
#include <locale>
int main()
{
using namespace std;
cin.imbue(locale("")); //
the user's preferred locale
cout.imbue(locale::classic());
double f;
while (cin >> f) cout << f << endl;
return (cin.fail() != 0);
}
--- end example]
This example illustrates two architectural uses of class
locale.
//
file: Date.h
#include <iosfwd>
#include <string>
#include <locale>
...
class Date {
...
public:
Date(unsigned day, unsigned month, unsigned year);
std::string asString(const std::locale& = std::locale());
};
istream& operator>>(istream& s, Date& d);
ostream& operator<<(ostream& s, Date d);
...
//
file: Date.C
#include "Date" // includes <ctime>
#include <sstream>
std::string Date::asString(const std::locale& l)
{
using namespace std;
ostringstream s; s.imbue(l);
s << *this; return s.str();
}
std::istream& operator>>(std::istream& s, Date& d)
{
using namespace std;
istream::sentry cerberos(s);
if (cerberos) {
ios_base::iostate err = goodbit;
struct tm t;
use_facet< time_get<char> >(s.getloc()).get_date(s, 0, s, err, &t);
if (!err) d = Date(t.tm_day, t.tm_mon + 1, t.tm_year + 1900);
s.setstate(err);
}
return s;
}
--- end example]
//
file: <jctype>
#include <locale>
namespace My {
using namespace std;
class JCtype : public locale::facet {
public:
static locale::id id; // required for use as a new locale facet
bool is_kanji(wchar_t c);
JCtype() {}
protected:
~JCtype() {}
};
}
//
file: filt.C
#include <iostream>
#include <locale>
#include "jctype" // above
std::locale::id JCtype::id; // the static JCtype member declared above.
int main()
{
using namespace std;
typedef ctype<wchar_t> wctype;
locale loc(locale(""), // the user's preferred locale ...
new My::JCType); // and a new feature ...
wchar_t c = use_facet<wctype>(loc).widen('!');
if (use_facet<My::JCType>(loc).is_kanji(c))
cout << "no it isn't!" << endl;
return 0;
}
--- end example]
//
file: my_bool.C
#include <iostream>
#include <locale>
#include <string>
namespace My {
using namespace std;
typedef numpunct_byname<char> cnumpunct;
class BoolNames : public cnumpunct {
protected:
string do_truename() { return "Oui Oui!"; }
string do_falsename() { return "Mais Non!"; }
~BoolNames() {}
public:
BoolNames(const char* name) : cnumpunct(name) {}
};
}
int main(int argc, char** argv)
{
using namespace std;
//
make the user's preferred locale, except for...
locale loc(locale(""), new My::BoolNames(""));
cout.imbue(loc);
cout << boolalpha << "Any arguments today? " << (argc > 1) << endl;
return 0;
}
--- end example]
22.3 - C Library Locales [lib.c.locales]
Type Name(s) Macros: LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY LC_NUMERIC LC_TIME NULL Struct: lconv Functions: localeconv setlocale