28 Localization library [localization]

28.4 Standard locale categories [locale.categories]

28.4.2 The numeric category [category.numeric]

28.4.2.2 Class template num_­put [locale.nm.put]

namespace std {
  template<class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class num_put : public locale::facet {
    public:
      using char_type = charT;
      using iter_type = OutputIterator;

      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, long 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, unsigned long 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 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, long 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, unsigned long 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;
    };
}
The facet num_­put is used to format numeric values to a character sequence such as an ostream.

28.4.2.2.1 Members [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, long 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, unsigned long 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;
Returns: do_­put(out, str, fill, val).

28.4.2.2.2 Virtual functions [facet.num.put.virtuals]

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, long 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, unsigned long 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;
Effects: Writes characters to the sequence out, formatting val as desired.
In the following description, loc names a local variable initialized as
locale loc = str.getloc();
The details of this operation occur in several stages:
  • Stage 1: Determine a printf conversion specifier spec and determine the characters that would be printed by printf ([c.files]) given this conversion specifier for
    printf(spec, val)
    
    assuming that the current locale is the "C" locale.
  • Stage 2: Adjust the representation by converting each char determined by stage 1 to a charT using a conversion and values returned by members of use_­facet<numpunct<charT>>(loc).
  • Stage 3: Determine where padding is required.
  • Stage 4: Insert the sequence into the out.
Detailed descriptions of each stage follow.
Returns: out.
  • 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));
    fmtflags showpoint =  (flags & (ios_base::showpoint));
    
    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.
    For conversion from an integral type other than a character type, the function determines the integral conversion specifier as indicated in Table 108.
    Table 108: Integer conversions   [tab:facet.num.put.int]
    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
    For conversion from a floating-point type, the function determines the floating-point conversion specifier as indicated in Table 109.
    Table 109: Floating-point conversions   [tab:facet.num.put.fp]
    State
    stdio equivalent
    floatfield == ios_­base​::​fixed
    %f
    floatfield == ios_­base​::​scientific && !uppercase
    %e
    floatfield == ios_­base​::​scientific
    %E
    floatfield == (ios_­base​::​fixed | ios_­base​::​scientific) && !uppercase
    %a
    floatfield == (ios_­base​::​fixed | ios_­base​::​scientific)
    %A
    !uppercase
    %g
    otherwise
    %G
    For conversions from an integral or floating-point type a length modifier is added to the conversion specifier as indicated in Table 110.
    Table 110: Length modifier   [tab:facet.num.put.length]
    Type
    Length modifier
    long
    l
    long long
    ll
    unsigned long
    l
    unsigned long long
    ll
    long double
    L
    otherwise
    none
    The conversion specifier has the following optional additional qualifiers prepended as indicated in Table 111.
    Table 111: Numeric conversions   [tab:facet.num.put.conv]
    Type(s)
    State
    stdio equivalent
    an integral type
    showpos
    +
    showbase
    #
    a floating-point type
    showpos
    +
    showpoint
    #
    For conversion from a floating-point type, if floatfield != (ios_­base​::​fixed | ios_­base​::​​scientific), str.precision() is specified as precision in the conversion specification.
    Otherwise, no precision is specified.
    For conversion from void* the specifier is %p.
    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.
  • Stage 2:
    Any character c other than a decimal point(.) is converted to a charT via
    use_facet<ctype<charT>>(loc).widen(c)
    
    A local variable punct is initialized via
    const numpunct<charT>& punct = use_facet<numpunct<charT>>(loc);
    
    For arithmetic 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 [facet.numpunct.virtuals]
    Decimal point characters(.) are replaced by punct.decimal_­point()
  • Stage 3:
    A local variable is initialized as
    fmtflags adjustfield = (flags & (ios_base::adjustfield));
    
    The location of any padding267 is determined according to Table 112.
    Table 112: Fill padding   [tab:facet.num.put.fill]
    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 or 0X
    pad after x or X
    otherwise
    pad before
    If str.width() is nonzero and the number of charT's in the sequence after stage 2 is less than str.​width(), then enough fill characters are added to the sequence at the position indicated for padding to bring the length of the sequence to str.width().
    str.width(0) is called.
  • Stage 4:
    The sequence of charT's at the end of stage 3 are output via
    *out++ = c
    
iter_type do_put(iter_type out, ios_base& str, char_type fill, bool val) const;
Returns: If (str.flags() & ios_­base​::​boolalpha) == 0 returns do_­put(out, str, fill,
(int)val)
, otherwise obtains a string s as if by
string_type s =
  val ? use_facet<numpunct<charT>>(loc).truename()
      : use_facet<numpunct<charT>>(loc).falsename();
and then inserts each character c of s into out via *out++ = c and returns out.
The conversion specification #o generates a leading 0 which is not a padding character.
⮥