1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057 |
- /*
- * Copyright (c) 1999
- * Silicon Graphics Computer Systems, Inc.
- *
- * Copyright (c) 1999
- * Boris Fomitchev
- *
- * This material is provided "as is", with absolutely no warranty expressed
- * or implied. Any use is at your own risk.
- *
- * Permission to use or copy this software for any purpose is hereby granted
- * without fee, provided the above notices are retained on all copies.
- * Permission to modify the code and to distribute modified code is granted,
- * provided the above notices are retained, and a notice that the code was
- * modified is included with the above copyright notice.
- *
- */
- #include "stlport_prefix.h"
- #include <hash_map>
- #include <vector>
- #include <locale>
- #include <istream>
- #include <algorithm>
- #include <functional>
- #include "c_locale.h"
- #include "locale_impl.h"
- #include "acquire_release.h"
- _STLP_BEGIN_NAMESPACE
- //----------------------------------------------------------------------
- // ctype_byname<char>
- #if defined (__DMC__)
- _STLP_DECLSPEC
- #endif
- ctype_byname<char>::ctype_byname(const char* name, size_t refs)
- : ctype<char>( 0, false, refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_ctype = _STLP_PRIV __acquire_ctype(name, buf, 0, &__err_code);
- if (!_M_ctype)
- locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
- _M_init();
- }
- void ctype_byname<char>::_M_init() {
- _M_ctype_table = _M_byname_table;
- // We have to do this, instead of just pointer twiddling, because
- // ctype_base::mask isn't the same type as _Locale_mask_t.
- const _Locale_mask_t* p = _Locale_ctype_table(_M_ctype);
- for (size_t i = 0; i != table_size; ++i) {
- _M_byname_table[i] = ctype_base::mask(p[i]);
- }
- }
- ctype_byname<char>::~ctype_byname()
- { _STLP_PRIV __release_ctype(_M_ctype); }
- char ctype_byname<char>::do_toupper(char c) const
- { return (char)_Locale_toupper(_M_ctype, c); }
- char ctype_byname<char>::do_tolower(char c) const
- { return (char)_Locale_tolower(_M_ctype, c); }
- const char*
- ctype_byname<char>::do_toupper(char* first, const char* last) const {
- for ( ; first != last ; ++first)
- *first = (char)_Locale_toupper(_M_ctype, *first);
- return last;
- }
- const char*
- ctype_byname<char>::do_tolower(char* first, const char* last) const {
- for ( ; first != last ; ++first)
- *first = (char)_Locale_tolower(_M_ctype, *first);
- return last;
- }
- // Some helper functions used in ctype<>::scan_is and scan_is_not.
- #if !defined (_STLP_NO_WCHAR_T)
- _STLP_MOVE_TO_PRIV_NAMESPACE
- // ctype_byname<wchar_t>
- struct _Ctype_byname_w_is_mask : public unary_function<wchar_t, bool> {
- _Locale_mask_t M;
- _Locale_ctype* M_ctp;
- _Ctype_byname_w_is_mask(_Locale_mask_t m, _Locale_ctype* c)
- : M(m), M_ctp(c) {}
- bool operator()(wchar_t c) const
- { return _WLocale_ctype(M_ctp, c, M) != 0; }
- };
- _STLP_MOVE_TO_STD_NAMESPACE
- #if defined (__DMC__)
- _STLP_DECLSPEC
- #endif
- ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
- : ctype<wchar_t>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_ctype = _STLP_PRIV __acquire_ctype(name, buf, 0, &__err_code);
- if (!_M_ctype)
- locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
- }
- ctype_byname<wchar_t>::~ctype_byname()
- { _STLP_PRIV __release_ctype(_M_ctype); }
- bool ctype_byname<wchar_t>::do_is(ctype_base::mask m, wchar_t c) const
- { return _WLocale_ctype(_M_ctype, c, (_Locale_mask_t)m) != 0; }
- const wchar_t*
- ctype_byname<wchar_t>::do_is(const wchar_t* low, const wchar_t* high,
- ctype_base::mask * m) const {
- _Locale_mask_t all_bits = _Locale_mask_t(ctype_base::space |
- ctype_base::print |
- ctype_base::cntrl |
- ctype_base::upper |
- ctype_base::lower |
- ctype_base::alpha |
- ctype_base::digit |
- ctype_base::punct |
- ctype_base::xdigit);
- for ( ; low < high; ++low, ++m)
- *m = ctype_base::mask (_WLocale_ctype(_M_ctype, *low, all_bits));
- return high;
- }
- const wchar_t*
- ctype_byname<wchar_t>
- ::do_scan_is(ctype_base::mask m, const wchar_t* low, const wchar_t* high) const
- { return find_if(low, high, _STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype)); }
- const wchar_t*
- ctype_byname<wchar_t>
- ::do_scan_not(ctype_base::mask m, const wchar_t* low, const wchar_t* high) const
- { return find_if(low, high, not1(_STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype))); }
- wchar_t ctype_byname<wchar_t>::do_toupper(wchar_t c) const
- { return _WLocale_toupper(_M_ctype, c); }
- const wchar_t*
- ctype_byname<wchar_t>::do_toupper(wchar_t* low, const wchar_t* high) const {
- for ( ; low < high; ++low)
- *low = _WLocale_toupper(_M_ctype, *low);
- return high;
- }
- wchar_t ctype_byname<wchar_t>::do_tolower(wchar_t c) const
- { return _WLocale_tolower(_M_ctype, c); }
- const wchar_t*
- ctype_byname<wchar_t>::do_tolower(wchar_t* low, const wchar_t* high) const {
- for ( ; low < high; ++low)
- *low = _WLocale_tolower(_M_ctype, *low);
- return high;
- }
- #endif /* WCHAR_T */
- // collate_byname<char>
- #if defined (__DMC__)
- _STLP_DECLSPEC
- #endif
- collate_byname<char>::collate_byname(const char* name, size_t refs)
- : collate<char>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_collate = _STLP_PRIV __acquire_collate(name, buf, 0, &__err_code);
- if (!_M_collate)
- locale::_M_throw_on_creation_failure(__err_code, name, "collate");
- }
- collate_byname<char>::~collate_byname()
- { _STLP_PRIV __release_collate(_M_collate); }
- int collate_byname<char>::do_compare(const char* __low1,
- const char* __high1,
- const char* __low2,
- const char* __high2) const {
- return _Locale_strcmp(_M_collate,
- __low1, __high1 - __low1,
- __low2, __high2 - __low2);
- }
- collate_byname<char>::string_type
- collate_byname<char>::do_transform(const char* low, const char* high) const {
- if (low == high)
- return string_type();
- size_t n = _Locale_strxfrm(_M_collate, NULL, 0, low, high - low);
- // NOT PORTABLE. What we're doing relies on internal details of the
- // string implementation. (Contiguity of string elements and presence
- // of trailing zero.)
- string_type buf(n, 0);
- _Locale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low);
- return buf;
- }
- #if !defined (_STLP_NO_WCHAR_T)
- // collate_byname<wchar_t>
- #if defined (__DMC__)
- _STLP_DECLSPEC
- #endif
- collate_byname<wchar_t>::collate_byname(const char* name, size_t refs)
- : collate<wchar_t>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_collate = _STLP_PRIV __acquire_collate(name, buf, 0, &__err_code);
- if (!_M_collate)
- locale::_M_throw_on_creation_failure(__err_code, name, "collate");
- }
- collate_byname<wchar_t>::~collate_byname()
- { _STLP_PRIV __release_collate(_M_collate); }
- int collate_byname<wchar_t>::do_compare(const wchar_t* low1,
- const wchar_t* high1,
- const wchar_t* low2,
- const wchar_t* high2) const {
- return _WLocale_strcmp(_M_collate,
- low1, high1 - low1,
- low2, high2 - low2);
- }
- collate_byname<wchar_t>::string_type
- collate_byname<wchar_t>::do_transform(const wchar_t* low,
- const wchar_t* high) const {
- if (low == high)
- return string_type();
- size_t n = _WLocale_strxfrm(_M_collate, NULL, 0, low, high - low);
- // NOT PORTABLE. What we're doing relies on internal details of the
- // string implementation. (Contiguity of string elements and presence
- // of trailing zero.)
- string_type buf(n, 0);
- _WLocale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low);
- return buf;
- }
- #endif /* _STLP_NO_WCHAR_T */
- //----------------------------------------------------------------------
- // codecvt_byname<char>
- codecvt_byname<char, char, mbstate_t>
- ::codecvt_byname(const char* name, size_t refs)
- : codecvt<char, char, mbstate_t>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- }
- codecvt_byname<char, char, mbstate_t>::~codecvt_byname() {}
- #if !defined (_STLP_NO_WCHAR_T)
- //----------------------------------------------------------------------
- // codecvt_byname<wchar_t>
- codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname(const char* name, size_t refs)
- : codecvt<wchar_t, char, mbstate_t>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_codecvt = _STLP_PRIV __acquire_codecvt(name, buf, 0, &__err_code);
- if (!_M_codecvt)
- locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
- }
- codecvt_byname<wchar_t, char, mbstate_t>::~codecvt_byname()
- { _STLP_PRIV __release_codecvt(_M_codecvt); }
- codecvt<wchar_t, char, mbstate_t>::result
- codecvt_byname<wchar_t, char, mbstate_t>::do_out(state_type& state,
- const intern_type* from,
- const intern_type* from_end,
- const intern_type*& from_next,
- extern_type* to,
- extern_type* to_limit,
- extern_type*& to_next) const {
- while (from != from_end && to != to_limit) {
- size_t chars_stored = _WLocale_wctomb(_M_codecvt,
- to, to_limit - to, *from,
- &state);
- if (chars_stored == (size_t) -1) {
- from_next = from;
- to_next = to;
- return error;
- }
- else if (chars_stored == (size_t) -2) {
- from_next = from;
- to_next = to;
- return partial;
- }
- ++from;
- to += chars_stored;
- }
- from_next = from;
- to_next = to;
- return ok;
- }
- codecvt<wchar_t, char, mbstate_t>::result
- codecvt_byname<wchar_t, char, mbstate_t>::do_in(state_type& state,
- const extern_type* from,
- const extern_type* from_end,
- const extern_type*& from_next,
- intern_type* to,
- intern_type* to_end,
- intern_type*& to_next) const {
- while (from != from_end && to != to_end) {
- size_t chars_read = _WLocale_mbtowc(_M_codecvt,
- to, from, from_end - from,
- &state);
- if (chars_read == (size_t) -1) {
- from_next = from;
- to_next = to;
- return error;
- }
- if (chars_read == (size_t) -2) {
- from_next = from;
- to_next = to;
- return partial;
- }
- from += chars_read;
- to++;
- }
- from_next = from;
- to_next = to;
- return ok;
- }
- codecvt<wchar_t, char, mbstate_t>::result
- codecvt_byname<wchar_t, char, mbstate_t>::do_unshift(state_type& state,
- extern_type* to,
- extern_type* to_limit,
- extern_type*& to_next) const {
- to_next = to;
- size_t result = _WLocale_unshift(_M_codecvt, &state,
- to, to_limit - to, &to_next);
- if (result == (size_t) -1)
- return error;
- else if (result == (size_t) -2)
- return partial;
- else
- # if defined (__ISCPP__)
- return /*to_next == to ? noconv :*/ ok;
- # else
- return to_next == to ? noconv : ok;
- # endif
- }
- int
- codecvt_byname<wchar_t, char, mbstate_t>::do_encoding() const _STLP_NOTHROW {
- if (_WLocale_is_stateless(_M_codecvt)) {
- int max_width = _WLocale_mb_cur_max(_M_codecvt);
- int min_width = _WLocale_mb_cur_min(_M_codecvt);
- return min_width == max_width ? min_width : 0;
- }
- else
- return -1;
- }
- bool
- codecvt_byname<wchar_t, char, mbstate_t>::do_always_noconv() const _STLP_NOTHROW
- { return false; }
- int
- codecvt_byname<wchar_t, char, mbstate_t>::do_length(state_type& state,
- const extern_type* from,
- const extern_type* end,
- size_t mx) const {
- size_t __count = 0;
- while (from != end && mx--) {
- intern_type __dummy;
- size_t chars_read = _WLocale_mbtowc(_M_codecvt,
- &__dummy, from, end - from,
- &state);
- if ((chars_read == (size_t) -1) || (chars_read == (size_t) -2)) // error or partial
- break;
- __count += chars_read;
- from += chars_read;
- }
- return int(__count);
- }
- int
- codecvt_byname<wchar_t, char, mbstate_t>::do_max_length() const _STLP_NOTHROW
- { return _WLocale_mb_cur_max(_M_codecvt); }
- #endif
- // numpunct_byname<char>
- numpunct_byname<char>::numpunct_byname(const char* name, size_t refs)
- : numpunct<char>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_numeric = _STLP_PRIV __acquire_numeric(name, buf, 0, &__err_code);
- if (!_M_numeric)
- locale::_M_throw_on_creation_failure(__err_code, name, "numpunct");
- }
- numpunct_byname<char>::~numpunct_byname()
- { _STLP_PRIV __release_numeric(_M_numeric); }
- char numpunct_byname<char>::do_decimal_point() const
- { return _Locale_decimal_point(_M_numeric); }
- char numpunct_byname<char>::do_thousands_sep() const
- { return _Locale_thousands_sep(_M_numeric); }
- string numpunct_byname<char>::do_grouping() const {
- const char * __grouping = _Locale_grouping(_M_numeric);
- if (__grouping != NULL && __grouping[0] == CHAR_MAX)
- __grouping = "";
- return __grouping;
- }
- string numpunct_byname<char>::do_truename() const
- { return _Locale_true(_M_numeric); }
- string numpunct_byname<char>::do_falsename() const
- { return _Locale_false(_M_numeric); }
- //----------------------------------------------------------------------
- // numpunct<wchar_t>
- #if !defined (_STLP_NO_WCHAR_T)
- // numpunct_byname<wchar_t>
- numpunct_byname<wchar_t>::numpunct_byname(const char* name, size_t refs)
- : numpunct<wchar_t>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_numeric = _STLP_PRIV __acquire_numeric(name, buf, 0, &__err_code);
- if (!_M_numeric)
- locale::_M_throw_on_creation_failure(__err_code, name, "numpunct");
- }
- numpunct_byname<wchar_t>::~numpunct_byname()
- { _STLP_PRIV __release_numeric(_M_numeric); }
- wchar_t numpunct_byname<wchar_t>::do_decimal_point() const
- { return _WLocale_decimal_point(_M_numeric); }
- wchar_t numpunct_byname<wchar_t>::do_thousands_sep() const
- { return _WLocale_thousands_sep(_M_numeric); }
- string numpunct_byname<wchar_t>::do_grouping() const {
- const char * __grouping = _Locale_grouping(_M_numeric);
- if (__grouping != NULL && __grouping[0] == CHAR_MAX)
- __grouping = "";
- return __grouping;
- }
- wstring numpunct_byname<wchar_t>::do_truename() const {
- wchar_t buf[16];
- return _WLocale_true(_M_numeric, _STLP_ARRAY_AND_SIZE(buf));
- }
- wstring numpunct_byname<wchar_t>::do_falsename() const {
- wchar_t buf[16];
- return _WLocale_false(_M_numeric, _STLP_ARRAY_AND_SIZE(buf));
- }
- #endif
- _STLP_MOVE_TO_PRIV_NAMESPACE
- static void _Init_monetary_formats(money_base::pattern& pos_format,
- money_base::pattern& neg_format,
- _Locale_monetary * monetary) {
- switch (_Locale_p_sign_posn(monetary)) {
- case 0: // Parentheses surround the quantity and currency symbol
- case 1: // The sign string precedes the quantity and currency symbol
- pos_format.field[0] = (char) money_base::sign;
- if (_Locale_p_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a positive value
- pos_format.field[1] = (char) money_base::symbol;
- if (_Locale_p_sep_by_space(monetary)) {
- // a space separates currency symbol from a positive value.
- pos_format.field[2] = (char) money_base::space;
- pos_format.field[3] = (char) money_base::value;
- } else {
- // a space not separates currency symbol from a positive value.
- pos_format.field[2] = (char) money_base::value;
- pos_format.field[3] = (char) money_base::none;
- }
- } else {
- // 0 if currency symbol succeeds a positive value
- pos_format.field[1] = (char) money_base::value;
- if (_Locale_p_sep_by_space(monetary)) {
- // a space separates currency symbol from a positive value.
- pos_format.field[2] = (char) money_base::space;
- pos_format.field[3] = (char) money_base::symbol;
- } else {
- // a space not separates currency symbol from a positive value.
- pos_format.field[2] = (char) money_base::symbol;
- pos_format.field[3] = (char) money_base::none;
- }
- }
- break;
- case 2: // The sign string succeeds the quantity and currency symbol.
- if (_Locale_p_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a positive value
- pos_format.field[0] = (char) money_base::symbol;
- if (_Locale_p_sep_by_space(monetary)) {
- // a space separates currency symbol from a positive value.
- pos_format.field[1] = (char) money_base::space;
- pos_format.field[2] = (char) money_base::value;
- pos_format.field[3] = (char) money_base::sign;
- } else {
- // a space not separates currency symbol from a positive value.
- pos_format.field[1] = (char) money_base::value;
- pos_format.field[2] = (char) money_base::sign;
- pos_format.field[3] = (char) money_base::none;
- }
- } else {
- // 0 if currency symbol succeeds a positive value
- pos_format.field[0] = (char) money_base::value;
- if (_Locale_p_sep_by_space(monetary)) {
- // a space separates currency symbol from a positive value.
- pos_format.field[1] = (char) money_base::space;
- pos_format.field[2] = (char) money_base::symbol;
- pos_format.field[3] = (char) money_base::sign;
- } else {
- // a space not separates currency symbol from a positive value.
- pos_format.field[1] = (char) money_base::symbol;
- pos_format.field[2] = (char) money_base::sign;
- pos_format.field[3] = (char) money_base::none;
- }
- }
- break;
- case 3: // The sign string immediately precedes the currency symbol.
- if (_Locale_p_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a positive value
- pos_format.field[0] = (char) money_base::sign;
- pos_format.field[1] = (char) money_base::symbol;
- if (_Locale_p_sep_by_space(monetary)) {
- // a space separates currency symbol from a positive value.
- pos_format.field[2] = (char) money_base::space;
- pos_format.field[3] = (char) money_base::value;
- } else {
- // a space not separates currency symbol from a positive value.
- pos_format.field[2] = (char) money_base::value;
- pos_format.field[3] = (char) money_base::none;
- }
- } else {
- // 0 if currency symbol succeeds a positive value
- pos_format.field[0] = (char) money_base::value;
- pos_format.field[1] = (char) money_base::sign;
- pos_format.field[2] = (char) money_base::symbol;
- pos_format.field[3] = (char) money_base::none;
- }
- break;
- case 4: // The sign string immediately succeeds the currency symbol.
- if (_Locale_p_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a positive value
- pos_format.field[0] = (char) money_base::symbol;
- pos_format.field[1] = (char) money_base::sign;
- pos_format.field[2] = (char) money_base::value;
- pos_format.field[3] = (char) money_base::none;
- } else {
- // 0 if currency symbol succeeds a positive value
- pos_format.field[0] = (char) money_base::value;
- if (_Locale_p_sep_by_space(monetary)) {
- // a space separates currency symbol from a positive value.
- pos_format.field[1] = (char) money_base::space;
- pos_format.field[2] = (char) money_base::symbol;
- pos_format.field[3] = (char) money_base::sign;
- } else {
- // a space not separates currency symbol from a positive value.
- pos_format.field[1] = (char) money_base::symbol;
- pos_format.field[2] = (char) money_base::sign;
- pos_format.field[3] = (char) money_base::none;
- }
- }
- break;
- default: // Default C++ Standard format
- pos_format.field[0] = (char) money_base::symbol;
- pos_format.field[1] = (char) money_base::sign;
- pos_format.field[2] = (char) money_base::none;
- pos_format.field[3] = (char) money_base::value;
- break;
- }
- switch (_Locale_n_sign_posn(monetary)) {
- case 0: // Parentheses surround the quantity and currency symbol
- case 1: // The sign string precedes the quantity and currency symbol
- neg_format.field[0] = (char) money_base::sign;
- if (_Locale_n_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a negative value
- neg_format.field[1] = (char) money_base::symbol;
- if (_Locale_n_sep_by_space(monetary)) {
- // a space separates currency symbol from a negative value.
- neg_format.field[2] = (char) money_base::space;
- neg_format.field[3] = (char) money_base::value;
- } else {
- // a space not separates currency symbol from a negative value.
- neg_format.field[2] = (char) money_base::value;
- neg_format.field[3] = (char) money_base::none;
- }
- } else {
- // 0 if currency symbol succeeds a negative value
- neg_format.field[1] = (char) money_base::value;
- if (_Locale_n_sep_by_space(monetary)) {
- // a space separates currency symbol from a negative value.
- neg_format.field[2] = (char) money_base::space;
- neg_format.field[3] = (char) money_base::symbol;
- } else {
- // a space not separates currency symbol from a negative value.
- neg_format.field[2] = (char) money_base::symbol;
- neg_format.field[3] = (char) money_base::none;
- }
- }
- break;
- case 2: // The sign string succeeds the quantity and currency symbol.
- if (_Locale_n_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a negative value
- neg_format.field[0] = (char) money_base::symbol;
- if (_Locale_n_sep_by_space(monetary)) {
- // a space separates currency symbol from a negative value.
- neg_format.field[1] = (char) money_base::space;
- neg_format.field[2] = (char) money_base::value;
- neg_format.field[3] = (char) money_base::sign;
- } else {
- // a space not separates currency symbol from a negative value.
- neg_format.field[1] = (char) money_base::value;
- neg_format.field[2] = (char) money_base::sign;
- neg_format.field[3] = (char) money_base::none;
- }
- } else {
- // 0 if currency symbol succeeds a negative value
- neg_format.field[0] = (char) money_base::value;
- if (_Locale_n_sep_by_space(monetary)) {
- // a space separates currency symbol from a negative value.
- neg_format.field[1] = (char) money_base::space;
- neg_format.field[2] = (char) money_base::symbol;
- neg_format.field[3] = (char) money_base::sign;
- } else {
- // a space not separates currency symbol from a negative value.
- neg_format.field[1] = (char) money_base::symbol;
- neg_format.field[2] = (char) money_base::sign;
- neg_format.field[3] = (char) money_base::none;
- }
- }
- break;
- case 3: // The sign string immediately precedes the currency symbol.
- if (_Locale_n_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a negative value
- neg_format.field[0] = (char) money_base::sign;
- neg_format.field[1] = (char) money_base::symbol;
- if (_Locale_n_sep_by_space(monetary)) {
- // a space separates currency symbol from a negative value.
- neg_format.field[2] = (char) money_base::space;
- neg_format.field[3] = (char) money_base::value;
- } else {
- // a space not separates currency symbol from a negative value.
- neg_format.field[2] = (char) money_base::value;
- neg_format.field[3] = (char) money_base::none;
- }
- } else {
- // 0 if currency symbol succeeds a negative value
- neg_format.field[0] = (char) money_base::value;
- neg_format.field[1] = (char) money_base::sign;
- neg_format.field[2] = (char) money_base::symbol;
- neg_format.field[3] = (char) money_base::none;
- }
- break;
- case 4: // The sign string immediately succeeds the currency symbol.
- if (_Locale_n_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a negative value
- neg_format.field[0] = (char) money_base::symbol;
- neg_format.field[1] = (char) money_base::sign;
- neg_format.field[2] = (char) money_base::none;
- neg_format.field[3] = (char) money_base::value;
- } else {
- // 0 if currency symbol succeeds a negative value
- neg_format.field[0] = (char) money_base::value;
- if (_Locale_n_sep_by_space(monetary)) {
- // a space separates currency symbol from a negative value.
- neg_format.field[1] = (char) money_base::space;
- neg_format.field[2] = (char) money_base::symbol;
- neg_format.field[3] = (char) money_base::sign;
- } else {
- // a space not separates currency symbol from a negative value.
- neg_format.field[1] = (char) money_base::symbol;
- neg_format.field[2] = (char) money_base::sign;
- neg_format.field[3] = (char) money_base::none;
- }
- }
- break;
- default: // Default C++ Standard format
- neg_format.field[0] = (char) money_base::symbol;
- neg_format.field[1] = (char) money_base::sign;
- neg_format.field[2] = (char) money_base::none;
- neg_format.field[3] = (char) money_base::value;
- break;
- }
- }
- // international variant of monetary
- /*
- * int_curr_symbol
- *
- * The international currency symbol. The operand is a four-character
- * string, with the first three characters containing the alphabetic
- * international currency symbol in accordance with those specified
- * in the ISO 4217 specification. The fourth character is the character used
- * to separate the international currency symbol from the monetary quantity.
- *
- * (http://www.opengroup.org/onlinepubs/7990989775/xbd/locale.html)
- */
- /*
- * Standards are unclear in the usage of international currency
- * and monetary formats.
- * But I am expect that international currency symbol should be the first
- * (not depends upon where currency symbol situated in the national
- * format).
- *
- * If this isn't so, let's see:
- * 1 234.56 RUR
- * GBP 1,234.56
- * USD 1,234.56
- * The situation really is worse than you see above:
- * RUR typed wrong here---it prints '1 234.56 RUR ' (see space after RUR).
- * This is due to intl_fmp.curr_symbol() == "RUR ". (see reference in comments
- * above).
- *
- */
- static void _Init_monetary_formats_int(money_base::pattern& pos_format,
- money_base::pattern& neg_format,
- _Locale_monetary * monetary)
- {
- switch (_Locale_p_sign_posn(monetary)) {
- case 0: // Parentheses surround the quantity and currency symbol
- case 1: // The sign string precedes the quantity and currency symbol
- pos_format.field[0] = (char) money_base::symbol;
- pos_format.field[1] = (char) money_base::sign;
- pos_format.field[2] = (char) money_base::value;
- pos_format.field[3] = (char) money_base::none;
- break;
- case 2: // The sign string succeeds the quantity and currency symbol.
- pos_format.field[0] = (char) money_base::symbol;
- pos_format.field[1] = (char) money_base::value;
- pos_format.field[2] = (char) money_base::sign;
- pos_format.field[3] = (char) money_base::none;
- break;
- case 3: // The sign string immediately precedes the currency symbol.
- case 4: // The sign string immediately succeeds the currency symbol.
- pos_format.field[0] = (char) money_base::symbol;
- if (_Locale_p_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a positive value
- pos_format.field[1] = (char) money_base::sign;
- pos_format.field[2] = (char) money_base::value;
- } else {
- // 0 if currency symbol succeeds a positive value
- pos_format.field[1] = (char) money_base::value;
- pos_format.field[2] = (char) money_base::sign;
- }
- pos_format.field[3] = (char) money_base::none;
- break;
- default: // Default C++ Standard format
- pos_format.field[0] = (char) money_base::symbol;
- pos_format.field[1] = (char) money_base::sign;
- pos_format.field[2] = (char) money_base::none;
- pos_format.field[3] = (char) money_base::value;
- break;
- }
- switch (_Locale_n_sign_posn(monetary)) {
- case 0: // Parentheses surround the quantity and currency symbol
- case 1: // The sign string precedes the quantity and currency symbol
- neg_format.field[0] = (char) money_base::symbol;
- neg_format.field[1] = (char) money_base::sign;
- neg_format.field[2] = (char) money_base::value;
- neg_format.field[3] = (char) money_base::none;
- break;
- case 2: // The sign string succeeds the quantity and currency symbol.
- neg_format.field[0] = (char) money_base::symbol;
- neg_format.field[1] = (char) money_base::value;
- neg_format.field[2] = (char) money_base::sign;
- neg_format.field[3] = (char) money_base::none;
- break;
- case 3: // The sign string immediately precedes the currency symbol.
- case 4: // The sign string immediately succeeds the currency symbol.
- neg_format.field[0] = (char) money_base::symbol;
- if (_Locale_n_cs_precedes(monetary)) {
- // 1 if currency symbol precedes a negative value
- neg_format.field[1] = (char) money_base::sign;
- neg_format.field[2] = (char) money_base::value;
- } else {
- // 0 if currency symbol succeeds a negative value
- neg_format.field[1] = (char) money_base::value;
- neg_format.field[2] = (char) money_base::sign;
- }
- neg_format.field[3] = (char) money_base::none;
- break;
- default: // Default C++ Standard format
- neg_format.field[0] = (char) money_base::symbol;
- neg_format.field[1] = (char) money_base::sign;
- neg_format.field[2] = (char) money_base::none;
- neg_format.field[3] = (char) money_base::value;
- break;
- }
- }
- _STLP_MOVE_TO_STD_NAMESPACE
- //
- // moneypunct_byname<>
- //
- moneypunct_byname<char, true>::moneypunct_byname(const char * name,
- size_t refs)
- : moneypunct<char, true>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code);
- if (!_M_monetary)
- locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct");
- _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
- }
- moneypunct_byname<char, true>::moneypunct_byname(_Locale_monetary *__mon)
- : _M_monetary(__mon) {
- _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
- }
- moneypunct_byname<char, true>::~moneypunct_byname()
- { _STLP_PRIV __release_monetary(_M_monetary); }
- char moneypunct_byname<char, true>::do_decimal_point() const
- { return _Locale_mon_decimal_point(_M_monetary); }
- char moneypunct_byname<char, true>::do_thousands_sep() const
- { return _Locale_mon_thousands_sep(_M_monetary); }
- string moneypunct_byname<char, true>::do_grouping() const
- { return _Locale_mon_grouping(_M_monetary); }
- string moneypunct_byname<char, true>::do_curr_symbol() const
- { return _Locale_int_curr_symbol(_M_monetary); }
- string moneypunct_byname<char, true>::do_positive_sign() const
- { return _Locale_positive_sign(_M_monetary); }
- string moneypunct_byname<char, true>::do_negative_sign() const
- { return _Locale_negative_sign(_M_monetary); }
- int moneypunct_byname<char, true>::do_frac_digits() const
- { return _Locale_int_frac_digits(_M_monetary); }
- moneypunct_byname<char, false>::moneypunct_byname(const char * name,
- size_t refs)
- : moneypunct<char, false>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code);
- if (!_M_monetary)
- locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct");
- _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
- }
- moneypunct_byname<char, false>::moneypunct_byname(_Locale_monetary *__mon)
- : _M_monetary(__mon) {
- _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
- }
- moneypunct_byname<char, false>::~moneypunct_byname()
- { _STLP_PRIV __release_monetary(_M_monetary); }
- char moneypunct_byname<char, false>::do_decimal_point() const
- { return _Locale_mon_decimal_point(_M_monetary); }
- char moneypunct_byname<char, false>::do_thousands_sep() const
- { return _Locale_mon_thousands_sep(_M_monetary); }
- string moneypunct_byname<char, false>::do_grouping() const
- { return _Locale_mon_grouping(_M_monetary); }
- string moneypunct_byname<char, false>::do_curr_symbol() const
- { return _Locale_currency_symbol(_M_monetary); }
- string moneypunct_byname<char, false>::do_positive_sign() const
- { return _Locale_positive_sign(_M_monetary); }
- string moneypunct_byname<char, false>::do_negative_sign() const
- { return _Locale_negative_sign(_M_monetary); }
- int moneypunct_byname<char, false>::do_frac_digits() const
- { return _Locale_frac_digits(_M_monetary); }
- //
- // moneypunct_byname<wchar_t>
- //
- #if !defined (_STLP_NO_WCHAR_T)
- moneypunct_byname<wchar_t, true>::moneypunct_byname(const char * name,
- size_t refs)
- : moneypunct<wchar_t, true>(refs) {
- if (!name)
- locale::_M_throw_on_null_name();
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code);
- if (!_M_monetary)
- locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct");
- _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
- }
- moneypunct_byname<wchar_t, true>::moneypunct_byname(_Locale_monetary *__mon)
- : _M_monetary(__mon) {
- _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
- }
- moneypunct_byname<wchar_t, true>::~moneypunct_byname()
- { _STLP_PRIV __release_monetary(_M_monetary); }
- wchar_t moneypunct_byname<wchar_t, true>::do_decimal_point() const
- { return _Locale_mon_decimal_point(_M_monetary); }
- wchar_t moneypunct_byname<wchar_t, true>::do_thousands_sep() const
- { return _Locale_mon_thousands_sep(_M_monetary); }
- string moneypunct_byname<wchar_t, true>::do_grouping() const
- { return _Locale_mon_grouping(_M_monetary); }
- inline wstring __do_widen (string const& str) {
- #if defined (_STLP_NO_MEMBER_TEMPLATES) || defined (_STLP_MSVC)
- wstring::_Reserve_t __Reserve;
- size_t __size = str.size();
- wstring result(__Reserve, __size);
- copy(str.begin(), str.end(), result.begin());
- #else
- wstring result(str.begin(), str.end());
- #endif
- return result;
- }
- wstring moneypunct_byname<wchar_t, true>::do_curr_symbol() const
- { wchar_t buf[16]; return _WLocale_int_curr_symbol(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
- wstring moneypunct_byname<wchar_t, true>::do_positive_sign() const
- { wchar_t buf[16]; return _WLocale_positive_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
- wstring moneypunct_byname<wchar_t, true>::do_negative_sign() const
- { wchar_t buf[16]; return _WLocale_negative_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
- int moneypunct_byname<wchar_t, true>::do_frac_digits() const
- { return _Locale_int_frac_digits(_M_monetary); }
- moneypunct_byname<wchar_t, false>::moneypunct_byname(const char * name,
- size_t refs)
- : moneypunct<wchar_t, false>(refs) {
- if (!name)
- locale::_M_throw_on_null_name() ;
- int __err_code;
- char buf[_Locale_MAX_SIMPLE_NAME];
- _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code);
- if (!_M_monetary)
- locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct");
- _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
- }
- moneypunct_byname<wchar_t, false>::moneypunct_byname(_Locale_monetary *__mon)
- : _M_monetary(__mon) {
- _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
- }
- moneypunct_byname<wchar_t, false>::~moneypunct_byname()
- { _STLP_PRIV __release_monetary(_M_monetary); }
- wchar_t moneypunct_byname<wchar_t, false>::do_decimal_point() const
- { return _Locale_mon_decimal_point(_M_monetary); }
- wchar_t moneypunct_byname<wchar_t, false>::do_thousands_sep() const
- { return _Locale_mon_thousands_sep(_M_monetary); }
- string moneypunct_byname<wchar_t, false>::do_grouping() const
- { return _Locale_mon_grouping(_M_monetary); }
- wstring moneypunct_byname<wchar_t, false>::do_curr_symbol() const
- { wchar_t buf[16]; return _WLocale_currency_symbol(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
- wstring moneypunct_byname<wchar_t, false>::do_positive_sign() const
- { wchar_t buf[16]; return _WLocale_positive_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
- wstring moneypunct_byname<wchar_t, false>::do_negative_sign() const
- { wchar_t buf[16]; return _WLocale_negative_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
- int moneypunct_byname<wchar_t, false>::do_frac_digits() const
- { return _Locale_frac_digits(_M_monetary); }
- #endif
- _STLP_END_NAMESPACE
|