build/stlport/src/facets_byname.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /*
     2  * Copyright (c) 1999
     3  * Silicon Graphics Computer Systems, Inc.
     4  *
     5  * Copyright (c) 1999
     6  * Boris Fomitchev
     7  *
     8  * This material is provided "as is", with absolutely no warranty expressed
     9  * or implied. Any use is at your own risk.
    10  *
    11  * Permission to use or copy this software for any purpose is hereby granted
    12  * without fee, provided the above notices are retained on all copies.
    13  * Permission to modify the code and to distribute modified code is granted,
    14  * provided the above notices are retained, and a notice that the code was
    15  * modified is included with the above copyright notice.
    16  *
    17  */
    18 #include "stlport_prefix.h"
    20 #include <hash_map>
    21 #include <vector>
    23 #include <locale>
    24 #include <istream>
    26 #include <algorithm>
    27 #include <functional>
    29 #include "c_locale.h"
    30 #include "locale_impl.h"
    31 #include "acquire_release.h"
    33 _STLP_BEGIN_NAMESPACE
    35 //----------------------------------------------------------------------
    36 // ctype_byname<char>
    38 #if defined (__DMC__)
    39 _STLP_DECLSPEC
    40 #endif
    41 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
    42     : ctype<char>( 0, false, refs) {
    43   if (!name)
    44     locale::_M_throw_on_null_name();
    46   int __err_code;
    47   char buf[_Locale_MAX_SIMPLE_NAME];
    48   _M_ctype = _STLP_PRIV __acquire_ctype(name, buf, 0, &__err_code);
    49   if (!_M_ctype)
    50     locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
    52   _M_init();
    53 }
    55 void ctype_byname<char>::_M_init() {
    56   _M_ctype_table = _M_byname_table;
    58   // We have to do this, instead of just pointer twiddling, because
    59   // ctype_base::mask isn't the same type as _Locale_mask_t.
    60   const _Locale_mask_t* p = _Locale_ctype_table(_M_ctype);
    61   for (size_t i = 0; i != table_size; ++i) {
    62     _M_byname_table[i] = ctype_base::mask(p[i]);
    63   }
    64 }
    66 ctype_byname<char>::~ctype_byname()
    67 { _STLP_PRIV __release_ctype(_M_ctype); }
    69 char ctype_byname<char>::do_toupper(char c) const
    70 { return (char)_Locale_toupper(_M_ctype, c); }
    72 char ctype_byname<char>::do_tolower(char c) const
    73 { return (char)_Locale_tolower(_M_ctype, c); }
    75 const char*
    76 ctype_byname<char>::do_toupper(char* first, const char* last) const {
    77   for ( ; first != last ; ++first)
    78     *first = (char)_Locale_toupper(_M_ctype, *first);
    79   return last;
    80 }
    82 const char*
    83 ctype_byname<char>::do_tolower(char* first, const char* last) const {
    84   for ( ; first != last ; ++first)
    85     *first = (char)_Locale_tolower(_M_ctype, *first);
    86   return last;
    87 }
    90 // Some helper functions used in ctype<>::scan_is and scan_is_not.
    91 #if !defined (_STLP_NO_WCHAR_T)
    93 _STLP_MOVE_TO_PRIV_NAMESPACE
    95 // ctype_byname<wchar_t>
    97 struct _Ctype_byname_w_is_mask : public unary_function<wchar_t, bool> {
    98   _Locale_mask_t M;
    99   _Locale_ctype* M_ctp;
   101   _Ctype_byname_w_is_mask(_Locale_mask_t m, _Locale_ctype* c)
   102     : M(m), M_ctp(c) {}
   103   bool operator()(wchar_t c) const
   104   { return _WLocale_ctype(M_ctp, c, M) != 0; }
   105 };
   107 _STLP_MOVE_TO_STD_NAMESPACE
   109 #if defined (__DMC__)
   110 _STLP_DECLSPEC
   111 #endif
   112 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
   113   : ctype<wchar_t>(refs) {
   114   if (!name)
   115     locale::_M_throw_on_null_name();
   117   int __err_code;
   118   char buf[_Locale_MAX_SIMPLE_NAME];
   119   _M_ctype = _STLP_PRIV __acquire_ctype(name, buf, 0, &__err_code);
   120   if (!_M_ctype)
   121     locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
   122 }
   124 ctype_byname<wchar_t>::~ctype_byname()
   125 { _STLP_PRIV __release_ctype(_M_ctype); }
   127 bool ctype_byname<wchar_t>::do_is(ctype_base::mask  m, wchar_t c) const
   128 { return _WLocale_ctype(_M_ctype, c, (_Locale_mask_t)m) != 0; }
   130 const wchar_t*
   131 ctype_byname<wchar_t>::do_is(const wchar_t* low, const wchar_t* high,
   132                              ctype_base::mask * m) const {
   133   _Locale_mask_t all_bits = _Locale_mask_t(ctype_base::space |
   134                                            ctype_base::print |
   135                                            ctype_base::cntrl |
   136                                            ctype_base::upper |
   137                                            ctype_base::lower |
   138                                            ctype_base::alpha |
   139                                            ctype_base::digit |
   140                                            ctype_base::punct |
   141                                            ctype_base::xdigit);
   143   for ( ; low < high; ++low, ++m)
   144     *m = ctype_base::mask (_WLocale_ctype(_M_ctype, *low, all_bits));
   145   return high;
   146 }
   148 const wchar_t*
   149 ctype_byname<wchar_t>
   150   ::do_scan_is(ctype_base::mask  m, const wchar_t* low, const wchar_t* high) const
   151 { return find_if(low, high, _STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype)); }
   153 const wchar_t*
   154 ctype_byname<wchar_t>
   155   ::do_scan_not(ctype_base::mask  m, const wchar_t* low, const wchar_t* high) const
   156 { return find_if(low, high, not1(_STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype))); }
   158 wchar_t ctype_byname<wchar_t>::do_toupper(wchar_t c) const
   159 { return _WLocale_toupper(_M_ctype, c); }
   161 const wchar_t*
   162 ctype_byname<wchar_t>::do_toupper(wchar_t* low, const wchar_t* high) const {
   163   for ( ; low < high; ++low)
   164     *low = _WLocale_toupper(_M_ctype, *low);
   165   return high;
   166 }
   168 wchar_t ctype_byname<wchar_t>::do_tolower(wchar_t c) const
   169 { return _WLocale_tolower(_M_ctype, c); }
   171 const wchar_t*
   172 ctype_byname<wchar_t>::do_tolower(wchar_t* low, const wchar_t* high) const {
   173   for ( ; low < high; ++low)
   174     *low = _WLocale_tolower(_M_ctype, *low);
   175   return high;
   176 }
   178 #endif /* WCHAR_T */
   180 // collate_byname<char>
   181 #if defined (__DMC__)
   182 _STLP_DECLSPEC
   183 #endif
   184 collate_byname<char>::collate_byname(const char* name, size_t refs)
   185   : collate<char>(refs) {
   186   if (!name)
   187     locale::_M_throw_on_null_name();
   189   int __err_code;
   190   char buf[_Locale_MAX_SIMPLE_NAME];
   191   _M_collate = _STLP_PRIV __acquire_collate(name, buf, 0, &__err_code);
   192   if (!_M_collate)
   193     locale::_M_throw_on_creation_failure(__err_code, name, "collate");
   194 }
   196 collate_byname<char>::~collate_byname()
   197 { _STLP_PRIV __release_collate(_M_collate); }
   199 int collate_byname<char>::do_compare(const char* __low1,
   200                                      const char* __high1,
   201                                      const char* __low2,
   202                                      const char* __high2) const {
   203   return _Locale_strcmp(_M_collate,
   204                         __low1, __high1 - __low1,
   205                         __low2, __high2 - __low2);
   206 }
   208 collate_byname<char>::string_type
   209 collate_byname<char>::do_transform(const char* low, const char* high) const {
   210   if (low == high)
   211     return string_type();
   213   size_t n = _Locale_strxfrm(_M_collate, NULL, 0, low, high - low);
   215   // NOT PORTABLE.  What we're doing relies on internal details of the
   216   // string implementation.  (Contiguity of string elements and presence
   217   // of trailing zero.)
   218   string_type buf(n, 0);
   219   _Locale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low);
   220   return buf;
   221 }
   224 #if !defined (_STLP_NO_WCHAR_T)
   226 // collate_byname<wchar_t>
   228 #if defined (__DMC__)
   229 _STLP_DECLSPEC
   230 #endif
   231 collate_byname<wchar_t>::collate_byname(const char* name, size_t refs)
   232   : collate<wchar_t>(refs) {
   233   if (!name)
   234     locale::_M_throw_on_null_name();
   236   int __err_code;
   237   char buf[_Locale_MAX_SIMPLE_NAME];
   238   _M_collate = _STLP_PRIV __acquire_collate(name, buf, 0, &__err_code);
   239   if (!_M_collate)
   240     locale::_M_throw_on_creation_failure(__err_code, name, "collate");
   241 }
   243 collate_byname<wchar_t>::~collate_byname()
   244 { _STLP_PRIV __release_collate(_M_collate); }
   246 int collate_byname<wchar_t>::do_compare(const wchar_t* low1,
   247                                         const wchar_t* high1,
   248                                         const wchar_t* low2,
   249                                         const wchar_t* high2) const {
   250   return _WLocale_strcmp(_M_collate,
   251                          low1, high1 - low1,
   252                          low2, high2 - low2);
   253 }
   255 collate_byname<wchar_t>::string_type
   256 collate_byname<wchar_t>::do_transform(const wchar_t* low,
   257                                       const wchar_t* high) const {
   258   if (low == high)
   259     return string_type();
   261   size_t n = _WLocale_strxfrm(_M_collate, NULL, 0, low, high - low);
   263   // NOT PORTABLE.  What we're doing relies on internal details of the
   264   // string implementation.  (Contiguity of string elements and presence
   265   // of trailing zero.)
   266   string_type buf(n, 0);
   267   _WLocale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low);
   268   return buf;
   269 }
   271 #endif /*  _STLP_NO_WCHAR_T */
   273 //----------------------------------------------------------------------
   274 // codecvt_byname<char>
   276 codecvt_byname<char, char, mbstate_t>
   277   ::codecvt_byname(const char* name, size_t refs)
   278     : codecvt<char, char, mbstate_t>(refs) {
   279   if (!name)
   280     locale::_M_throw_on_null_name();
   281 }
   283 codecvt_byname<char, char, mbstate_t>::~codecvt_byname() {}
   286 #if !defined (_STLP_NO_WCHAR_T)
   288 //----------------------------------------------------------------------
   289 // codecvt_byname<wchar_t>
   290 codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname(const char* name, size_t refs)
   291   : codecvt<wchar_t, char, mbstate_t>(refs) {
   292   if (!name)
   293     locale::_M_throw_on_null_name();
   295   int __err_code;
   296   char buf[_Locale_MAX_SIMPLE_NAME];
   297   _M_codecvt = _STLP_PRIV __acquire_codecvt(name, buf, 0, &__err_code);
   298   if (!_M_codecvt)
   299     locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
   300 }
   302 codecvt_byname<wchar_t, char, mbstate_t>::~codecvt_byname()
   303 { _STLP_PRIV __release_codecvt(_M_codecvt); }
   305 codecvt<wchar_t, char, mbstate_t>::result
   306 codecvt_byname<wchar_t, char, mbstate_t>::do_out(state_type&         state,
   307                                                  const intern_type*  from,
   308                                                  const intern_type*  from_end,
   309                                                  const intern_type*& from_next,
   310                                                  extern_type*        to,
   311                                                  extern_type*        to_limit,
   312                                                  extern_type*&       to_next) const {
   313   while (from != from_end && to != to_limit) {
   314     size_t chars_stored = _WLocale_wctomb(_M_codecvt,
   315                                           to, to_limit - to, *from,
   316                                           &state);
   317     if (chars_stored == (size_t) -1) {
   318       from_next = from;
   319       to_next   = to;
   320       return error;
   321     }
   322     else if (chars_stored == (size_t) -2) {
   323       from_next = from;
   324       to_next   = to;
   325       return partial;
   326     }
   328     ++from;
   329     to += chars_stored;
   330   }
   332   from_next = from;
   333   to_next   = to;
   334   return ok;
   335 }
   337 codecvt<wchar_t, char, mbstate_t>::result
   338 codecvt_byname<wchar_t, char, mbstate_t>::do_in(state_type&         state,
   339                                                 const extern_type*  from,
   340                                                 const extern_type*  from_end,
   341                                                 const extern_type*& from_next,
   342                                                 intern_type*        to,
   343                                                 intern_type*        to_end,
   344                                                 intern_type*&       to_next) const {
   345   while (from != from_end && to != to_end) {
   346     size_t chars_read = _WLocale_mbtowc(_M_codecvt,
   347                                         to, from, from_end - from,
   348                                         &state);
   349     if (chars_read == (size_t) -1) {
   350       from_next = from;
   351       to_next   = to;
   352       return error;
   353     }
   355     if (chars_read == (size_t) -2) {
   356       from_next = from;
   357       to_next   = to;
   358       return partial;
   359     }
   361     from += chars_read;
   362     to++;
   363   }
   365   from_next = from;
   366   to_next   = to;
   367   return ok;
   368 }
   370 codecvt<wchar_t, char, mbstate_t>::result
   371 codecvt_byname<wchar_t, char, mbstate_t>::do_unshift(state_type&   state,
   372                                                      extern_type*  to,
   373                                                      extern_type*  to_limit,
   374                                                      extern_type*& to_next) const {
   375   to_next = to;
   376   size_t result = _WLocale_unshift(_M_codecvt, &state,
   377                                    to, to_limit - to, &to_next);
   378   if (result == (size_t) -1)
   379     return error;
   380   else if (result == (size_t) -2)
   381     return partial;
   382   else
   383 #    if defined (__ISCPP__)
   384     return /*to_next == to ? noconv :*/ ok;
   385 #    else
   386     return to_next == to ? noconv : ok;
   387 #    endif
   388 }
   390 int
   391 codecvt_byname<wchar_t, char, mbstate_t>::do_encoding() const _STLP_NOTHROW {
   392   if (_WLocale_is_stateless(_M_codecvt)) {
   393     int max_width = _WLocale_mb_cur_max(_M_codecvt);
   394     int min_width = _WLocale_mb_cur_min(_M_codecvt);
   395     return min_width == max_width ? min_width : 0;
   396   }
   397   else
   398     return -1;
   399 }
   401 bool
   402 codecvt_byname<wchar_t, char, mbstate_t>::do_always_noconv() const _STLP_NOTHROW
   403 { return false; }
   405 int
   406 codecvt_byname<wchar_t, char, mbstate_t>::do_length(state_type&         state,
   407                                                     const  extern_type* from,
   408                                                     const  extern_type* end,
   409                                                     size_t              mx) const {
   410   size_t __count = 0;
   411   while (from != end && mx--) {
   412     intern_type __dummy;
   413     size_t chars_read = _WLocale_mbtowc(_M_codecvt,
   414                                         &__dummy, from, end - from,
   415                                         &state);
   416     if ((chars_read == (size_t) -1) || (chars_read == (size_t) -2)) // error or partial
   417       break;
   418     __count += chars_read;
   419     from += chars_read;
   420   }
   421   return int(__count); 
   422 }
   424 int
   425 codecvt_byname<wchar_t, char, mbstate_t>::do_max_length() const _STLP_NOTHROW
   426 { return _WLocale_mb_cur_max(_M_codecvt); }
   427 #endif
   429 // numpunct_byname<char>
   430 numpunct_byname<char>::numpunct_byname(const char* name, size_t refs)
   431 : numpunct<char>(refs) {
   432   if (!name)
   433     locale::_M_throw_on_null_name();
   435   int __err_code;
   436   char buf[_Locale_MAX_SIMPLE_NAME];
   437   _M_numeric = _STLP_PRIV __acquire_numeric(name, buf, 0, &__err_code);
   438   if (!_M_numeric)
   439     locale::_M_throw_on_creation_failure(__err_code, name, "numpunct");
   440 }
   442 numpunct_byname<char>::~numpunct_byname()
   443 { _STLP_PRIV __release_numeric(_M_numeric); }
   445 char numpunct_byname<char>::do_decimal_point() const
   446 { return _Locale_decimal_point(_M_numeric); }
   448 char numpunct_byname<char>::do_thousands_sep() const
   449 { return _Locale_thousands_sep(_M_numeric); }
   451 string numpunct_byname<char>::do_grouping() const {
   452   const char * __grouping = _Locale_grouping(_M_numeric);
   453   if (__grouping != NULL && __grouping[0] == CHAR_MAX)
   454     __grouping = "";
   455   return __grouping;
   456 }
   458 string numpunct_byname<char>::do_truename() const
   459 { return _Locale_true(_M_numeric); }
   461 string numpunct_byname<char>::do_falsename() const
   462 { return _Locale_false(_M_numeric); }
   464 //----------------------------------------------------------------------
   465 // numpunct<wchar_t>
   467 #if !defined (_STLP_NO_WCHAR_T)
   469 // numpunct_byname<wchar_t>
   471 numpunct_byname<wchar_t>::numpunct_byname(const char* name, size_t refs)
   472 : numpunct<wchar_t>(refs) {
   473   if (!name)
   474     locale::_M_throw_on_null_name();
   476   int __err_code;
   477   char buf[_Locale_MAX_SIMPLE_NAME];
   478   _M_numeric = _STLP_PRIV __acquire_numeric(name, buf, 0, &__err_code);
   479   if (!_M_numeric)
   480     locale::_M_throw_on_creation_failure(__err_code, name, "numpunct");
   481 }
   483 numpunct_byname<wchar_t>::~numpunct_byname()
   484 { _STLP_PRIV __release_numeric(_M_numeric); }
   486 wchar_t numpunct_byname<wchar_t>::do_decimal_point() const
   487 { return _WLocale_decimal_point(_M_numeric); }
   489 wchar_t numpunct_byname<wchar_t>::do_thousands_sep() const
   490 { return _WLocale_thousands_sep(_M_numeric); }
   492 string numpunct_byname<wchar_t>::do_grouping() const {
   493   const char * __grouping = _Locale_grouping(_M_numeric);
   494   if (__grouping != NULL && __grouping[0] == CHAR_MAX)
   495     __grouping = "";
   496   return __grouping;
   497 }
   499 wstring numpunct_byname<wchar_t>::do_truename() const {
   500   wchar_t buf[16];
   501   return _WLocale_true(_M_numeric, _STLP_ARRAY_AND_SIZE(buf));
   502 }
   504 wstring numpunct_byname<wchar_t>::do_falsename() const {
   505   wchar_t buf[16];
   506   return _WLocale_false(_M_numeric, _STLP_ARRAY_AND_SIZE(buf));
   507 }
   509 #endif
   511 _STLP_MOVE_TO_PRIV_NAMESPACE
   513 static void _Init_monetary_formats(money_base::pattern& pos_format,
   514                                    money_base::pattern& neg_format,
   515                                    _Locale_monetary * monetary) {
   516   switch (_Locale_p_sign_posn(monetary)) {
   517     case 0: // Parentheses surround the quantity and currency symbol
   518     case 1: // The sign string precedes the quantity and currency symbol
   519       pos_format.field[0] = (char) money_base::sign;
   520       if (_Locale_p_cs_precedes(monetary)) {
   521         // 1 if currency symbol precedes a positive value
   522         pos_format.field[1] = (char) money_base::symbol;
   523         if (_Locale_p_sep_by_space(monetary)) {
   524           // a space separates currency symbol from a positive value.
   525           pos_format.field[2] = (char) money_base::space;
   526           pos_format.field[3] = (char) money_base::value;
   527         } else {
   528           // a space not separates currency symbol from a positive value.
   529           pos_format.field[2] = (char) money_base::value;
   530           pos_format.field[3] = (char) money_base::none;
   531         }
   532       } else {
   533         // 0 if currency symbol succeeds a positive value
   534         pos_format.field[1] = (char) money_base::value;
   535         if (_Locale_p_sep_by_space(monetary)) {
   536           // a space separates currency symbol from a positive value.
   537           pos_format.field[2] = (char) money_base::space;
   538           pos_format.field[3] = (char) money_base::symbol;
   539         } else {
   540           // a space not separates currency symbol from a positive value.
   541           pos_format.field[2] = (char) money_base::symbol;
   542           pos_format.field[3] = (char) money_base::none;
   543         }
   544       }
   545       break;
   546     case 2: // The sign string succeeds the quantity and currency symbol.
   547       if (_Locale_p_cs_precedes(monetary)) {
   548         // 1 if currency symbol precedes a positive value
   549         pos_format.field[0] = (char) money_base::symbol;
   550         if (_Locale_p_sep_by_space(monetary)) {
   551           // a space separates currency symbol from a positive value.
   552           pos_format.field[1] = (char) money_base::space;
   553           pos_format.field[2] = (char) money_base::value;
   554           pos_format.field[3] = (char) money_base::sign;
   555         } else {
   556           // a space not separates currency symbol from a positive value.
   557           pos_format.field[1] = (char) money_base::value;
   558           pos_format.field[2] = (char) money_base::sign;
   559           pos_format.field[3] = (char) money_base::none;
   560         }
   561       } else {
   562         // 0 if currency symbol succeeds a positive value
   563         pos_format.field[0] = (char) money_base::value;
   564         if (_Locale_p_sep_by_space(monetary)) {
   565           // a space separates currency symbol from a positive value.
   566           pos_format.field[1] = (char) money_base::space;
   567           pos_format.field[2] = (char) money_base::symbol;
   568           pos_format.field[3] = (char) money_base::sign;
   569         } else {
   570           // a space not separates currency symbol from a positive value.
   571           pos_format.field[1] = (char) money_base::symbol;
   572           pos_format.field[2] = (char) money_base::sign;
   573           pos_format.field[3] = (char) money_base::none;
   574         }
   575       }
   576       break;
   577     case 3: // The sign string immediately precedes the currency symbol.
   578       if (_Locale_p_cs_precedes(monetary)) {
   579         // 1 if currency symbol precedes a positive value
   580         pos_format.field[0] = (char) money_base::sign;
   581         pos_format.field[1] = (char) money_base::symbol;
   582         if (_Locale_p_sep_by_space(monetary)) {
   583           // a space separates currency symbol from a positive value.
   584           pos_format.field[2] = (char) money_base::space;
   585           pos_format.field[3] = (char) money_base::value;
   586         } else {
   587           // a space not separates currency symbol from a positive value.
   588           pos_format.field[2] = (char) money_base::value;
   589           pos_format.field[3] = (char) money_base::none;
   590         }
   591       } else {
   592         // 0 if currency symbol succeeds a positive value
   593         pos_format.field[0] = (char) money_base::value;
   594         pos_format.field[1] = (char) money_base::sign;
   595         pos_format.field[2] = (char) money_base::symbol;
   596         pos_format.field[3] = (char) money_base::none;
   597       }
   598       break;
   599     case 4: // The sign string immediately succeeds the currency symbol.
   600       if (_Locale_p_cs_precedes(monetary)) {
   601         // 1 if currency symbol precedes a positive value
   602         pos_format.field[0] = (char) money_base::symbol;
   603         pos_format.field[1] = (char) money_base::sign;
   604         pos_format.field[2] = (char) money_base::value;
   605         pos_format.field[3] = (char) money_base::none;
   606       } else {
   607         // 0 if currency symbol succeeds a positive value
   608         pos_format.field[0] = (char) money_base::value;
   609         if (_Locale_p_sep_by_space(monetary)) {
   610           // a space separates currency symbol from a positive value.
   611           pos_format.field[1] = (char) money_base::space;
   612           pos_format.field[2] = (char) money_base::symbol;
   613           pos_format.field[3] = (char) money_base::sign;
   614         } else {
   615           // a space not separates currency symbol from a positive value.
   616           pos_format.field[1] = (char) money_base::symbol;
   617           pos_format.field[2] = (char) money_base::sign;
   618           pos_format.field[3] = (char) money_base::none;
   619         }
   620       }
   621       break;
   622     default: // Default C++ Standard format
   623       pos_format.field[0] = (char) money_base::symbol;
   624       pos_format.field[1] = (char) money_base::sign;
   625       pos_format.field[2] = (char) money_base::none;
   626       pos_format.field[3] = (char) money_base::value;
   627       break;
   628   }
   630   switch (_Locale_n_sign_posn(monetary)) {
   631     case 0: // Parentheses surround the quantity and currency symbol
   632     case 1: // The sign string precedes the quantity and currency symbol
   633       neg_format.field[0] = (char) money_base::sign;
   634       if (_Locale_n_cs_precedes(monetary)) {
   635         // 1 if currency symbol precedes a negative value
   636         neg_format.field[1] = (char) money_base::symbol;
   637         if (_Locale_n_sep_by_space(monetary)) {
   638           // a space separates currency symbol from a negative value.
   639           neg_format.field[2] = (char) money_base::space;
   640           neg_format.field[3] = (char) money_base::value;
   641         } else {
   642           // a space not separates currency symbol from a negative value.
   643           neg_format.field[2] = (char) money_base::value;
   644           neg_format.field[3] = (char) money_base::none;
   645         }
   646       } else {
   647         // 0 if currency symbol succeeds a negative value
   648         neg_format.field[1] = (char) money_base::value;
   649         if (_Locale_n_sep_by_space(monetary)) {
   650           // a space separates currency symbol from a negative value.
   651           neg_format.field[2] = (char) money_base::space;
   652           neg_format.field[3] = (char) money_base::symbol;
   653         } else {
   654           // a space not separates currency symbol from a negative value.
   655           neg_format.field[2] = (char) money_base::symbol;
   656           neg_format.field[3] = (char) money_base::none;
   657         }
   658       }
   659       break;
   660     case 2: // The sign string succeeds the quantity and currency symbol.
   661       if (_Locale_n_cs_precedes(monetary)) {
   662         // 1 if currency symbol precedes a negative value
   663         neg_format.field[0] = (char) money_base::symbol;
   664         if (_Locale_n_sep_by_space(monetary)) {
   665           // a space separates currency symbol from a negative value.
   666           neg_format.field[1] = (char) money_base::space;
   667           neg_format.field[2] = (char) money_base::value;
   668           neg_format.field[3] = (char) money_base::sign;
   669         } else {
   670           // a space not separates currency symbol from a negative value.
   671           neg_format.field[1] = (char) money_base::value;
   672           neg_format.field[2] = (char) money_base::sign;
   673           neg_format.field[3] = (char) money_base::none;
   674         }
   675       } else {
   676         // 0 if currency symbol succeeds a negative value
   677         neg_format.field[0] = (char) money_base::value;
   678         if (_Locale_n_sep_by_space(monetary)) {
   679           // a space separates currency symbol from a negative value.
   680           neg_format.field[1] = (char) money_base::space;
   681           neg_format.field[2] = (char) money_base::symbol;
   682           neg_format.field[3] = (char) money_base::sign;
   683         } else {
   684           // a space not separates currency symbol from a negative value.
   685           neg_format.field[1] = (char) money_base::symbol;
   686           neg_format.field[2] = (char) money_base::sign;
   687           neg_format.field[3] = (char) money_base::none;
   688         }
   689       }
   690       break;
   691     case 3: // The sign string immediately precedes the currency symbol.
   692       if (_Locale_n_cs_precedes(monetary)) {
   693         // 1 if currency symbol precedes a negative value
   694         neg_format.field[0] = (char) money_base::sign;
   695         neg_format.field[1] = (char) money_base::symbol;
   696         if (_Locale_n_sep_by_space(monetary)) {
   697           // a space separates currency symbol from a negative value.
   698           neg_format.field[2] = (char) money_base::space;
   699           neg_format.field[3] = (char) money_base::value;
   700         } else {
   701           // a space not separates currency symbol from a negative value.
   702           neg_format.field[2] = (char) money_base::value;
   703           neg_format.field[3] = (char) money_base::none;
   704         }
   705       } else {
   706         // 0 if currency symbol succeeds a negative value
   707         neg_format.field[0] = (char) money_base::value;
   708         neg_format.field[1] = (char) money_base::sign;
   709         neg_format.field[2] = (char) money_base::symbol;
   710         neg_format.field[3] = (char) money_base::none;
   711       }
   712       break;
   713     case 4: // The sign string immediately succeeds the currency symbol.
   714       if (_Locale_n_cs_precedes(monetary)) {
   715         // 1 if currency symbol precedes a negative value
   716         neg_format.field[0] = (char) money_base::symbol;
   717         neg_format.field[1] = (char) money_base::sign;
   718         neg_format.field[2] = (char) money_base::none;
   719         neg_format.field[3] = (char) money_base::value;
   720       } else {
   721         // 0 if currency symbol succeeds a negative value
   722         neg_format.field[0] = (char) money_base::value;
   723         if (_Locale_n_sep_by_space(monetary)) {
   724           // a space separates currency symbol from a negative value.
   725           neg_format.field[1] = (char) money_base::space;
   726           neg_format.field[2] = (char) money_base::symbol;
   727           neg_format.field[3] = (char) money_base::sign;
   728         } else {
   729           // a space not separates currency symbol from a negative value.
   730           neg_format.field[1] = (char) money_base::symbol;
   731           neg_format.field[2] = (char) money_base::sign;
   732           neg_format.field[3] = (char) money_base::none;
   733         }
   734       }
   735       break;
   736     default: // Default C++ Standard format
   737       neg_format.field[0] = (char) money_base::symbol;
   738       neg_format.field[1] = (char) money_base::sign;
   739       neg_format.field[2] = (char) money_base::none;
   740       neg_format.field[3] = (char) money_base::value;
   741       break;
   742   }
   743 }
   745 // international variant of monetary
   747 /*
   748  * int_curr_symbol
   749  *
   750  *   The international currency symbol. The operand is a four-character
   751  *   string, with the first three characters containing the alphabetic
   752  *   international currency symbol in accordance with those specified
   753  *   in the ISO 4217 specification. The fourth character is the character used
   754  *   to separate the international currency symbol from the monetary quantity.
   755  *
   756  * (http://www.opengroup.org/onlinepubs/7990989775/xbd/locale.html)
   757  */
   759 /*
   760  * Standards are unclear in the usage of international currency
   761  * and monetary formats.
   762  * But I am expect that international currency symbol should be the first
   763  * (not depends upon where currency symbol situated in the national
   764  * format).
   765  *
   766  * If this isn't so, let's see:
   767  *       1 234.56 RUR
   768  *       GBP 1,234.56
   769  *       USD 1,234.56
   770  * The situation really is worse than you see above:
   771  * RUR typed wrong here---it prints '1 234.56 RUR ' (see space after RUR).
   772  * This is due to intl_fmp.curr_symbol() == "RUR ". (see reference in comments
   773  * above).
   774  *
   775  */
   777 static void _Init_monetary_formats_int(money_base::pattern& pos_format,
   778                                        money_base::pattern& neg_format,
   779                                        _Locale_monetary * monetary)
   780 {
   782   switch (_Locale_p_sign_posn(monetary)) {
   783     case 0: // Parentheses surround the quantity and currency symbol
   784     case 1: // The sign string precedes the quantity and currency symbol
   785       pos_format.field[0] = (char) money_base::symbol;
   786       pos_format.field[1] = (char) money_base::sign;
   787       pos_format.field[2] = (char) money_base::value;
   788       pos_format.field[3] = (char) money_base::none;
   789       break;
   790     case 2: // The sign string succeeds the quantity and currency symbol.
   791       pos_format.field[0] = (char) money_base::symbol;
   792       pos_format.field[1] = (char) money_base::value;
   793       pos_format.field[2] = (char) money_base::sign;
   794       pos_format.field[3] = (char) money_base::none;
   795       break;
   796     case 3: // The sign string immediately precedes the currency symbol.
   797     case 4: // The sign string immediately succeeds the currency symbol.
   798       pos_format.field[0] = (char) money_base::symbol;
   799       if (_Locale_p_cs_precedes(monetary)) {
   800         // 1 if currency symbol precedes a positive value
   801         pos_format.field[1] = (char) money_base::sign;
   802         pos_format.field[2] = (char) money_base::value;
   803       } else {
   804         // 0 if currency symbol succeeds a positive value
   805         pos_format.field[1] = (char) money_base::value;
   806         pos_format.field[2] = (char) money_base::sign;
   807       }
   808       pos_format.field[3] = (char) money_base::none;
   809       break;
   810     default: // Default C++ Standard format
   811       pos_format.field[0] = (char) money_base::symbol;
   812       pos_format.field[1] = (char) money_base::sign;
   813       pos_format.field[2] = (char) money_base::none;
   814       pos_format.field[3] = (char) money_base::value;
   815       break;
   816   }
   819   switch (_Locale_n_sign_posn(monetary)) {
   820     case 0: // Parentheses surround the quantity and currency symbol
   821     case 1: // The sign string precedes the quantity and currency symbol
   822       neg_format.field[0] = (char) money_base::symbol;
   823       neg_format.field[1] = (char) money_base::sign;
   824       neg_format.field[2] = (char) money_base::value;
   825       neg_format.field[3] = (char) money_base::none;
   826       break;
   827     case 2: // The sign string succeeds the quantity and currency symbol.
   828       neg_format.field[0] = (char) money_base::symbol;
   829       neg_format.field[1] = (char) money_base::value;
   830       neg_format.field[2] = (char) money_base::sign;
   831       neg_format.field[3] = (char) money_base::none;
   832       break;
   833     case 3: // The sign string immediately precedes the currency symbol.
   834     case 4: // The sign string immediately succeeds the currency symbol.
   835       neg_format.field[0] = (char) money_base::symbol;
   836       if (_Locale_n_cs_precedes(monetary)) {
   837         // 1 if currency symbol precedes a negative value
   838         neg_format.field[1] = (char) money_base::sign;
   839         neg_format.field[2] = (char) money_base::value;
   840       } else {
   841         // 0 if currency symbol succeeds a negative value
   842         neg_format.field[1] = (char) money_base::value;
   843         neg_format.field[2] = (char) money_base::sign;
   844       }
   845       neg_format.field[3] = (char) money_base::none;
   846       break;
   847     default: // Default C++ Standard format
   848       neg_format.field[0] = (char) money_base::symbol;
   849       neg_format.field[1] = (char) money_base::sign;
   850       neg_format.field[2] = (char) money_base::none;
   851       neg_format.field[3] = (char) money_base::value;
   852       break;
   853   }
   854 }
   856 _STLP_MOVE_TO_STD_NAMESPACE
   858 //
   859 // moneypunct_byname<>
   860 //
   861 moneypunct_byname<char, true>::moneypunct_byname(const char * name,
   862                                                  size_t refs)
   863     : moneypunct<char, true>(refs) {
   864   if (!name)
   865     locale::_M_throw_on_null_name();
   867   int __err_code;
   868   char buf[_Locale_MAX_SIMPLE_NAME];
   869   _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code);
   870   if (!_M_monetary)
   871     locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct");
   873   _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
   874 }
   876 moneypunct_byname<char, true>::moneypunct_byname(_Locale_monetary *__mon)
   877   : _M_monetary(__mon) {
   878   _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
   879 }
   881 moneypunct_byname<char, true>::~moneypunct_byname()
   882 { _STLP_PRIV __release_monetary(_M_monetary); }
   884 char moneypunct_byname<char, true>::do_decimal_point() const
   885 { return _Locale_mon_decimal_point(_M_monetary); }
   887 char moneypunct_byname<char, true>::do_thousands_sep() const
   888 { return _Locale_mon_thousands_sep(_M_monetary); }
   890 string moneypunct_byname<char, true>::do_grouping() const
   891 { return _Locale_mon_grouping(_M_monetary); }
   893 string moneypunct_byname<char, true>::do_curr_symbol() const
   894 { return _Locale_int_curr_symbol(_M_monetary); }
   896 string moneypunct_byname<char, true>::do_positive_sign() const
   897 { return _Locale_positive_sign(_M_monetary); }
   899 string moneypunct_byname<char, true>::do_negative_sign() const
   900 { return _Locale_negative_sign(_M_monetary); }
   902 int moneypunct_byname<char, true>::do_frac_digits() const
   903 { return _Locale_int_frac_digits(_M_monetary); }
   905 moneypunct_byname<char, false>::moneypunct_byname(const char * name,
   906                                                   size_t refs)
   907     : moneypunct<char, false>(refs) {
   908   if (!name)
   909     locale::_M_throw_on_null_name();
   911   int __err_code;
   912   char buf[_Locale_MAX_SIMPLE_NAME];
   913   _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code);
   914   if (!_M_monetary)
   915     locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct");
   917   _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
   918 }
   920 moneypunct_byname<char, false>::moneypunct_byname(_Locale_monetary *__mon)
   921   : _M_monetary(__mon) {
   922   _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
   923 }
   925 moneypunct_byname<char, false>::~moneypunct_byname()
   926 { _STLP_PRIV __release_monetary(_M_monetary); }
   928 char moneypunct_byname<char, false>::do_decimal_point() const
   929 { return _Locale_mon_decimal_point(_M_monetary); }
   931 char moneypunct_byname<char, false>::do_thousands_sep() const
   932 { return _Locale_mon_thousands_sep(_M_monetary); }
   934 string moneypunct_byname<char, false>::do_grouping() const
   935 { return _Locale_mon_grouping(_M_monetary); }
   937 string moneypunct_byname<char, false>::do_curr_symbol() const
   938 { return _Locale_currency_symbol(_M_monetary); }
   940 string moneypunct_byname<char, false>::do_positive_sign() const
   941 { return _Locale_positive_sign(_M_monetary); }
   943 string moneypunct_byname<char, false>::do_negative_sign() const
   944 { return _Locale_negative_sign(_M_monetary); }
   946 int moneypunct_byname<char, false>::do_frac_digits() const
   947 { return _Locale_frac_digits(_M_monetary); }
   949 //
   950 // moneypunct_byname<wchar_t>
   951 //
   952 #if !defined (_STLP_NO_WCHAR_T)
   954 moneypunct_byname<wchar_t, true>::moneypunct_byname(const char * name,
   955                                                     size_t refs)
   956     : moneypunct<wchar_t, true>(refs) {
   957   if (!name)
   958     locale::_M_throw_on_null_name();
   960   int __err_code;
   961   char buf[_Locale_MAX_SIMPLE_NAME];
   962   _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code);
   963   if (!_M_monetary)
   964     locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct");
   966   _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
   967 }
   969 moneypunct_byname<wchar_t, true>::moneypunct_byname(_Locale_monetary *__mon)
   970   : _M_monetary(__mon) {
   971   _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
   972 }
   974 moneypunct_byname<wchar_t, true>::~moneypunct_byname()
   975 { _STLP_PRIV __release_monetary(_M_monetary); }
   977 wchar_t moneypunct_byname<wchar_t, true>::do_decimal_point() const
   978 { return _Locale_mon_decimal_point(_M_monetary); }
   980 wchar_t moneypunct_byname<wchar_t, true>::do_thousands_sep() const
   981 { return _Locale_mon_thousands_sep(_M_monetary); }
   983 string moneypunct_byname<wchar_t, true>::do_grouping() const
   984 { return _Locale_mon_grouping(_M_monetary); }
   986 inline wstring __do_widen (string const& str) {
   987 #if defined (_STLP_NO_MEMBER_TEMPLATES) || defined (_STLP_MSVC)
   988   wstring::_Reserve_t __Reserve;
   989   size_t __size = str.size();
   990   wstring result(__Reserve, __size);
   991   copy(str.begin(), str.end(), result.begin());
   992 #else
   993   wstring result(str.begin(), str.end());
   994 #endif
   995   return result;
   996 }
   998 wstring moneypunct_byname<wchar_t, true>::do_curr_symbol() const
   999 { wchar_t buf[16]; return _WLocale_int_curr_symbol(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
  1001 wstring moneypunct_byname<wchar_t, true>::do_positive_sign() const
  1002 { wchar_t buf[16]; return _WLocale_positive_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
  1004 wstring moneypunct_byname<wchar_t, true>::do_negative_sign() const
  1005 { wchar_t buf[16]; return _WLocale_negative_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
  1007 int moneypunct_byname<wchar_t, true>::do_frac_digits() const
  1008 { return _Locale_int_frac_digits(_M_monetary); }
  1010 moneypunct_byname<wchar_t, false>::moneypunct_byname(const char * name,
  1011                                                      size_t refs)
  1012     : moneypunct<wchar_t, false>(refs) {
  1013   if (!name)
  1014     locale::_M_throw_on_null_name() ;
  1016   int __err_code;
  1017   char buf[_Locale_MAX_SIMPLE_NAME];
  1018   _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code);
  1019   if (!_M_monetary)
  1020     locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct");
  1022   _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
  1025 moneypunct_byname<wchar_t, false>::moneypunct_byname(_Locale_monetary *__mon)
  1026   : _M_monetary(__mon) {
  1027   _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
  1030 moneypunct_byname<wchar_t, false>::~moneypunct_byname()
  1031 { _STLP_PRIV __release_monetary(_M_monetary); }
  1033 wchar_t moneypunct_byname<wchar_t, false>::do_decimal_point() const
  1034 { return _Locale_mon_decimal_point(_M_monetary); }
  1036 wchar_t moneypunct_byname<wchar_t, false>::do_thousands_sep() const
  1037 { return _Locale_mon_thousands_sep(_M_monetary); }
  1039 string moneypunct_byname<wchar_t, false>::do_grouping() const
  1040 { return _Locale_mon_grouping(_M_monetary); }
  1042 wstring moneypunct_byname<wchar_t, false>::do_curr_symbol() const
  1043 { wchar_t buf[16]; return _WLocale_currency_symbol(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
  1045 wstring moneypunct_byname<wchar_t, false>::do_positive_sign() const
  1046 { wchar_t buf[16]; return _WLocale_positive_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
  1048 wstring moneypunct_byname<wchar_t, false>::do_negative_sign() const
  1049 { wchar_t buf[16]; return _WLocale_negative_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); }
  1051 int moneypunct_byname<wchar_t, false>::do_frac_digits() const
  1052 { return _Locale_frac_digits(_M_monetary); }
  1054 #endif
  1056 _STLP_END_NAMESPACE

mercurial