25 Localization library [localization]

25.4 Standard locale categories [locale.categories]

25.4.6 The monetary category [category.monetary]

Эти шаблоны обрабатывают денежные форматы. Параметр шаблона указывает, какой формат валюты следует использовать: местный или международный.

Все спецификации функций-членов для money_­put и money_­get в подпунктах[category.monetary] применимы только к специализациям, требуемым в таблицах69 и70 ([locale.category]). Их члены используют их ios_­base&, ios_­base​::​iostate&и fill аргументы , как описано в[locale.categories], и moneypunct<> и ctype<> грани, чтобы определить детали форматирования.

25.4.6.1 Class template money_­get [locale.money.get]

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;
    };
}

25.4.6.1.1 money_­get members [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;

Returns: do_­get(s, end, intl, f, err, quant).

25.4.6.1.2 money_­get virtual functions [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;

Effects: Считывает символы из, s чтобы проанализировать и построить денежное значение в соответствии с форматом, указаннымmoneypunct<charT, Intl> ссылкой на фасет, mp и отображением символов, указаннымctype<charT> ссылкой на фасет, ct полученной из языкового стандарта, возвращенного str.getloc(), и str.flags(). Если действительная последовательность распознана, не изменяетсяerr; в противном случае устанавливаетсяerr значение (err|str.failbit)или, (err|str.failbit|str.eofbit) если больше нет доступных символов, и не изменяетсяunits илиdigits. Использует шаблон, возвращенный mp.neg_­format() для анализа всех значений. Результат возвращается как целое значение, хранящееся в, units или как последовательность цифр, которой может предшествовать знак минус (как результат, ct.widen(c) где c есть '-' или в диапазоне от '0' до '9', включительно), сохраненный в digits. [ Example: Последовательность $1,056.23 в общей местности Соединенных Штатов дало бы, по units, 105623, или, digits, "105623". ] Если указывает, что разделители тысяч не разрешены, любые такие символы не читаются, и синтаксический анализ завершается в точке, где они появляются впервые. В противном случае разделители тысяч не являются обязательными; если они присутствуют, они проверяются на правильность размещения только после того, как будут прочитаны все компоненты формата.end examplemp.grouping()

Если money_­base​::​space или money_­base​::​none отображается как последний элемент в шаблоне формата, пробелы не используются. В противном случае, гдеmoney_­base​::​space встречается в любом из начальных элементов шаблона формата, требуется по крайней мере один символ пробела. Если money_­base​::​none присутствует в любом из начальных элементов шаблона формата, пробелы разрешены, но не обязательны. Если задано значение (str.flags() & str.showbase) false, символ валюты является необязательным и используется только в том случае, если для завершения формата необходимы другие символы; в противном случае требуется символ валюты.

Если первый символ (если есть) в строке, pos возвращаемой mp.positive_­sign() илиneg возвращенной строкой , mp.negative_­sign() распознается в позиции, указанной sign в шаблоне формата, он используется, и любые оставшиеся символы в строке требуются после всех других компонентов формата. [ Example: Если showbase выключен, то для neg значения"()" и символа валютной"L", в потребляется; но если есть , то in не потребляется. ] Если или пусто, компонент знака является необязательным, и если знак не обнаружен, результат получает знак, соответствующий источнику пустой строки. В противном случае символ в указанной позиции должен соответствовать первому символу или , и результат получает соответствующий знак. Если первый символ равен первому символу или обе строки пусты, результат получает положительный знак."(100 L)" "L" neg"-""L" "-100 L" end exampleposnegposnegposneg

Цифры в числовом денежном компоненте извлекаются и помещаются в digitsили в символьный буфер buf1 для преобразования для получения значения unitsв том порядке, в котором они появляются, с предшествующим знаком минус тогда и только тогда, когда результат отрицательный. Значение units создается, как если бы248

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);

где n - количество символов, помещенных в buf1, buf2 - символьный буфер, а значения src и atoms определяются как если бы

static const char src[] = "0123456789-";
charT atoms[sizeof(src)];
ct.widen(src, src + sizeof(src) - 1, atoms);

Returns: Итератор, указывающий сразу за последним символом, признанным частью допустимой денежной величины.

Семантика здесь отличается от ct.narrow.

25.4.6.2 Class template money_­put [locale.money.put]

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;
    };
}

