These templates handle monetary formats
. A template parameter indicates whether
local or international monetary formats are to be used
. Their members use their
ios_base&,
ios_base::iostate&,
and
fill
arguments as described in
[locale.categories], and the
moneypunct<>
and
ctype<>
facets, to determine formatting details
. namespace std {
template<class charT, class InputIterator = istreambuf_iterator<charT>>
class money_get : public locale::facet {
public:
using char_type = charT;
using iter_type = InputIterator;
using string_type = basic_string<charT>;
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 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;
};
}
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(iter_type s, iter_type end, bool intl, ios_base& f,
ios_base::iostate& err, string_type& quant) const;
Returns:
do_get(s, end, intl, f, err, quant). 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;
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 1:
The sequence
$1,056.23
in a common United States locale would yield, for
units,
105623,
or, for
digits,
"105623". —
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
.Where
money_base::space
or
money_base::none
appears as the last element in the format pattern,
no whitespace is consumed
. Otherwise, where
money_base::space appears in any of the
initial elements of the format pattern, at least one whitespace character is required
. Where
money_base::none appears in any of the initial elements of the format pattern, white
space is allowed but not required
. 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
.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 2:
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
. —
end example]
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
neg,
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
.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
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);
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
static const char src[] = "0123456789-";
charT atoms[sizeof(src)];
ct.widen(src, src + sizeof(src) - 1, atoms);
Returns: An iterator pointing immediately beyond the last character recognized
as part of a valid monetary quantity
. namespace std {
template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
class money_put : public locale::facet {
public:
using char_type = charT;
using iter_type = OutputIterator;
using string_type = basic_string<charT>;
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 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;
};
}
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;
Returns:
do_put(s, intl, f, loc, quant). 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;
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
ct.widen(buf1, buf1 + sprintf(buf1, "%.0Lf", units), buf2)
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
. Returns: An iterator pointing immediately after the last character produced
. Remarks: 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 1:
It is possible, with some combinations of format patterns and flag values,
to produce output that cannot be parsed using
num_get<>::get. —
end note]
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:
using char_type = charT;
using string_type = basic_string<charT>;
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 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;
};
}
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
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
.Where
none
or
space
appears, whitespace is permitted in the format,
except where
none
appears at the end, in which case no whitespace 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
.The format of the numeric monetary value is a decimal number:
value:
units fractionalopt
decimal-point digits
fractional:
decimal-point digitsopt
if
frac_digits() returns a positive value, or
value:
units
otherwise
. The symbol
decimal-point
indicates the character returned by
decimal_point(). The other symbols are defined as follows:
units:
digits
digits thousands-sep 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().The placement of thousands-separator characters (if any)
is determined by the value returned by
grouping(),
defined identically as the member
numpunct<>::do_grouping().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;
Each of these functions
F
returns the result of calling the corresponding
virtual member function
do_F().charT do_decimal_point() const;
Returns: The radix separator to use in case
do_frac_digits()
is greater than zero
. charT do_thousands_sep() const;
Returns: The digit group separator to use in case
do_grouping()
specifies a digit grouping pattern
. string do_grouping() const;
Returns: A pattern defined identically as, but not necessarily equal to, the result of
numpunct<charT>::do_grouping(). string_type do_curr_symbol() const;
Returns: A string to use as the currency identifier symbol
. [
Note 1:
For specializations where the second template parameter is
true,
this is typically four characters long: a three-letter code as specified
by ISO 4217 followed by a space
. —
end note]
string_type do_positive_sign() const;
string_type do_negative_sign() const;
Returns:
do_positive_sign()
returns the string to use to indicate a
positive monetary value;
do_negative_sign()
returns the string to use to indicate a negative value
. int do_frac_digits() const;
Returns: The number of digits after the decimal radix separator, if any
. Returns: The specializations required in Table
103 (
[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 }. namespace std {
template<class charT, bool Intl = false>
class moneypunct_byname : public moneypunct<charT, Intl> {
public:
using pattern = money_base::pattern;
using string_type = basic_string<charT>;
explicit moneypunct_byname(const char*, size_t refs = 0);
explicit moneypunct_byname(const string&, size_t refs = 0);
protected:
~moneypunct_byname();
};
}