os/ossrv/genericopenlibs/cppstdlib/stl/src/facets_byname.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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"
    19 
    20 #include <hash_map>
    21 #include <vector>
    22 
    23 #include <locale>
    24 #include <istream>
    25 
    26 #include <algorithm>
    27 #include <functional>
    28 
    29 #include "c_locale.h"
    30 #include "locale_impl.h"
    31 #include "acquire_release.h"
    32 
    33 _STLP_BEGIN_NAMESPACE
    34 
    35 //----------------------------------------------------------------------
    36 // ctype_byname<char>
    37 
    38 _STLP_DECLSPEC ctype_byname<char>::ctype_byname(const char* name, size_t refs, _Locale_name_hint* hint) :
    39     ctype<char>( 0, false, refs),
    40     _M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) {
    41   ctype<char>::_M_ctype_table = _M_byname_table;
    42   if (!_M_ctype)
    43     locale::_M_throw_runtime_error();
    44 
    45   // We have to do this, instead of just pointer twiddling, because
    46   // ctype_base::mask isn't the same type as _Locale_mask_t.
    47 
    48   const _Locale_mask_t* p = _Locale_ctype_table(_M_ctype);
    49 
    50   if (!p)
    51     locale::_M_throw_runtime_error();
    52 
    53   for (size_t i = 0; i < table_size; ++i) {
    54     _Locale_mask_t __m = p[i];
    55     if (__m & (upper | lower))
    56       __m |= alpha;
    57     _M_byname_table[i] = ctype_base::mask(__m);
    58   }
    59 }
    60 
    61 _STLP_DECLSPEC ctype_byname<char>::~ctype_byname()
    62 { _STLP_PRIV __release_ctype(_M_ctype); }
    63 
    64 _STLP_DECLSPEC char ctype_byname<char>::do_toupper(char c) const
    65 { return (char)_Locale_toupper(_M_ctype, c); }
    66 
    67 _STLP_DECLSPEC char ctype_byname<char>::do_tolower(char c) const
    68 { return (char)_Locale_tolower(_M_ctype, c); }
    69 
    70 _STLP_DECLSPEC const char*
    71 ctype_byname<char>::do_toupper(char* first, const char* last) const {
    72   for ( ; first != last ; ++first)
    73     *first = (char)_Locale_toupper(_M_ctype, *first);
    74   return last;
    75 }
    76 
    77 _STLP_DECLSPEC const char*
    78 ctype_byname<char>::do_tolower(char* first, const char* last) const {
    79   for ( ; first != last ; ++first)
    80     *first = (char)_Locale_tolower(_M_ctype, *first);
    81   return last;
    82 }
    83 
    84 
    85 // Some helper functions used in ctype<>::scan_is and scan_is_not.
    86 #if !defined (_STLP_NO_WCHAR_T)
    87 
    88 _STLP_MOVE_TO_PRIV_NAMESPACE
    89 
    90 // ctype_byname<wchar_t>
    91 
    92 struct _Ctype_byname_w_is_mask {
    93   typedef wchar_t argument_type;
    94   typedef bool    result_type;
    95 
    96   /* ctype_base::mask*/ int  M;
    97   _Locale_ctype* M_ctp;
    98 
    99   _Ctype_byname_w_is_mask(/* ctype_base::mask */ int m, _Locale_ctype* c) : M((int)m), M_ctp(c) {}
   100   bool operator()(wchar_t c) const
   101     { return (M & _Locale_wchar_ctype(M_ctp, c, M)) != 0; }
   102 };
   103 
   104 _STLP_MOVE_TO_STD_NAMESPACE
   105 
   106 _STLP_DECLSPEC ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs, _Locale_name_hint* hint)
   107   : ctype<wchar_t>(refs),
   108     _M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) {
   109   if (!_M_ctype)
   110     locale::_M_throw_runtime_error();
   111 }
   112 
   113 _STLP_DECLSPEC ctype_byname<wchar_t>::~ctype_byname()
   114 { _STLP_PRIV __release_ctype(_M_ctype); }
   115 
   116 _STLP_DECLSPEC bool ctype_byname<wchar_t>::do_is(ctype_base::mask  m, wchar_t c) const
   117 { return (m & _Locale_wchar_ctype(_M_ctype, c, m)) != 0; }
   118 
   119 _STLP_DECLSPEC const wchar_t*
   120 ctype_byname<wchar_t>::do_is(const wchar_t* low, const wchar_t* high,
   121                              ctype_base::mask * m) const {
   122   ctype_base::mask all_bits = ctype_base::mask(
   123     ctype_base::space |
   124     ctype_base::print |
   125     ctype_base::cntrl |
   126     ctype_base::upper |
   127     ctype_base::lower |
   128     ctype_base::alpha |
   129     ctype_base::digit |
   130     ctype_base::punct |
   131     ctype_base::xdigit);
   132 
   133   for ( ; low < high; ++low, ++m)
   134     *m = ctype_base::mask (_Locale_wchar_ctype(_M_ctype, *low, all_bits));
   135   return high;
   136 }
   137 
   138 _STLP_DECLSPEC const wchar_t*
   139 ctype_byname<wchar_t>
   140   ::do_scan_is(ctype_base::mask  m, const wchar_t* low, const wchar_t* high) const
   141 { return find_if(low, high, _STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype)); }
   142 
   143 _STLP_DECLSPEC const wchar_t*
   144 ctype_byname<wchar_t>
   145   ::do_scan_not(ctype_base::mask  m, const wchar_t* low, const wchar_t* high) const
   146 { return find_if(low, high, not1(_STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype))); }
   147 
   148 _STLP_DECLSPEC wchar_t ctype_byname<wchar_t>::do_toupper(wchar_t c) const
   149 { return _Locale_wchar_toupper(_M_ctype, c); }
   150 
   151 _STLP_DECLSPEC const wchar_t*
   152 ctype_byname<wchar_t>::do_toupper(wchar_t* low, const wchar_t* high) const {
   153   for ( ; low < high; ++low)
   154     *low = _Locale_wchar_toupper(_M_ctype, *low);
   155   return high;
   156 }
   157 
   158 _STLP_DECLSPEC wchar_t ctype_byname<wchar_t>::do_tolower(wchar_t c) const
   159 { return _Locale_wchar_tolower(_M_ctype, c); }
   160 
   161 _STLP_DECLSPEC const wchar_t*
   162 ctype_byname<wchar_t>::do_tolower(wchar_t* low, const wchar_t* high) const {
   163   for ( ; low < high; ++low)
   164     *low = _Locale_wchar_tolower(_M_ctype, *low);
   165   return high;
   166 }
   167 
   168 #endif /* WCHAR_T */
   169 
   170 // collate_byname<char>
   171 _STLP_DECLSPEC collate_byname<char>::collate_byname(const char* name, size_t refs, _Locale_name_hint* hint)
   172   : collate<char>(refs),
   173     _M_collate(_STLP_PRIV __acquire_collate(name, hint)) {
   174   if (!_M_collate)
   175     locale::_M_throw_runtime_error();
   176 }
   177 
   178 _STLP_DECLSPEC collate_byname<char>::~collate_byname()
   179 { _STLP_PRIV __release_collate(_M_collate); }
   180 
   181 _STLP_DECLSPEC int collate_byname<char>::do_compare(const char* __low1,
   182                                      const char* __high1,
   183                                      const char* __low2,
   184                                      const char* __high2) const {
   185   return _Locale_strcmp(_M_collate,
   186                         __low1, __high1 - __low1,
   187                         __low2, __high2 - __low2);
   188 }
   189 
   190 _STLP_DECLSPEC collate_byname<char>::string_type
   191 collate_byname<char>::do_transform(const char* low, const char* high) const {
   192   if (low == high)
   193     return string_type();
   194 
   195   size_t n = _Locale_strxfrm(_M_collate, NULL, 0, low, high - low);
   196 
   197   // NOT PORTABLE.  What we're doing relies on internal details of the
   198   // string implementation.  (Contiguity of string elements and presence
   199   // of trailing zero.)
   200   string_type buf(n, 0);
   201   _Locale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low);
   202   return buf;
   203 }
   204 
   205 
   206 #if !defined (_STLP_NO_WCHAR_T)
   207 
   208 // collate_byname<wchar_t>
   209 
   210 _STLP_DECLSPEC collate_byname<wchar_t>::collate_byname(const char* name, size_t refs, _Locale_name_hint* hint)
   211   : collate<wchar_t>(refs),
   212     _M_collate(_STLP_PRIV __acquire_collate(name, hint)) {
   213   if (!_M_collate)
   214     locale::_M_throw_runtime_error();
   215 }
   216 
   217 _STLP_DECLSPEC collate_byname<wchar_t>::~collate_byname()
   218 { _STLP_PRIV __release_collate(_M_collate); }
   219 
   220 _STLP_DECLSPEC int collate_byname<wchar_t>::do_compare(const wchar_t* low1,
   221                                         const wchar_t* high1,
   222                                         const wchar_t* low2,
   223                                         const wchar_t* high2) const {
   224   return _Locale_strwcmp(_M_collate,
   225                          low1, high1 - low1,
   226                          low2, high2 - low2);
   227 }
   228 
   229 _STLP_DECLSPEC collate_byname<wchar_t>::string_type
   230 collate_byname<wchar_t>::do_transform(const wchar_t* low,
   231                                       const wchar_t* high) const {
   232   if (low == high)
   233     return string_type();
   234 
   235   size_t n = _Locale_strwxfrm(_M_collate, NULL, 0, low, high - low);
   236 
   237   // NOT PORTABLE.  What we're doing relies on internal details of the
   238   // string implementation.  (Contiguity of string elements and presence
   239   // of trailing zero.)
   240   string_type buf(n, 0);
   241   _Locale_strwxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low);
   242   return buf;
   243 }
   244 
   245 #endif /*  _STLP_NO_WCHAR_T */
   246 
   247 _STLP_END_NAMESPACE
   248 
   249 #if !defined (_STLP_NO_MBSTATE_T)
   250 
   251 _STLP_BEGIN_NAMESPACE
   252 
   253 //----------------------------------------------------------------------
   254 // codecvt_byname<char>
   255 
   256 _STLP_DECLSPEC codecvt_byname<char, char, mbstate_t>
   257   ::codecvt_byname(const char* /* name */, size_t refs)
   258     : codecvt<char, char, mbstate_t>(refs) {}
   259 
   260 _STLP_DECLSPEC codecvt_byname<char, char, mbstate_t>::~codecvt_byname() {}
   261 
   262 
   263 #  if !defined (_STLP_NO_WCHAR_T)
   264 
   265 //----------------------------------------------------------------------
   266 // codecvt_byname<wchar_t>
   267 _STLP_DECLSPEC codecvt_byname<wchar_t, char, mbstate_t>
   268   ::codecvt_byname(const char* name, size_t refs, _Locale_name_hint* hint)
   269     : codecvt<wchar_t, char, mbstate_t>(refs),
   270       _M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) {
   271   if (!_M_ctype)
   272     locale::_M_throw_runtime_error();
   273 }
   274 
   275 _STLP_DECLSPEC codecvt_byname<wchar_t, char, mbstate_t>::~codecvt_byname()
   276 { _STLP_PRIV __release_ctype(_M_ctype); }
   277 
   278 _STLP_DECLSPEC codecvt<wchar_t, char, mbstate_t>::result
   279 codecvt_byname<wchar_t, char, mbstate_t>
   280   ::do_out(state_type&     state,
   281            const wchar_t*  from,
   282            const wchar_t*  from_end,
   283            const wchar_t*& from_next,
   284            char*           to,
   285            char*           to_limit,
   286            char*&          to_next) const {
   287   while (from != from_end) {
   288     size_t chars_stored = _Locale_wctomb(_M_ctype,
   289                                          to, to_limit - to, *from,
   290                                          &state);
   291     if (chars_stored == (size_t) -1) {
   292       from_next = from;
   293       to_next   = to;
   294       return error;
   295     }
   296     else if (chars_stored == (size_t) -2) {
   297       from_next = from;
   298       to_next   = to;
   299       return partial;
   300     }
   301 
   302     ++from;
   303     to += chars_stored;
   304   }
   305 
   306   from_next = from;
   307   to_next   = to;
   308   return ok;
   309 }
   310 
   311  _STLP_DECLSPEC codecvt<wchar_t, char, mbstate_t>::result
   312 codecvt_byname<wchar_t, char, mbstate_t>
   313   ::do_in(state_type&         state,
   314           const extern_type*  from,
   315           const extern_type*  from_end,
   316           const extern_type*& from_next,
   317           intern_type*        to,
   318           intern_type*        ,
   319           intern_type*&       to_next) const {
   320   while (from != from_end) {
   321     size_t chars_read = _Locale_mbtowc(_M_ctype,
   322                                        to, from, from_end - from,
   323                                        &state);
   324     if (chars_read == (size_t) -1) {
   325       from_next = from;
   326       to_next   = to;
   327       return error;
   328     }
   329 
   330     if (chars_read == (size_t) -2) {
   331       from_next = from;
   332       to_next   = to;
   333       return partial;
   334     }
   335 
   336     from += chars_read;
   337     to++;
   338   }
   339 
   340   from_next = from;
   341   to_next   = to;
   342   return ok;
   343 }
   344 
   345 _STLP_DECLSPEC codecvt<wchar_t, char, mbstate_t>::result
   346 codecvt_byname<wchar_t, char, mbstate_t>
   347   ::do_unshift(state_type&   state,
   348                extern_type*  to,
   349                extern_type*  to_limit,
   350                extern_type*& to_next) const {
   351   to_next = to;
   352   size_t result = _Locale_unshift(_M_ctype, &state,
   353                                   to, to_limit - to, &to_next);
   354   if (result == (size_t) -1)
   355     return error;
   356   else if (result == (size_t) -2)
   357     return partial;
   358   else
   359 #    if defined (__ISCPP__)
   360     return /*to_next == to ? noconv :*/ ok;
   361 #    else
   362     return to_next == to ? noconv : ok;
   363 #    endif
   364 }
   365 
   366 _STLP_DECLSPEC int
   367 codecvt_byname<wchar_t, char, mbstate_t>::do_encoding() const _STLP_NOTHROW {
   368   if (_Locale_is_stateless(_M_ctype)) {
   369     int max_width = _Locale_mb_cur_max(_M_ctype);
   370     int min_width = _Locale_mb_cur_min(_M_ctype);
   371     return min_width == max_width ? min_width : 0;
   372   }
   373   else
   374     return -1;
   375 }
   376 
   377 _STLP_DECLSPEC bool codecvt_byname<wchar_t, char, mbstate_t>
   378   ::do_always_noconv() const _STLP_NOTHROW {
   379   return false;
   380 }
   381 
   382 _STLP_DECLSPEC int
   383 codecvt_byname<wchar_t, char, mbstate_t>::do_length(const state_type&,
   384                                                     const  extern_type* from, const  extern_type* end,
   385                                                     size_t mx) const
   386 { return (int)(min) ((size_t) (end - from), mx); }
   387 
   388 _STLP_DECLSPEC int
   389 codecvt_byname<wchar_t, char, mbstate_t>::do_max_length() const _STLP_NOTHROW
   390 { return _Locale_mb_cur_max(_M_ctype); }
   391 #  endif
   392 
   393 _STLP_END_NAMESPACE
   394 
   395 #endif /* MBSTATE_T */
   396 
   397 _STLP_BEGIN_NAMESPACE
   398 
   399 // numpunct_byname<char>
   400 _STLP_DECLSPEC numpunct_byname<char>::numpunct_byname(const char* name, size_t refs, _Locale_name_hint* hint)
   401   : numpunct<char>(refs),
   402     _M_numeric(_STLP_PRIV __acquire_numeric(name, hint)) {
   403   if (!_M_numeric)
   404     locale::_M_throw_runtime_error();
   405 
   406   _M_truename  = _Locale_true(_M_numeric);
   407   _M_falsename = _Locale_false(_M_numeric);
   408 }
   409 
   410 _STLP_DECLSPEC numpunct_byname<char>::~numpunct_byname()
   411 { _STLP_PRIV __release_numeric(_M_numeric); }
   412 
   413 _STLP_DECLSPEC char numpunct_byname<char>::do_decimal_point() const
   414 { return _Locale_decimal_point(_M_numeric); }
   415 
   416 _STLP_DECLSPEC char numpunct_byname<char>::do_thousands_sep() const
   417 { return _Locale_thousands_sep(_M_numeric); }
   418 
   419 _STLP_DECLSPEC string numpunct_byname<char>::do_grouping() const {
   420   const char * __grouping = _Locale_grouping(_M_numeric);
   421   if (__grouping != NULL && __grouping[0] == CHAR_MAX)
   422     __grouping = "";
   423   return __grouping;
   424 }
   425 
   426 //----------------------------------------------------------------------
   427 // numpunct<wchar_t>
   428 
   429 #if !defined (_STLP_NO_WCHAR_T)
   430 
   431 // numpunct_byname<wchar_t>
   432 
   433 _STLP_DECLSPEC numpunct_byname<wchar_t>::numpunct_byname(const char* name, size_t refs, _Locale_name_hint* hint)
   434   : numpunct<wchar_t>(refs),
   435     _M_numeric(_STLP_PRIV __acquire_numeric(name, hint)) {
   436   if (!_M_numeric)
   437     locale::_M_throw_runtime_error();
   438 
   439   const char* truename  = _Locale_true(_M_numeric);
   440   const char* falsename = _Locale_false(_M_numeric);
   441   _M_truename.resize(strlen(truename));
   442   _M_falsename.resize(strlen(falsename));
   443   copy(truename,  truename  + strlen(truename), _M_truename.begin());
   444   copy(falsename, falsename + strlen(falsename), _M_falsename.begin());
   445 }
   446 
   447 _STLP_DECLSPEC numpunct_byname<wchar_t>::~numpunct_byname()
   448 { _STLP_PRIV __release_numeric(_M_numeric); }
   449 
   450 _STLP_DECLSPEC wchar_t numpunct_byname<wchar_t>::do_decimal_point() const
   451 { return (wchar_t) _Locale_decimal_point(_M_numeric); }
   452 
   453 _STLP_DECLSPEC wchar_t numpunct_byname<wchar_t>::do_thousands_sep() const
   454 { return (wchar_t) _Locale_thousands_sep(_M_numeric); }
   455 
   456 _STLP_DECLSPEC string numpunct_byname<wchar_t>::do_grouping() const {
   457   const char * __grouping = _Locale_grouping(_M_numeric);
   458   if (__grouping != NULL && __grouping[0] == CHAR_MAX)
   459     __grouping = "";
   460   return __grouping;
   461 }
   462 
   463 #endif
   464 
   465 _STLP_MOVE_TO_PRIV_NAMESPACE
   466 
   467 static void _Init_monetary_formats(money_base::pattern& pos_format,
   468                                    money_base::pattern& neg_format,
   469                                    _Locale_monetary * monetary) {
   470   switch (_Locale_p_sign_posn(monetary)) {
   471     case 0: // Parentheses surround the quantity and currency_symbol
   472     case 1: // The sign string precedes the quantity and currency_symbol
   473       pos_format.field[0] = (char) money_base::sign;
   474       if (_Locale_p_cs_precedes(monetary)) {
   475         // 1 if currency_symbol precedes a positive value
   476         pos_format.field[1] = (char) money_base::symbol;
   477         if (_Locale_p_sep_by_space(monetary)) {
   478           // a space separates currency_symbol from a positive value.
   479           pos_format.field[2] = (char) money_base::space;
   480           pos_format.field[3] = (char) money_base::value;
   481         } else {
   482           // a space not separates currency_symbol from a positive value.
   483           pos_format.field[2] = (char) money_base::value;
   484           pos_format.field[3] = (char) money_base::none;
   485         }
   486       } else {
   487         // 0 if currency_symbol succeeds a positive value
   488         pos_format.field[1] = (char) money_base::value;
   489         if (_Locale_p_sep_by_space(monetary)) {
   490           // a space separates currency_symbol from a positive value.
   491           pos_format.field[2] = (char) money_base::space;
   492           pos_format.field[3] = (char) money_base::symbol;
   493         } else {
   494           // a space not separates currency_symbol from a positive value.
   495           pos_format.field[2] = (char) money_base::symbol;
   496           pos_format.field[3] = (char) money_base::none;
   497         }
   498       }
   499       break;
   500     case 2: // The sign string succeeds the quantity and currency_symbol.
   501       if (_Locale_p_cs_precedes(monetary)) {
   502         // 1 if currency_symbol precedes a positive value
   503         pos_format.field[0] = (char) money_base::symbol;
   504         if (_Locale_p_sep_by_space(monetary)) {
   505           // a space separates currency_symbol from a positive value.
   506           pos_format.field[1] = (char) money_base::space;
   507           pos_format.field[2] = (char) money_base::value;
   508           pos_format.field[3] = (char) money_base::sign;
   509         } else {
   510           // a space not separates currency_symbol from a positive value.
   511           pos_format.field[1] = (char) money_base::value;
   512           pos_format.field[2] = (char) money_base::sign;
   513           pos_format.field[3] = (char) money_base::none;
   514         }
   515       } else {
   516         // 0 if currency_symbol succeeds a positive value
   517         pos_format.field[0] = (char) money_base::value;
   518         if (_Locale_p_sep_by_space(monetary)) {
   519           // a space separates currency_symbol from a positive value.
   520           pos_format.field[1] = (char) money_base::space;
   521           pos_format.field[2] = (char) money_base::symbol;
   522           pos_format.field[3] = (char) money_base::sign;
   523         } else {
   524           // a space not separates currency_symbol from a positive value.
   525           pos_format.field[1] = (char) money_base::symbol;
   526           pos_format.field[2] = (char) money_base::sign;
   527           pos_format.field[3] = (char) money_base::none;
   528         }
   529       }
   530       break;
   531     case 3: // The sign string immediately precedes the currency_symbol.
   532       if (_Locale_p_cs_precedes(monetary)) {
   533         // 1 if currency_symbol precedes a positive value
   534         pos_format.field[0] = (char) money_base::sign;
   535         pos_format.field[1] = (char) money_base::symbol;
   536         if (_Locale_p_sep_by_space(monetary)) {
   537           // a space separates currency_symbol from a positive value.
   538           pos_format.field[2] = (char) money_base::space;
   539           pos_format.field[3] = (char) money_base::value;
   540         } else {
   541           // a space not separates currency_symbol from a positive value.
   542           pos_format.field[2] = (char) money_base::value;
   543           pos_format.field[3] = (char) money_base::none;
   544         }
   545       } else {
   546         // 0 if currency_symbol succeeds a positive value
   547         pos_format.field[0] = (char) money_base::value;
   548         pos_format.field[1] = (char) money_base::sign;
   549         pos_format.field[2] = (char) money_base::symbol;
   550         pos_format.field[3] = (char) money_base::none;
   551       }
   552       break;
   553     case 4: // The sign string immediately succeeds the currency_symbol.
   554     default:
   555       if (_Locale_p_cs_precedes(monetary)) {
   556         // 1 if currency_symbol precedes a positive value
   557         pos_format.field[0] = (char) money_base::symbol;
   558         pos_format.field[1] = (char) money_base::sign;
   559         pos_format.field[2] = (char) money_base::value;
   560         pos_format.field[3] = (char) money_base::none;
   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   }
   578 
   579   switch (_Locale_n_sign_posn(monetary)) {
   580     case 0: // Parentheses surround the quantity and currency_symbol
   581     case 1: // The sign string precedes the quantity and currency_symbol
   582       neg_format.field[0] = (char) money_base::sign;
   583       if (_Locale_n_cs_precedes(monetary)) {
   584         // 1 if currency_symbol precedes a negative value
   585         neg_format.field[1] = (char) money_base::symbol;
   586         if (_Locale_n_sep_by_space(monetary)) {
   587           // a space separates currency_symbol from a negative value.
   588           neg_format.field[2] = (char) money_base::space;
   589           neg_format.field[3] = (char) money_base::value;
   590         } else {
   591           // a space not separates currency_symbol from a negative value.
   592           neg_format.field[2] = (char) money_base::value;
   593           neg_format.field[3] = (char) money_base::none;
   594         }
   595       } else {
   596         // 0 if currency_symbol succeeds a negative value
   597         neg_format.field[1] = (char) money_base::value;
   598         if (_Locale_n_sep_by_space(monetary)) {
   599           // a space separates currency_symbol from a negative value.
   600           neg_format.field[2] = (char) money_base::space;
   601           neg_format.field[3] = (char) money_base::symbol;
   602         } else {
   603           // a space not separates currency_symbol from a negative value.
   604           neg_format.field[2] = (char) money_base::symbol;
   605           neg_format.field[3] = (char) money_base::none;
   606         }
   607       }
   608       break;
   609     case 2: // The sign string succeeds the quantity and currency_symbol.
   610       if (_Locale_n_cs_precedes(monetary)) {
   611         // 1 if currency_symbol precedes a negative value
   612         neg_format.field[0] = (char) money_base::symbol;
   613         if (_Locale_n_sep_by_space(monetary)) {
   614           // a space separates currency_symbol from a negative value.
   615           neg_format.field[1] = (char) money_base::space;
   616           neg_format.field[2] = (char) money_base::value;
   617           neg_format.field[3] = (char) money_base::sign;
   618         } else {
   619           // a space not separates currency_symbol from a negative value.
   620           neg_format.field[1] = (char) money_base::value;
   621           neg_format.field[2] = (char) money_base::sign;
   622           neg_format.field[3] = (char) money_base::none;
   623         }
   624       } else {
   625         // 0 if currency_symbol succeeds a negative value
   626         neg_format.field[0] = (char) money_base::value;
   627         if (_Locale_n_sep_by_space(monetary)) {
   628           // a space separates currency_symbol from a negative value.
   629           neg_format.field[1] = (char) money_base::space;
   630           neg_format.field[2] = (char) money_base::symbol;
   631           neg_format.field[3] = (char) money_base::sign;
   632         } else {
   633           // a space not separates currency_symbol from a negative value.
   634           neg_format.field[1] = (char) money_base::symbol;
   635           neg_format.field[2] = (char) money_base::sign;
   636           neg_format.field[3] = (char) money_base::none;
   637         }
   638       }
   639       break;
   640     case 3: // The sign string immediately precedes the currency_symbol.
   641       if (_Locale_n_cs_precedes(monetary)) {
   642         // 1 if currency_symbol precedes a negative value
   643         neg_format.field[0] = (char) money_base::sign;
   644         neg_format.field[1] = (char) money_base::symbol;
   645         if (_Locale_n_sep_by_space(monetary)) {
   646           // a space separates currency_symbol from a negative value.
   647           neg_format.field[2] = (char) money_base::space;
   648           neg_format.field[3] = (char) money_base::value;
   649         } else {
   650           // a space not separates currency_symbol from a negative value.
   651           neg_format.field[2] = (char) money_base::value;
   652           neg_format.field[3] = (char) money_base::none;
   653         }
   654       } else {
   655         // 0 if currency_symbol succeeds a negative value
   656         neg_format.field[0] = (char) money_base::value;
   657         neg_format.field[1] = (char) money_base::sign;
   658         neg_format.field[2] = (char) money_base::symbol;
   659         neg_format.field[3] = (char) money_base::none;
   660       }
   661       break;
   662     case 4: // The sign string immediately succeeds the currency_symbol.
   663     default:
   664       if (_Locale_n_cs_precedes(monetary)) {
   665         // 1 if currency_symbol precedes a negative value
   666         neg_format.field[0] = (char) money_base::symbol;
   667         neg_format.field[1] = (char) money_base::sign;
   668         neg_format.field[2] = (char) money_base::value;
   669         neg_format.field[3] = (char) money_base::none;
   670       } else {
   671         // 0 if currency_symbol succeeds a negative value
   672         neg_format.field[0] = (char) money_base::value;
   673         if (_Locale_n_sep_by_space(monetary)) {
   674           // a space separates currency_symbol from a negative value.
   675           neg_format.field[1] = (char) money_base::space;
   676           neg_format.field[2] = (char) money_base::symbol;
   677           neg_format.field[3] = (char) money_base::sign;
   678         } else {
   679           // a space not separates currency_symbol from a negative value.
   680           neg_format.field[1] = (char) money_base::symbol;
   681           neg_format.field[2] = (char) money_base::sign;
   682           neg_format.field[3] = (char) money_base::none;
   683         }
   684       }
   685       break;
   686   }
   687 }
   688 
   689 // international variant of monetary
   690 
   691 /*
   692  * int_curr_symbol
   693  *
   694  *   The international currency symbol. The operand is a four-character
   695  *   string, with the first three characters containing the alphabetic
   696  *   international currency symbol in accordance with those specified
   697  *   in the ISO 4217 specification. The fourth character is the character used
   698  *   to separate the international currency symbol from the monetary quantity.
   699  *
   700  * (http://www.opengroup.org/onlinepubs/7990989775/xbd/locale.html)
   701  */
   702 
   703 /*
   704  * Standards are unclear in the usage of international currency
   705  * and monetary formats.
   706  * But I am expect that international currency symbol should be the first
   707  * (not depends upon where currency symbol situated in the national
   708  * format).
   709  *
   710  * If this isn't so, let's see:
   711  *       1 234.56 RUR
   712  *       GBP 1,234.56
   713  *       USD 1,234.56
   714  * The situation really is worse than you see above:
   715  * RUR typed wrong here---it prints '1 234.56 RUR ' (see space after RUR).
   716  * This is due to intl_fmp.curr_symbol() == "RUR ". (see reference in comments
   717  * above).
   718  *
   719  */
   720 
   721 static void _Init_monetary_formats_int(money_base::pattern& pos_format,
   722                                        money_base::pattern& neg_format,
   723                                        _Locale_monetary * monetary)
   724 {
   725   pos_format.field[0] = (char) money_base::symbol;
   726   // pos_format.field[1] = (char) money_base::space;
   727 
   728   switch (_Locale_p_sign_posn(monetary)) {
   729     case 0: // Parentheses surround the quantity and currency_symbol
   730     case 1: // The sign string precedes the quantity and currency_symbol
   731       pos_format.field[1] = (char) money_base::sign;
   732       pos_format.field[2] = (char) money_base::value;
   733       break;
   734     case 2: // The sign string succeeds the quantity and currency_symbol.
   735       pos_format.field[1] = (char) money_base::value;
   736       pos_format.field[2] = (char) money_base::sign;
   737       break;
   738     case 3: // The sign string immediately precedes the currency_symbol.
   739     case 4: // The sign string immediately succeeds the currency_symbol.
   740     default:
   741       if (_Locale_p_cs_precedes(monetary)) {
   742         // 1 if currency_symbol precedes a positive value
   743         pos_format.field[1] = (char) money_base::sign;
   744         pos_format.field[2] = (char) money_base::value;
   745       } else {
   746         // 0 if currency_symbol succeeds a positive value
   747         pos_format.field[1] = (char) money_base::value;
   748         pos_format.field[2] = (char) money_base::sign;
   749       }
   750       break;
   751   }
   752   pos_format.field[3] = (char) money_base::none;
   753 
   754   neg_format.field[0] = (char) money_base::symbol;
   755   // neg_format.field[1] = (char) money_base::space;
   756 
   757   switch (_Locale_n_sign_posn(monetary)) {
   758     case 0: // Parentheses surround the quantity and currency_symbol
   759     case 1: // The sign string precedes the quantity and currency_symbol
   760       neg_format.field[1] = (char) money_base::sign;
   761       neg_format.field[2] = (char) money_base::value;
   762       break;
   763     case 2: // The sign string succeeds the quantity and currency_symbol.
   764       neg_format.field[1] = (char) money_base::value;
   765       neg_format.field[2] = (char) money_base::sign;
   766       break;
   767     case 3: // The sign string immediately precedes the currency_symbol.
   768     case 4: // The sign string immediately succeeds the currency_symbol.
   769     default:
   770       if (_Locale_n_cs_precedes(monetary)) {
   771         // 1 if currency_symbol precedes a negative value
   772         neg_format.field[1] = (char) money_base::sign;
   773         neg_format.field[2] = (char) money_base::value;
   774       } else {
   775         // 0 if currency_symbol succeeds a negative value
   776         neg_format.field[1] = (char) money_base::value;
   777         neg_format.field[2] = (char) money_base::sign;
   778       }
   779       break;
   780   }
   781   neg_format.field[3] = (char) money_base::none;
   782 }
   783 
   784 _STLP_MOVE_TO_STD_NAMESPACE
   785 
   786 //
   787 // moneypunct_byname<>
   788 //
   789 _STLP_DECLSPEC moneypunct_byname<char, true>::moneypunct_byname(const char * name,
   790                                                  size_t refs, _Locale_name_hint* hint):
   791   moneypunct<char, true>(refs), _M_monetary(_STLP_PRIV __acquire_monetary(name, hint)) {
   792   if (!_M_monetary)
   793     locale::_M_throw_runtime_error();
   794   _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
   795 }
   796 
   797 _STLP_DECLSPEC moneypunct_byname<char, true>::~moneypunct_byname()
   798 { _STLP_PRIV __release_monetary(_M_monetary); }
   799 
   800 _STLP_DECLSPEC char moneypunct_byname<char, true>::do_decimal_point() const
   801 { return _Locale_mon_decimal_point(_M_monetary); }
   802 
   803 _STLP_DECLSPEC char moneypunct_byname<char, true>::do_thousands_sep() const
   804 { return _Locale_mon_thousands_sep(_M_monetary); }
   805 
   806 _STLP_DECLSPEC string moneypunct_byname<char, true>::do_grouping() const
   807 { return _Locale_mon_grouping(_M_monetary); }
   808 
   809 _STLP_DECLSPEC string moneypunct_byname<char, true>::do_curr_symbol() const
   810 { return _Locale_int_curr_symbol(_M_monetary); }
   811 
   812 _STLP_DECLSPEC string moneypunct_byname<char, true>::do_positive_sign() const
   813 { return _Locale_positive_sign(_M_monetary); }
   814 
   815 _STLP_DECLSPEC string moneypunct_byname<char, true>::do_negative_sign() const
   816 { return _Locale_negative_sign(_M_monetary); }
   817 
   818 _STLP_DECLSPEC int moneypunct_byname<char, true>::do_frac_digits() const
   819 { return _Locale_int_frac_digits(_M_monetary); }
   820 
   821 _STLP_DECLSPEC moneypunct_byname<char, false>::moneypunct_byname(const char * name,
   822                                                   size_t refs, _Locale_name_hint* hint):
   823   moneypunct<char, false>(refs), _M_monetary(_STLP_PRIV __acquire_monetary(name, hint)) {
   824   if (!_M_monetary)
   825     locale::_M_throw_runtime_error();
   826   _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
   827 }
   828 
   829 _STLP_DECLSPEC moneypunct_byname<char, false>::~moneypunct_byname()
   830 { _STLP_PRIV __release_monetary(_M_monetary); }
   831 
   832 _STLP_DECLSPEC char moneypunct_byname<char, false>::do_decimal_point() const
   833 { return _Locale_mon_decimal_point(_M_monetary); }
   834 
   835 _STLP_DECLSPEC char moneypunct_byname<char, false>::do_thousands_sep() const
   836 { return _Locale_mon_thousands_sep(_M_monetary); }
   837 
   838 _STLP_DECLSPEC string moneypunct_byname<char, false>::do_grouping() const
   839 { return _Locale_mon_grouping(_M_monetary); }
   840 
   841 _STLP_DECLSPEC string moneypunct_byname<char, false>::do_curr_symbol() const
   842 { return _Locale_currency_symbol(_M_monetary); }
   843 
   844 _STLP_DECLSPEC string moneypunct_byname<char, false>::do_positive_sign() const
   845 { return _Locale_positive_sign(_M_monetary); }
   846 
   847 _STLP_DECLSPEC string moneypunct_byname<char, false>::do_negative_sign() const
   848 { return _Locale_negative_sign(_M_monetary); }
   849 
   850 _STLP_DECLSPEC int moneypunct_byname<char, false>::do_frac_digits() const
   851 { return _Locale_frac_digits(_M_monetary); }
   852 
   853 //
   854 // moneypunct_byname<wchar_t>
   855 //
   856 #if !defined (_STLP_NO_WCHAR_T)
   857 
   858 _STLP_DECLSPEC moneypunct_byname<wchar_t, true>::moneypunct_byname(const char * name,
   859                                                     size_t refs, _Locale_name_hint* hint):
   860   moneypunct<wchar_t, true>(refs), _M_monetary(_STLP_PRIV __acquire_monetary(name, hint)) {
   861   if (!_M_monetary)
   862     locale::_M_throw_runtime_error();
   863   _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary);
   864 }
   865 
   866 _STLP_DECLSPEC moneypunct_byname<wchar_t, true>::~moneypunct_byname()
   867 { _STLP_PRIV __release_monetary(_M_monetary); }
   868 
   869 _STLP_DECLSPEC wchar_t moneypunct_byname<wchar_t, true>::do_decimal_point() const
   870 { return _Locale_mon_decimal_point(_M_monetary); }
   871 
   872 _STLP_DECLSPEC wchar_t moneypunct_byname<wchar_t, true>::do_thousands_sep() const
   873 { return _Locale_mon_thousands_sep(_M_monetary); }
   874 
   875 _STLP_DECLSPEC string moneypunct_byname<wchar_t, true>::do_grouping() const
   876 { return _Locale_mon_grouping(_M_monetary); }
   877 
   878 inline wstring __do_widen (string const& str) {
   879 #if defined (_STLP_NO_MEMBER_TEMPLATES) || defined (_STLP_MSVC) || defined(__MRC__) || defined(__SC__) //*ty 05/26/2001 - added workaround for mpw
   880   wstring::_Reserve_t __Reserve;
   881   size_t __size = str.size();
   882   wstring result(__Reserve, __size);
   883   copy(str.begin(), str.end(), result.begin());
   884 #else
   885   wstring result(str.begin(), str.end());
   886 #endif
   887   return result;
   888 }
   889 
   890 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, true>::do_curr_symbol() const
   891 { return __do_widen(_Locale_int_curr_symbol(_M_monetary)); }
   892 
   893 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, true>::do_positive_sign() const
   894 { return __do_widen(_Locale_positive_sign(_M_monetary)); }
   895 
   896 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, true>::do_negative_sign() const
   897 { return __do_widen(_Locale_negative_sign(_M_monetary)); }
   898 
   899 _STLP_DECLSPEC int moneypunct_byname<wchar_t, true>::do_frac_digits() const
   900 { return _Locale_int_frac_digits(_M_monetary); }
   901 
   902 _STLP_DECLSPEC moneypunct_byname<wchar_t, false>::moneypunct_byname(const char * name,
   903                                                      size_t refs, _Locale_name_hint* hint):
   904   moneypunct<wchar_t, false>(refs), _M_monetary(_STLP_PRIV __acquire_monetary(name, hint)) {
   905   if (!_M_monetary)
   906     locale::_M_throw_runtime_error() ;
   907   _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary);
   908 }
   909 
   910 _STLP_DECLSPEC moneypunct_byname<wchar_t, false>::~moneypunct_byname()
   911 { _STLP_PRIV __release_monetary(_M_monetary); }
   912 
   913 _STLP_DECLSPEC wchar_t moneypunct_byname<wchar_t, false>::do_decimal_point() const
   914 { return _Locale_mon_decimal_point(_M_monetary); }
   915 
   916 _STLP_DECLSPEC wchar_t moneypunct_byname<wchar_t, false>::do_thousands_sep() const
   917 { return _Locale_mon_thousands_sep(_M_monetary); }
   918 
   919 _STLP_DECLSPEC string moneypunct_byname<wchar_t, false>::do_grouping() const
   920 { return _Locale_mon_grouping(_M_monetary); }
   921 
   922 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, false>::do_curr_symbol() const
   923 { return __do_widen(_Locale_currency_symbol(_M_monetary)); }
   924 
   925 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, false>::do_positive_sign() const
   926 { return __do_widen(_Locale_positive_sign(_M_monetary)); }
   927 
   928 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, false>::do_negative_sign() const
   929 { return __do_widen(_Locale_negative_sign(_M_monetary)); }
   930 
   931 _STLP_DECLSPEC int moneypunct_byname<wchar_t, false>::do_frac_digits() const
   932 { return _Locale_frac_digits(_M_monetary); }
   933 
   934 #endif
   935 
   936 _STLP_END_NAMESPACE
   937 
   938 #include "message_facets.h"
   939 
   940 _STLP_BEGIN_NAMESPACE
   941 
   942 _STLP_MOVE_TO_PRIV_NAMESPACE
   943 
   944 void _Catalog_locale_map::insert(nl_catd_type key, const locale& L) {
   945   _STLP_TRY {
   946 #if !defined(_STLP_NO_TYPEINFO) && !defined(_STLP_NO_RTTI)
   947     // Don't bother to do anything unless we're using a non-default ctype facet
   948 # ifdef _STLP_NO_WCHAR_T
   949     typedef char _Char;
   950 # else
   951     typedef wchar_t _Char;
   952 # endif
   953 
   954     typedef ctype<_Char> wctype;
   955     wctype const& wct = use_facet<wctype>(L);
   956     if (typeid(wct) != typeid(wctype)) {
   957 # endif /* _STLP_NO_TYPEINFO */
   958       if (!M)
   959         M = new map_type;
   960 
   961 #if defined (__SC__)
   962       if (!M) delete M;
   963 #endif
   964       M->insert(map_type::value_type(key, L));
   965 #if !defined(_STLP_NO_TYPEINFO) && !defined(_STLP_NO_RTTI)
   966     }
   967 # endif /* _STLP_NO_TYPEINFO */
   968   }
   969   _STLP_CATCH_ALL {}
   970 }
   971 
   972 void _Catalog_locale_map::erase(nl_catd_type key) {
   973   if (M)
   974     M->erase(key);
   975 }
   976 
   977 locale _Catalog_locale_map::lookup(nl_catd_type key) const {
   978   if (M) {
   979     map_type::const_iterator i = M->find(key);
   980     return i != M->end() ? (*i).second : locale::classic();
   981   }
   982   else
   983     return locale::classic();
   984 }
   985 
   986 
   987 #if defined (_STLP_USE_NL_CATD_MAPPING)
   988 _STLP_VOLATILE __stl_atomic_t _Catalog_nl_catd_map::_count = 0;
   989 
   990 messages_base::catalog _Catalog_nl_catd_map::insert(nl_catd_type cat) {
   991   messages_base::catalog &res = Mr[cat];
   992   if ( res == 0 ) {
   993 #if defined (_STLP_ATOMIC_INCREMENT)
   994     res = __STATIC_CAST(int, _STLP_ATOMIC_INCREMENT(&_count));
   995 #else
   996     static _STLP_STATIC_MUTEX _Count_lock _STLP_MUTEX_INITIALIZER;
   997     {
   998       _STLP_auto_lock sentry(_Count_lock);
   999       res = __STATIC_CAST(int, ++_count);
  1000     }
  1001 #endif
  1002     M[res] = cat;
  1003   }
  1004   return res;
  1005 }
  1006 
  1007 void _Catalog_nl_catd_map::erase(messages_base::catalog cat) {
  1008   map_type::iterator mit(M.find(cat));
  1009   if (mit != M.end()) {
  1010     Mr.erase((*mit).second);
  1011     M.erase(mit);
  1012   }
  1013 }
  1014 #endif
  1015 
  1016 //----------------------------------------------------------------------
  1017 //
  1018 //
  1019 
  1020 _Messages_impl::_Messages_impl(bool is_wide, _Locale_name_hint* hint) :
  1021   _M_message_obj(0), _M_map(0) {
  1022   _M_delete = true;
  1023   if (is_wide)
  1024     _M_map = new _Catalog_locale_map;
  1025   _M_message_obj = __acquire_messages("C", hint);
  1026 }
  1027 
  1028 _Messages_impl::_Messages_impl(bool is_wide, _Locale_messages* msg_obj ) :
  1029   _M_message_obj(msg_obj), _M_map(0) {
  1030   _M_delete = true;
  1031   if (is_wide)
  1032     _M_map = new _Catalog_locale_map;
  1033 }
  1034 
  1035 _Messages_impl::~_Messages_impl() {
  1036   __release_messages(_M_message_obj);
  1037   if (_M_map) delete _M_map;
  1038 }
  1039 
  1040 _Messages::catalog _Messages_impl::do_open(const string& filename, const locale& L) const {
  1041   nl_catd_type result = _M_message_obj ? _Locale_catopen(_M_message_obj, filename.c_str())
  1042     : (nl_catd_type)(-1);
  1043 
  1044   if ( result != (nl_catd_type)(-1) ) {
  1045     if ( _M_map != 0 ) {
  1046       _M_map->insert(result, L);
  1047     }
  1048     return _M_cat.insert( result );
  1049   }
  1050 
  1051   return -1;
  1052 }
  1053 
  1054 string _Messages_impl::do_get(catalog cat,
  1055                               int set, int p_id, const string& dfault) const {
  1056   return _M_message_obj != 0 && cat >= 0
  1057     ? string(_Locale_catgets(_M_message_obj, _M_cat[cat], set, p_id, dfault.c_str()))
  1058     : dfault;
  1059 }
  1060 
  1061 #if !defined (_STLP_NO_WCHAR_T)
  1062 
  1063 wstring
  1064 _Messages_impl::do_get(catalog thecat,
  1065                        int set, int p_id, const wstring& dfault) const {
  1066   typedef ctype<wchar_t> wctype;
  1067   const wctype& ct = use_facet<wctype>(_M_map->lookup( _M_cat[thecat] ) );
  1068 
  1069   const char* str = _Locale_catgets(_M_message_obj, _M_cat[thecat], set, p_id, "");
  1070 
  1071   // Verify that the lookup failed; an empty string might represent success.
  1072   if (!str)
  1073     return dfault;
  1074   else if (str[0] == '\0') {
  1075     const char* str2 = _Locale_catgets(_M_message_obj, _M_cat[thecat], set, p_id, "*");
  1076     if (!str2 || ((str2[0] == '*') && (str2[1] == '\0')))
  1077       return dfault;
  1078   }
  1079 
  1080   // str is correct.  Now we must widen it to get a wstring.
  1081   size_t n = strlen(str);
  1082 
  1083   // NOT PORTABLE.  What we're doing relies on internal details of the
  1084   // string implementation.  (Contiguity of string elements.)
  1085   wstring result(n, wchar_t(0));
  1086   ct.widen(str, str + n, &*result.begin());
  1087   return result;
  1088 }
  1089 
  1090 #endif
  1091 
  1092 void _Messages_impl::do_close(catalog thecat) const {
  1093   if (_M_message_obj)
  1094     _Locale_catclose(_M_message_obj, _M_cat[thecat]);
  1095   if (_M_map) _M_map->erase(_M_cat[thecat]);
  1096   _M_cat.erase( thecat );
  1097 }
  1098 
  1099 _STLP_MOVE_TO_STD_NAMESPACE
  1100 
  1101 //----------------------------------------------------------------------
  1102 // messages<char>
  1103 
  1104 _STLP_DECLSPEC messages<char>::messages(size_t refs) :
  1105   locale::facet(refs), _M_impl(new _STLP_PRIV _Messages_impl(false)) {}
  1106 
  1107 _STLP_DECLSPEC messages<char>::messages(size_t refs, _Locale_messages* msg_obj) : locale::facet(refs),
  1108   _M_impl(new _STLP_PRIV _Messages_impl(false, msg_obj)) {}
  1109 
  1110 
  1111 //----------------------------------------------------------------------
  1112 // messages_byname<char>
  1113 
  1114 _STLP_DECLSPEC messages_byname<char>::messages_byname(const char* name, size_t refs, _Locale_name_hint* hint)
  1115   : messages<char>(refs, name ? _STLP_PRIV __acquire_messages(name, hint) : 0) {}
  1116 
  1117 _STLP_DECLSPEC messages_byname<char>::~messages_byname() {}
  1118 
  1119 #if !defined (_STLP_NO_WCHAR_T)
  1120 
  1121 //----------------------------------------------------------------------
  1122 // messages<wchar_t>
  1123 
  1124 _STLP_DECLSPEC messages<wchar_t>::messages(size_t refs)  :
  1125   locale::facet(refs), _M_impl(new _STLP_PRIV _Messages_impl(true)) {}
  1126 
  1127 _STLP_DECLSPEC messages<wchar_t>::messages(size_t refs, _Locale_messages* msg_obj)
  1128   : locale::facet(refs),
  1129     _M_impl(new _STLP_PRIV _Messages_impl(true, msg_obj)) {}
  1130 
  1131 //----------------------------------------------------------------------
  1132 // messages_byname<wchar_t>
  1133 
  1134 
  1135 _STLP_DECLSPEC messages_byname<wchar_t>::messages_byname(const char* name, size_t refs, _Locale_name_hint* hint)
  1136   : messages<wchar_t>(refs, name ? _STLP_PRIV __acquire_messages(name, hint) : 0) {}
  1137 
  1138 _STLP_DECLSPEC messages_byname<wchar_t>::~messages_byname() {}
  1139 
  1140 #endif
  1141 
  1142 _STLP_END_NAMESPACE
  1143