25.4.6.2.1 money_­put members [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;

Returns: do_­put(s, intl, f, loc, quant).

25.4.6.2.2 money_­put virtual functions [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;

Effects: Записывает символы в s соответствии с форматом, указаннымmoneypunct<charT, Intl> ссылкой на фасет, mp и отображением символов, указаннымctype<charT> ссылкой на фасет, ct полученной из языкового стандарта, возвращаемого параметрами str.getloc(), и str.flags(). Аргумент units преобразуется в последовательность широких символов, как если бы

ct.widen(buf1, buf1 + sprintf(buf1, "%.0Lf", units), buf2)

для символьных буферов buf1 и buf2. Если первый символ в digits или buf2 равен ct.widen('-'), то шаблон, используемый для форматирования, является результатом mp.neg_­format(); в противном случае узор является результатом mp.pos_­format(). Цифровые символы записываются с вкраплениями разделителей тысяч и десятичной точки, указанных в формате, в том порядке, в котором они появляются (после необязательного ведущего знака минус) в digits или buf2. В digitsиспользуются только необязательный начальный знак минус и непосредственно следующие за ним цифровые символы (согласно классификации ct); любые завершающие символы (включая цифры, появляющиеся после нецифрового символа) игнорируются. Звонки str.width(0).

Remarks: Символ валюты генерируется тогда и только тогда, когда он не (str.flags() & str.showbase) равен нулю. Если количество символов, сгенерированных для указанного формата, меньше значения, возвращаемогоstr.width() функцией при входе в функцию, то копии fill вставляются по мере необходимости для заполнения до указанной ширины. Для значения, af равного (str.flags() & str.adjustfield), если (af == str.internal) естьtrue, символы заполнения помещаются там, где none или space появляются в шаблоне форматирования; в противном случае, если (af == str.left) естьtrue, они помещаются после других символов; в противном случае они помещаются перед другими символами. [ Note: Возможно, с некоторыми комбинациями шаблонов формата и значений флагов, чтобы произвести вывод, который не может быть проанализирован с использованием num_­get<>​::​get. ]end note

Returns: Итератор, указывающий сразу после последнего созданного символа.

25.4.6.3 Class template moneypunct [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:
      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;
    };
}

moneypunct<> Фасет определяет денежные параметры форматирования , используемые money_­get<> и money_­put<>. Денежный формат представляет собой последовательность из четырех компонентов, задается pattern значением p, таким образом, что part значение static_­cast<part>(p.field[i]) определяет iй компонент формата249 В field члене pattern объекта, каждое значении symbol, sign, value, и или space или none появляется ровно один раз. Значение none, если оно присутствует, не является первым; значение space, если оно есть, не является ни первым, ни последним.

В тех местах, где none или spaceпоявляется, в формате разрешены пробелы, кроме тех, где они none появляются в конце, и в этом случае пробелы не допускаются. Значение space указывает, что в этой позиции требуется хотя бы один пробел. Если symbol появляется, последовательность символов, возвращаемая curr_­symbol() функцией, разрешена и может быть обязательной. Тамsign , где появляется, требуется первая (если есть) из последовательности символов, возвращаемых функцией positive_­sign() или negative_­sign()(соответственно, поскольку денежное значение неотрицательно или отрицательно). Любые оставшиеся символы знаковой последовательности требуются после всех остальных компонентов формата. Где value появляется, требуется абсолютное числовое значение в денежном выражении.

Формат числового денежного значения - десятичное число:

value ::= units [ decimal-point [ digits ]] |
  decimal-point digits

если frac_­digits() возвращает положительное значение, или

value ::= units

иначе. Этот символ decimal-point указывает на символ, возвращаемый функцией decimal_­point(). Остальные символы определены следующим образом:

units ::= digits [ thousands-sep units ]
digits ::= adigit [ digits ]

В описании синтаксиса, символ adigit является любым из значений ct.widen(c) для c в диапазоне '0' через '9', включительно, и ct является ссылкой типа ,const ctype<charT>& полученным , как описано в определениях money_­get<> и money_­put<>. Символ thousands-sep - это символ, возвращаемый функцией thousands_­sep(). Используемый пробел - это значение ct.widen(' '). Символы пробела - это те символы,c для которых выполняется ci.is(space, c) возврат true. Количество цифр, необходимых после десятичной точки (если есть), в точности равно значению, возвращаемому функцией frac_­digits().

Размещение символов-разделителей тысяч (если есть) определяется значением, возвращаемым grouping(), определяемым идентично члену numpunct<>​::​do_­grouping().

Массив char, а не массив part, указан pattern​::​field исключительно для эффективности.

25.4.6.3.1 moneypunct members [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;

Каждая из этих функцийF возвращает результат вызова соответствующей виртуальной функции-члена do_­F().

25.4.6.3.2 moneypunct virtual functions [locale.moneypunct.virtuals]

charT do_decimal_point() const;

Returns: Разделитель системы счисления, используемый в случае, если do_­frac_­digits() он больше нуля.250

charT do_thousands_sep() const;

Returns: Разделитель групп цифр, используемый в случае, do_­grouping() указывает шаблон группировки цифр.251

string do_grouping() const;

Returns: Шаблон, идентичный, но не обязательно равному результату numpunct<charT>​::​​do_­grouping().252

string_type do_curr_symbol() const;

Returns: Строка, используемая в качестве символа идентификатора валюты.253

string_type do_positive_sign() const; string_type do_negative_sign() const;

Returns: do_­positive_­sign() возвращает строку, используемую для обозначения положительного денежного значения;254 do_­negative_­sign() возвращает строку, используемую для обозначения отрицательного значения.

int do_frac_digits() const;

Returns: Количество цифр после десятичного разделителя системы счисления, если таковой имеется.255

pattern do_pos_format() const; pattern do_neg_format() const;

Returns: В специализации требуемая в таблице70 ([locale.category]), а именно moneypunct<char>, moneypunct<​wchar_­t>, moneypunct<char, true>, и moneypunct<wchar_­t, true>, возвращает объект типа pattern инициализируется { symbol, sign, none, value }.256

В обычных регионах США это так '.'.

В обычных регионах США это так ','.

Чтобы указать группировку по 3 с, значение равно"\003" not "3".

Для международных специализаций (второй параметр шаблона true) это обычно четыре символа, обычно три буквы и пробел.

Обычно это пустая строка.

В обычных регионах США это 2.

Обратите внимание, что международный символ, возвращаемый функцией, do_­curr_­sym() обычно сам содержит пробел; например"USD ",.

25.4.6.4 Class template moneypunct_­byname [locale.moneypunct.byname]

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();
  };
}