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