os/ossrv/genericopenlibs/cppstdlib/stl/test/unit/locale_test.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/test/unit/locale_test.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1497 @@
     1.4 +/*
     1.5 +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +* All rights reserved.
     1.7 + */
     1.8 +#include <string>
     1.9 +
    1.10 +#if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
    1.11 +#  include <sstream>
    1.12 +#  include <locale>
    1.13 +#  include <stdexcept>
    1.14 +#  include <memory>
    1.15 +#  include <algorithm>
    1.16 +//#  include <iostream>
    1.17 +
    1.18 +#  include "cppunit/cppunit_proxy.h"
    1.19 +
    1.20 +#  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
    1.21 +using namespace std;
    1.22 +#  endif
    1.23 +
    1.24 +struct ref_locale {
    1.25 +  const char *name;
    1.26 +  const char *decimal_point;
    1.27 +  const char *thousands_sep;
    1.28 +  const char *money_int_prefix;
    1.29 +  const char *money_int_prefix_old;
    1.30 +  const char *money_prefix;
    1.31 +  const char *money_suffix;
    1.32 +  const char *money_decimal_point;
    1.33 +  const char *money_thousands_sep;
    1.34 +};
    1.35 +
    1.36 +// Pls, don't write #ifdef _STLP_REAL_LOCALE_IMPLEMENTED here!
    1.37 +// It undefined in any case!!!!!
    1.38 +
    1.39 +static const ref_locale tested_locales[] = {
    1.40 +//{  name,         decimal_point, thousands_sep, money_int_prefix, money_int_prefix_old, money_prefix, money_suffix, money_decimal_point, money_thousands_sep},
    1.41 +  { "fr_FR",       ",",           "\xa0",        "EUR ",           "FRF ",               "",           "",           ",",
    1.42 +#  if defined (WIN32) || defined (_WIN32)
    1.43 +                                                                                                                                          "\xa0" },
    1.44 +#  else
    1.45 +                                                                                                                                          " " },
    1.46 +#  endif
    1.47 +  { "ru_RU.koi8r", ",",           ".",           "RUB ",           "RUR ",               "",           "\xd2\xd5\xc2", ".",               " " },
    1.48 +  { "en_GB",       ".",           ",",           "GBP ",           "",                   "\xa3",       "",           ".",                 "," },
    1.49 +  { "en_US",       ".",           ",",           "USD ",           "",                   "$",          "",           ".",                 "," },
    1.50 +  { "C",           ".",           ",",           "",               "",                   "",           "",           " ",                 " " },
    1.51 +};
    1.52 +
    1.53 +
    1.54 +//
    1.55 +// TestCase class
    1.56 +//
    1.57 +class LocaleTest : public CPPUNIT_NS::TestCase
    1.58 +{
    1.59 +  CPPUNIT_TEST_SUITE(LocaleTest);
    1.60 +#  if defined (STLPORT) && !defined (_STLP_USE_EXCEPTIONS)
    1.61 +  CPPUNIT_IGNORE;
    1.62 +#  endif
    1.63 +  CPPUNIT_TEST(locale_by_name);
    1.64 +  CPPUNIT_STOP_IGNORE;
    1.65 +  CPPUNIT_TEST(loc_has_facet);
    1.66 +  CPPUNIT_TEST(num_put_get);
    1.67 +  CPPUNIT_TEST(money_put_get);
    1.68 +  CPPUNIT_TEST(money_put_X_bug);
    1.69 +  CPPUNIT_TEST(time_put_get);
    1.70 +#  if defined (__DMC__) && defined (_DLL)
    1.71 +  CPPUNIT_IGNORE;
    1.72 +#  endif
    1.73 +  CPPUNIT_TEST(collate_facet);
    1.74 +  CPPUNIT_TEST(ctype_facet);
    1.75 +#  if defined (STLPORT) && defined (_STLP_NO_MEMBER_TEMPLATES)
    1.76 +  CPPUNIT_IGNORE;
    1.77 +#  endif
    1.78 +  CPPUNIT_TEST(locale_init_problem);
    1.79 +  CPPUNIT_STOP_IGNORE;
    1.80 +  CPPUNIT_TEST(default_locale);
    1.81 +#  if !defined (STLPORT)
    1.82 +  CPPUNIT_IGNORE;
    1.83 +#  endif
    1.84 +  CPPUNIT_TEST(facet_id);
    1.85 +  CPPUNIT_STOP_IGNORE;
    1.86 +#  if defined (STLPORT) && \
    1.87 +     (!defined (_STLP_USE_EXCEPTIONS) || defined (_STLP_NO_MEMBER_TEMPLATES) || defined (_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS))
    1.88 +  CPPUNIT_IGNORE;
    1.89 +#  endif
    1.90 +  CPPUNIT_TEST(combine);
    1.91 +  CPPUNIT_TEST_SUITE_END();
    1.92 +
    1.93 +public:
    1.94 +  void locale_by_name();
    1.95 +  void loc_has_facet();
    1.96 +  void num_put_get();
    1.97 +  void money_put_get();
    1.98 +  void time_put_get();
    1.99 +  void collate_facet();
   1.100 +  void ctype_facet();
   1.101 +  void locale_init_problem();
   1.102 +  void money_put_X_bug();
   1.103 +  void default_locale();
   1.104 +  void facet_id();
   1.105 +  void combine();
   1.106 +private:
   1.107 +  void _loc_has_facet( const locale&, const ref_locale& );
   1.108 +  void _num_put_get( const locale&, const ref_locale& );
   1.109 +  void _money_put_get( const locale&, const ref_locale& );
   1.110 +  void _money_put_get2( const locale& loc, const locale& streamLoc, const ref_locale& );
   1.111 +  void _time_put_get( const locale&, const ref_locale& );
   1.112 +  void _ctype_facet( const locale&, const ref_locale& );
   1.113 +  void _locale_init_problem( const locale&, const ref_locale& );
   1.114 +  void _money_put_X_bug( const locale&, const ref_locale& );
   1.115 +};
   1.116 +
   1.117 +CPPUNIT_TEST_SUITE_REGISTRATION(LocaleTest);
   1.118 +
   1.119 +//
   1.120 +// tests implementation
   1.121 +//
   1.122 +void LocaleTest::_num_put_get( const locale& loc, const ref_locale& rl ) {
   1.123 +  CPPUNIT_ASSERT( has_facet<numpunct<char> >(loc) );
   1.124 +  numpunct<char> const& npct = use_facet<numpunct<char> >(loc);
   1.125 +  CPPUNIT_ASSERT( npct.decimal_point() == *rl.decimal_point );
   1.126 +
   1.127 +  float val = 1234.56f;
   1.128 +  ostringstream fostr;
   1.129 +  fostr.imbue(loc);
   1.130 +  fostr << val;
   1.131 +
   1.132 +  string ref = "1";
   1.133 +  if (!npct.grouping().empty()) {
   1.134 +    ref += npct.thousands_sep();
   1.135 +  }
   1.136 +  ref += "234";
   1.137 +  ref += npct.decimal_point();
   1.138 +  ref += "56";
   1.139 +  //cout << "In " << loc.name() << " 1234.56 is written: " << fostr.str() << endl;
   1.140 +  CPPUNIT_ASSERT( fostr.str() == ref );
   1.141 +
   1.142 +  val = 12345678.9f;
   1.143 +  ref = "1";
   1.144 +  ref += npct.decimal_point();
   1.145 +  ref += "23457e+07";
   1.146 +  fostr.str("");
   1.147 +  fostr << val;
   1.148 +  CPPUNIT_ASSERT( fostr.str() == ref );
   1.149 +
   1.150 +  val = 1000000000.0f;
   1.151 +  fostr.str("");
   1.152 +  fostr << val;
   1.153 +  CPPUNIT_ASSERT( fostr.str() == "1e+09" );
   1.154 +
   1.155 +  val = 1234.0f;
   1.156 +  ref = "1";
   1.157 +  if (!npct.grouping().empty()) {
   1.158 +    ref += npct.thousands_sep();
   1.159 +  }
   1.160 +  ref += "234";
   1.161 +  fostr.str("");
   1.162 +  fostr << val;
   1.163 +  CPPUNIT_ASSERT( fostr.str() == ref );
   1.164 +
   1.165 +  val = 10000001.0f;
   1.166 +  fostr.str("");
   1.167 +  fostr << val;
   1.168 +  CPPUNIT_ASSERT( fostr.str() == "1e+07" );
   1.169 +}
   1.170 +
   1.171 +void LocaleTest::_money_put_get( const locale& loc, const ref_locale& rl )
   1.172 +{
   1.173 +  _money_put_get2(loc, loc, rl);
   1.174 +}
   1.175 +
   1.176 +void LocaleTest::_money_put_get2( const locale& loc, const locale& streamLoc, const ref_locale& rl )
   1.177 +{
   1.178 +  CPPUNIT_ASSERT( has_facet<money_put<char> >(loc) );
   1.179 +  money_put<char> const& fmp = use_facet<money_put<char> >(loc);
   1.180 +  CPPUNIT_ASSERT( has_facet<money_get<char> >(loc) );
   1.181 +  money_get<char> const& fmg = use_facet<money_get<char> >(loc);
   1.182 +
   1.183 +  ostringstream ostr;
   1.184 +  ostr.imbue(streamLoc);
   1.185 +  ostr << showbase;
   1.186 +
   1.187 +  //Check a positive value (international format)
   1.188 +  {
   1.189 +    string str_res;
   1.190 +    //money_put
   1.191 +    {
   1.192 +      CPPUNIT_ASSERT( (has_facet<moneypunct<char, true> >(loc)) );
   1.193 +      moneypunct<char, true> const& intl_fmp = use_facet<moneypunct<char, true> >(loc);
   1.194 +
   1.195 +      ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, true, ostr, ' ', 123456);
   1.196 +
   1.197 +      CPPUNIT_ASSERT( !res.failed() );
   1.198 +      str_res = ostr.str();
   1.199 +
   1.200 +      size_t fieldIndex = 0;
   1.201 +      size_t index = 0;
   1.202 +
   1.203 +      //On a positive value we skip the sign field if exists:
   1.204 +      if (intl_fmp.pos_format().field[fieldIndex] == money_base::sign) {
   1.205 +        ++fieldIndex;
   1.206 +      }
   1.207 +      // international currency abbreviation, if it is before value
   1.208 +
   1.209 +      /*
   1.210 +       * int_curr_symbol
   1.211 +       *
   1.212 +       *   The international currency symbol. The operand is a four-character
   1.213 +       *   string, with the first three characters containing the alphabetic
   1.214 +       *   international currency symbol in accordance with those specified
   1.215 +       *   in the ISO 4217 specification. The fourth character is the character used
   1.216 +       *   to separate the international currency symbol from the monetary quantity.
   1.217 +       *
   1.218 +       * (http://www.opengroup.org/onlinepubs/7990989775/xbd/locale.html)
   1.219 +       */
   1.220 +      string::size_type p = strlen( rl.money_int_prefix );
   1.221 +      if (p != 0) {
   1.222 +        CPPUNIT_ASSERT( intl_fmp.pos_format().field[fieldIndex] == money_base::symbol );
   1.223 +        string::size_type p_old = strlen( rl.money_int_prefix_old );
   1.224 +        CPPUNIT_ASSERT( (str_res.substr(index, p) == rl.money_int_prefix) ||
   1.225 +                        ((p_old != 0) && (str_res.substr(index, p_old) ==  rl.money_int_prefix_old)) );
   1.226 +        if ( str_res.substr(index, p) == rl.money_int_prefix ) {
   1.227 +          index += p;
   1.228 +        } else {
   1.229 +          index += p_old;
   1.230 +        }
   1.231 +        ++fieldIndex;
   1.232 +      }
   1.233 +
   1.234 +      // space after currency
   1.235 +      if (intl_fmp.pos_format().field[fieldIndex] == money_base::space ||
   1.236 +          intl_fmp.pos_format().field[fieldIndex] == money_base::none) {
   1.237 +        // iternational currency symobol has four chars, one of these chars
   1.238 +        // is separator, so if format has space on this place, it should
   1.239 +        // be skipped.
   1.240 +        ++fieldIndex;
   1.241 +      }
   1.242 +
   1.243 +      // sign
   1.244 +      if (intl_fmp.pos_format().field[fieldIndex] == money_base::sign) {
   1.245 +        ++fieldIndex;
   1.246 +      }
   1.247 +
   1.248 +      // value
   1.249 +      CPPUNIT_ASSERT( str_res[index++] == '1' );
   1.250 +      if (!intl_fmp.grouping().empty()) {
   1.251 +        CPPUNIT_ASSERT( str_res[index++] == /* intl_fmp.thousands_sep() */ *rl.money_thousands_sep );
   1.252 +      }
   1.253 +      CPPUNIT_ASSERT( str_res[index++] == '2' );
   1.254 +      CPPUNIT_ASSERT( str_res[index++] == '3' );
   1.255 +      CPPUNIT_ASSERT( str_res[index++] == '4' );
   1.256 +      if (intl_fmp.frac_digits() != 0) {
   1.257 +        CPPUNIT_ASSERT( str_res[index++] == /* intl_fmp.decimal_point() */ *rl.money_decimal_point );
   1.258 +      }
   1.259 +      CPPUNIT_ASSERT( str_res[index++] == '5' );
   1.260 +      CPPUNIT_ASSERT( str_res[index++] == '6' );
   1.261 +      ++fieldIndex;
   1.262 +
   1.263 +      // sign
   1.264 +      if (intl_fmp.pos_format().field[fieldIndex] == money_base::sign) {
   1.265 +        ++fieldIndex;
   1.266 +      }
   1.267 +
   1.268 +      // space
   1.269 +      if (intl_fmp.pos_format().field[fieldIndex] == money_base::space ) {
   1.270 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.271 +        ++fieldIndex;
   1.272 +      }
   1.273 +
   1.274 +      // sign
   1.275 +      if (intl_fmp.pos_format().field[fieldIndex] == money_base::sign) {
   1.276 +        ++fieldIndex;
   1.277 +      }
   1.278 +
   1.279 +      //as space cannot be last the only left format can be none:
   1.280 +      while ( fieldIndex < 3 ) {
   1.281 +        CPPUNIT_ASSERT( intl_fmp.pos_format().field[fieldIndex] == money_base::none );
   1.282 +        ++fieldIndex;
   1.283 +      }
   1.284 +    }
   1.285 +
   1.286 +    //money_get
   1.287 +    {
   1.288 +      ios_base::iostate err = ios_base::goodbit;
   1.289 +      string digits;
   1.290 +
   1.291 +      istringstream istr(str_res);
   1.292 +      ostr.str( "" );
   1.293 +      ostr.clear();
   1.294 +      fmg.get(istr, istreambuf_iterator<char, char_traits<char> >(), true, ostr, err, digits);
   1.295 +      CPPUNIT_ASSERT( (err & (ios_base::failbit | ios_base::badbit)) == 0 );
   1.296 +      CPPUNIT_ASSERT( digits == "123456" );
   1.297 +    }
   1.298 +  }
   1.299 +
   1.300 +  ostr.str("");
   1.301 +  //Check a negative value (national format)
   1.302 +  {
   1.303 +    CPPUNIT_ASSERT( (has_facet<moneypunct<char, false> >(loc)) );
   1.304 +    moneypunct<char, false> const& dom_fmp = use_facet<moneypunct<char, false> >(loc);
   1.305 +    string str_res;
   1.306 +    //Check money_put
   1.307 +    {
   1.308 +      ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, false, ostr, ' ', -123456);
   1.309 +
   1.310 +      CPPUNIT_ASSERT( !res.failed() );
   1.311 +      str_res = ostr.str();
   1.312 +
   1.313 +      size_t fieldIndex = 0;
   1.314 +      size_t index = 0;
   1.315 +
   1.316 +      if (dom_fmp.neg_format().field[fieldIndex] == money_base::sign) {
   1.317 +        CPPUNIT_ASSERT( str_res.substr(index, dom_fmp.negative_sign().size()) == dom_fmp.negative_sign() );
   1.318 +        index += dom_fmp.negative_sign().size();
   1.319 +        ++fieldIndex;
   1.320 +      }
   1.321 +
   1.322 +      string::size_type p = strlen( rl.money_prefix );
   1.323 +      if (p != 0) {
   1.324 +        CPPUNIT_ASSERT( str_res.substr(index, p) == rl.money_prefix );
   1.325 +        index += p;
   1.326 +        ++fieldIndex;
   1.327 +      }
   1.328 +      if (dom_fmp.neg_format().field[fieldIndex] == money_base::space ||
   1.329 +          dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
   1.330 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.331 +        ++fieldIndex;
   1.332 +      }
   1.333 +
   1.334 +      CPPUNIT_ASSERT( str_res[index++] == '1' );
   1.335 +      if (!dom_fmp.grouping().empty()) {
   1.336 +        CPPUNIT_ASSERT( str_res[index++] == dom_fmp.thousands_sep() );
   1.337 +      }
   1.338 +      CPPUNIT_ASSERT( str_res[index++] == '2' );
   1.339 +      CPPUNIT_ASSERT( str_res[index++] == '3' );
   1.340 +      CPPUNIT_ASSERT( str_res[index++] == '4' );
   1.341 +      if (dom_fmp.frac_digits() != 0) {
   1.342 +        CPPUNIT_ASSERT( str_res[index++] == dom_fmp.decimal_point() );
   1.343 +      }
   1.344 +      CPPUNIT_ASSERT( str_res[index++] == '5' );
   1.345 +      CPPUNIT_ASSERT( str_res[index++] == '6' );
   1.346 +      ++fieldIndex;
   1.347 +
   1.348 +      //space cannot be last:
   1.349 +      if ((fieldIndex < 3) &&
   1.350 +          dom_fmp.neg_format().field[fieldIndex] == money_base::space) {
   1.351 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.352 +        ++fieldIndex;
   1.353 +      }
   1.354 +
   1.355 +      if (fieldIndex == 3) {
   1.356 +        //If none is last we should not add anything to the resulting string:
   1.357 +        if (dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
   1.358 +          CPPUNIT_ASSERT( index == str_res.size() );
   1.359 +        } else {
   1.360 +          CPPUNIT_ASSERT( dom_fmp.neg_format().field[fieldIndex] == money_base::symbol );
   1.361 +          CPPUNIT_ASSERT( str_res.substr(index, strlen(rl.money_suffix)) == rl.money_suffix );
   1.362 +        }
   1.363 +      }
   1.364 +    }
   1.365 +
   1.366 +    //money_get
   1.367 +    {
   1.368 +      ios_base::iostate err = ios_base::goodbit;
   1.369 +#  if defined (STLPORT)
   1.370 +      _STLP_LONGEST_FLOAT_TYPE val;
   1.371 +#  else
   1.372 +      long double val;
   1.373 +#  endif
   1.374 +
   1.375 +      istringstream istr(str_res);
   1.376 +      fmg.get(istr, istreambuf_iterator<char, char_traits<char> >(), false, ostr, err, val);
   1.377 +      CPPUNIT_ASSERT( (err & (ios_base::failbit | ios_base::badbit)) == 0 );
   1.378 +      if (dom_fmp.negative_sign().empty()) {
   1.379 +        //Without negative sign there is no way to guess the resulting amount sign ("C" locale):
   1.380 +        CPPUNIT_ASSERT( val == 123456 );
   1.381 +      }
   1.382 +      else {
   1.383 +        CPPUNIT_ASSERT( val == -123456 );
   1.384 +      }
   1.385 +    }
   1.386 +  }
   1.387 +  ostr.str("");
   1.388 +  //Check a negative value (national format)
   1.389 +  {
   1.390 +    CPPUNIT_ASSERT( (has_facet<moneypunct<char, false> >(loc)) );
   1.391 +    moneypunct<char, true> const& dom_fmp = use_facet<moneypunct<char, true> >(loc);
   1.392 +    string str_res;
   1.393 +    //Check money_put
   1.394 +    {
   1.395 +      ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, true, ostr, ' ', -123456);
   1.396 +
   1.397 +      CPPUNIT_ASSERT( !res.failed() );
   1.398 +      str_res = ostr.str();
   1.399 +
   1.400 +      size_t fieldIndex = 0;
   1.401 +      size_t index = 0;
   1.402 +
   1.403 +      if (dom_fmp.neg_format().field[fieldIndex] == money_base::sign) {
   1.404 +        CPPUNIT_ASSERT( str_res.substr(index, dom_fmp.negative_sign().size()) == dom_fmp.negative_sign() );
   1.405 +        index += dom_fmp.negative_sign().size();
   1.406 +        ++fieldIndex;
   1.407 +      }
   1.408 +
   1.409 +      string::size_type p = strlen( rl.money_prefix );
   1.410 +      if (p != 0) {
   1.411 +        CPPUNIT_ASSERT( str_res.substr(index, p) == rl.money_prefix );
   1.412 +        index += p;
   1.413 +        ++fieldIndex;
   1.414 +      }
   1.415 +      if (dom_fmp.neg_format().field[fieldIndex] == money_base::space ||
   1.416 +          dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
   1.417 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.418 +        ++fieldIndex;
   1.419 +      }
   1.420 +
   1.421 +      CPPUNIT_ASSERT( str_res[index++] == '1' );
   1.422 +      if (!dom_fmp.grouping().empty()) {
   1.423 +        CPPUNIT_ASSERT( str_res[index++] == dom_fmp.thousands_sep() );
   1.424 +      }
   1.425 +      CPPUNIT_ASSERT( str_res[index++] == '2' );
   1.426 +      CPPUNIT_ASSERT( str_res[index++] == '3' );
   1.427 +      CPPUNIT_ASSERT( str_res[index++] == '4' );
   1.428 +      if (dom_fmp.frac_digits() != 0) {
   1.429 +        CPPUNIT_ASSERT( str_res[index++] == dom_fmp.decimal_point() );
   1.430 +      }
   1.431 +      CPPUNIT_ASSERT( str_res[index++] == '5' );
   1.432 +      CPPUNIT_ASSERT( str_res[index++] == '6' );
   1.433 +      ++fieldIndex;
   1.434 +
   1.435 +      //space cannot be last:
   1.436 +      if ((fieldIndex < 3) &&
   1.437 +          dom_fmp.neg_format().field[fieldIndex] == money_base::space) {
   1.438 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.439 +        ++fieldIndex;
   1.440 +      }
   1.441 +
   1.442 +      if (fieldIndex == 3) {
   1.443 +        //If none is last we should not add anything to the resulting string:
   1.444 +        if (dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
   1.445 +          CPPUNIT_ASSERT( index == str_res.size() );
   1.446 +        } else {
   1.447 +          CPPUNIT_ASSERT( dom_fmp.neg_format().field[fieldIndex] == money_base::symbol );
   1.448 +          CPPUNIT_ASSERT( str_res.substr(index, strlen(rl.money_suffix)) == rl.money_suffix );
   1.449 +        }
   1.450 +      }
   1.451 +    }
   1.452 +
   1.453 +    //money_get
   1.454 +    {
   1.455 +      ios_base::iostate err = ios_base::goodbit;
   1.456 +#  if defined (STLPORT)
   1.457 +      _STLP_LONGEST_FLOAT_TYPE val;
   1.458 +#  else
   1.459 +      long double val;
   1.460 +#  endif
   1.461 +
   1.462 +      istringstream istr(str_res);
   1.463 +      fmg.get(istr, istreambuf_iterator<char, char_traits<char> >(), false, ostr, err, val);
   1.464 +      CPPUNIT_ASSERT( (err & (ios_base::failbit | ios_base::badbit)) == 0 );
   1.465 +      if (dom_fmp.negative_sign().empty()) {
   1.466 +        //Without negative sign there is no way to guess the resulting amount sign ("C" locale):
   1.467 +        CPPUNIT_ASSERT( val == 123456 );
   1.468 +      }
   1.469 +      else {
   1.470 +        CPPUNIT_ASSERT( val == -123456 );
   1.471 +      }
   1.472 +    }
   1.473 +  }
   1.474 +}
   1.475 +
   1.476 +
   1.477 +// Test for bug in case when number of digits in value less then number
   1.478 +// of digits in fraction. I.e. '9' should be printed as '0.09',
   1.479 +// if x.frac_digits() == 2.
   1.480 +
   1.481 +void LocaleTest::_money_put_X_bug( const locale& loc, const ref_locale& rl )
   1.482 +{
   1.483 +  CPPUNIT_ASSERT( has_facet<money_put<char> >(loc) );
   1.484 +  money_put<char> const& fmp = use_facet<money_put<char> >(loc);
   1.485 +
   1.486 +  ostringstream ostr;
   1.487 +  ostr.imbue(loc);
   1.488 +  ostr << showbase;
   1.489 +
   1.490 +  // ostr.str("");
   1.491 +  // Check value with one decimal digit:
   1.492 +  {
   1.493 +    CPPUNIT_ASSERT( (has_facet<moneypunct<char, false> >(loc)) );
   1.494 +    moneypunct<char, false> const& dom_fmp = use_facet<moneypunct<char, false> >(loc);
   1.495 +    string str_res;
   1.496 +    // Check money_put
   1.497 +    {
   1.498 +      ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, false, ostr, ' ', 9);
   1.499 +
   1.500 +      CPPUNIT_ASSERT( !res.failed() );
   1.501 +      str_res = ostr.str();
   1.502 +
   1.503 +      size_t fieldIndex = 0;
   1.504 +      size_t index = 0;
   1.505 +
   1.506 +      if (dom_fmp.pos_format().field[fieldIndex] == money_base::sign) {
   1.507 +        CPPUNIT_ASSERT( str_res.substr(index, dom_fmp.positive_sign().size()) == dom_fmp.positive_sign() );
   1.508 +        index += dom_fmp.positive_sign().size();
   1.509 +        ++fieldIndex;
   1.510 +      }
   1.511 +
   1.512 +      string::size_type p = strlen( rl.money_prefix );
   1.513 +      if (p != 0) {
   1.514 +        CPPUNIT_ASSERT( str_res.substr(index, p) == rl.money_prefix );
   1.515 +        index += p;
   1.516 +        ++fieldIndex;
   1.517 +      }
   1.518 +      if (dom_fmp.neg_format().field[fieldIndex] == money_base::space ||
   1.519 +          dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
   1.520 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.521 +        ++fieldIndex;
   1.522 +      }
   1.523 +      if (dom_fmp.frac_digits() != 0) {
   1.524 +        CPPUNIT_ASSERT( str_res[index++] == '0' );
   1.525 +        CPPUNIT_ASSERT( str_res[index++] == dom_fmp.decimal_point() );
   1.526 +        for ( int fd = 1; fd < dom_fmp.frac_digits(); ++fd ) {
   1.527 +          CPPUNIT_ASSERT( str_res[index++] == '0' );
   1.528 +        }
   1.529 +      }
   1.530 +      CPPUNIT_ASSERT( str_res[index++] == '9' );
   1.531 +      ++fieldIndex;
   1.532 +
   1.533 +      //space cannot be last:
   1.534 +      if ((fieldIndex < 3) &&
   1.535 +          dom_fmp.neg_format().field[fieldIndex] == money_base::space) {
   1.536 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.537 +        ++fieldIndex;
   1.538 +      }
   1.539 +
   1.540 +      if (fieldIndex == 3) {
   1.541 +        //If none is last we should not add anything to the resulting string:
   1.542 +        if (dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
   1.543 +          CPPUNIT_ASSERT( index == str_res.size() );
   1.544 +        } else {
   1.545 +          CPPUNIT_ASSERT( dom_fmp.neg_format().field[fieldIndex] == money_base::symbol );
   1.546 +          CPPUNIT_ASSERT( str_res.substr(index, strlen(rl.money_suffix)) == rl.money_suffix );
   1.547 +        }
   1.548 +      }
   1.549 +    }
   1.550 +  }
   1.551 +
   1.552 +  ostr.str("");
   1.553 +  // Check value with two decimal digit:
   1.554 +  {
   1.555 +    CPPUNIT_ASSERT( (has_facet<moneypunct<char, false> >(loc)) );
   1.556 +    moneypunct<char, false> const& dom_fmp = use_facet<moneypunct<char, false> >(loc);
   1.557 +    string str_res;
   1.558 +    // Check money_put
   1.559 +    {
   1.560 +      ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, false, ostr, ' ', 90);
   1.561 +
   1.562 +      CPPUNIT_ASSERT( !res.failed() );
   1.563 +      str_res = ostr.str();
   1.564 +
   1.565 +      size_t fieldIndex = 0;
   1.566 +      size_t index = 0;
   1.567 +
   1.568 +      if (dom_fmp.pos_format().field[fieldIndex] == money_base::sign) {
   1.569 +        CPPUNIT_ASSERT( str_res.substr(index, dom_fmp.positive_sign().size()) == dom_fmp.positive_sign() );
   1.570 +        index += dom_fmp.positive_sign().size();
   1.571 +        ++fieldIndex;
   1.572 +      }
   1.573 +
   1.574 +      string::size_type p = strlen( rl.money_prefix );
   1.575 +      if (p != 0) {
   1.576 +        CPPUNIT_ASSERT( str_res.substr(index, p) == rl.money_prefix );
   1.577 +        index += p;
   1.578 +        ++fieldIndex;
   1.579 +      }
   1.580 +      if (dom_fmp.neg_format().field[fieldIndex] == money_base::space ||
   1.581 +          dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
   1.582 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.583 +        ++fieldIndex;
   1.584 +      }
   1.585 +      if (dom_fmp.frac_digits() != 0) {
   1.586 +        CPPUNIT_ASSERT( str_res[index++] == '0' );
   1.587 +        CPPUNIT_ASSERT( str_res[index++] == dom_fmp.decimal_point() );
   1.588 +        for ( int fd = 1; fd < dom_fmp.frac_digits() - 1; ++fd ) {
   1.589 +          CPPUNIT_ASSERT( str_res[index++] == '0' );
   1.590 +        }
   1.591 +      }
   1.592 +      CPPUNIT_ASSERT( str_res[index++] == '9' );
   1.593 +      if (dom_fmp.frac_digits() != 0) {
   1.594 +        CPPUNIT_ASSERT( str_res[index++] == '0' );
   1.595 +      }
   1.596 +      ++fieldIndex;
   1.597 +
   1.598 +      //space cannot be last:
   1.599 +      if ((fieldIndex < 3) &&
   1.600 +          dom_fmp.neg_format().field[fieldIndex] == money_base::space) {
   1.601 +        CPPUNIT_ASSERT( str_res[index++] == ' ' );
   1.602 +        ++fieldIndex;
   1.603 +      }
   1.604 +
   1.605 +      if (fieldIndex == 3) {
   1.606 +        //If none is last we should not add anything to the resulting string:
   1.607 +        if (dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
   1.608 +          CPPUNIT_ASSERT( index == str_res.size() );
   1.609 +        } else {
   1.610 +          CPPUNIT_ASSERT( dom_fmp.neg_format().field[fieldIndex] == money_base::symbol );
   1.611 +          CPPUNIT_ASSERT( str_res.substr(index, strlen(rl.money_suffix)) == rl.money_suffix );
   1.612 +        }
   1.613 +      }
   1.614 +    }
   1.615 +  }
   1.616 +}
   1.617 +
   1.618 +void LocaleTest::_time_put_get( const locale& loc, const ref_locale&)
   1.619 +{
   1.620 +  CPPUNIT_ASSERT( has_facet<time_put<char> >(loc) );
   1.621 +  const time_put<char>& tmp = use_facet<time_put<char> >(loc);
   1.622 +
   1.623 +  struct tm xmas = { 0, 0, 12, 25, 11, 93 };
   1.624 +  ostringstream ostr;
   1.625 +  ostr.imbue(loc);
   1.626 +  string format = "%B %d %Y";
   1.627 +
   1.628 +  time_put<char>::iter_type ret = tmp.put(ostr, ostr, ' ', &xmas, format.data(), format.data() + format.size());
   1.629 +  CPPUNIT_ASSERT( !ret.failed() );
   1.630 +
   1.631 +  /*
   1.632 +   * In other words, user conformation is required for reliable parsing
   1.633 +   * of user-entered dates and times, but machine-generated formats can be
   1.634 +   * parsed reliably. This allows parsers to be aggressive about interpreting
   1.635 +   * user variations on standard format.
   1.636 +   *
   1.637 +   *                                             ISO/IEC 14882, 22.2.5.1
   1.638 +   */
   1.639 +  CPPUNIT_ASSERT( has_facet<time_get<char> >(loc) );
   1.640 +  const time_get<char>& tmg = use_facet<time_get<char> >(loc);
   1.641 +  basic_ios<char> io(0);
   1.642 +  io.imbue(loc);
   1.643 +
   1.644 +  istringstream istr( ostr.str() );
   1.645 +  istreambuf_iterator<char, char_traits<char> > i( istr );
   1.646 +  istreambuf_iterator<char, char_traits<char> > e;
   1.647 +  ios_base::iostate err = ios_base::goodbit;
   1.648 +  struct tm other = { 15, 20, 9, 14, 7, 105 };
   1.649 +
   1.650 +  i = tmg.get_monthname( i, e, io, err, &other );
   1.651 +  CPPUNIT_ASSERT( err == ios_base::goodbit );
   1.652 +  CPPUNIT_ASSERT( other.tm_mon == xmas.tm_mon );
   1.653 +
   1.654 +  ++i; ++i; ++i; ++i; // skip day of month and spaces around it
   1.655 +  i = tmg.get_year( i, e, io, err, &other );
   1.656 +
   1.657 +  CPPUNIT_ASSERT( err == ios_base::eofbit );
   1.658 +  CPPUNIT_ASSERT( other.tm_year == xmas.tm_year );
   1.659 +
   1.660 +  ostringstream ostrX;
   1.661 +  ostrX.imbue(loc);
   1.662 +  format = "%x %X";
   1.663 +
   1.664 +  ret = tmp.put(ostrX, ostrX, ' ', &xmas, format.data(), format.data() + format.size());
   1.665 +  CPPUNIT_ASSERT( !ret.failed() );
   1.666 +
   1.667 +  istringstream istrX( ostrX.str() );
   1.668 +  istreambuf_iterator<char, char_traits<char> > j( istrX );
   1.669 +
   1.670 +  err = ios_base::goodbit;
   1.671 +
   1.672 +  struct tm yet_more = { 15, 20, 9, 14, 7, 105 };
   1.673 +
   1.674 +  j = tmg.get_date( j, e, io, err, &yet_more );
   1.675 +
   1.676 +  CPPUNIT_ASSERT( err == ios_base::goodbit );
   1.677 +
   1.678 +  CPPUNIT_ASSERT( yet_more.tm_sec != xmas.tm_sec );
   1.679 +  CPPUNIT_ASSERT( yet_more.tm_min != xmas.tm_min );
   1.680 +  CPPUNIT_ASSERT( yet_more.tm_hour != xmas.tm_hour );
   1.681 +  CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday );
   1.682 +  CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon );
   1.683 +  CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year );
   1.684 +
   1.685 +  ++j; // skip space
   1.686 +
   1.687 +  j = tmg.get_time( j, e, io, err, &yet_more );
   1.688 +
   1.689 +  CPPUNIT_ASSERT( err == ios_base::eofbit || err == ios_base::goodbit );
   1.690 +
   1.691 +  CPPUNIT_ASSERT( yet_more.tm_sec == xmas.tm_sec );
   1.692 +  CPPUNIT_ASSERT( yet_more.tm_min == xmas.tm_min );
   1.693 +  CPPUNIT_ASSERT( yet_more.tm_hour == xmas.tm_hour );
   1.694 +  CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday );
   1.695 +  CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon );
   1.696 +  CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year );
   1.697 +}
   1.698 +
   1.699 +void LocaleTest::_ctype_facet( const locale& loc, const ref_locale&)
   1.700 +{
   1.701 +#  if !(defined (__DMC__) && defined (_DLL))
   1.702 +  CPPUNIT_ASSERT( has_facet<ctype<char> >(loc) );
   1.703 +  ctype<char> const& ct = use_facet<ctype<char> >(loc);
   1.704 +
   1.705 +  //is
   1.706 +  {
   1.707 +    CPPUNIT_ASSERT( ct.is(ctype_base::digit, '0') );
   1.708 +    CPPUNIT_ASSERT( ct.is(ctype_base::upper, 'A') );
   1.709 +    CPPUNIT_ASSERT( ct.is(ctype_base::lower, 'a') );
   1.710 +    CPPUNIT_ASSERT( ct.is(ctype_base::alpha, 'A') );
   1.711 +    CPPUNIT_ASSERT( ct.is(ctype_base::space, ' ') );
   1.712 +    CPPUNIT_ASSERT( !ct.is(ctype_base::space, '2') );
   1.713 +    CPPUNIT_ASSERT( ct.is(ctype_base::punct, '.') );
   1.714 +    CPPUNIT_ASSERT( ct.is(ctype_base::xdigit, 'a') );
   1.715 +  }
   1.716 +
   1.717 +  //is range
   1.718 +  {
   1.719 +    char values[] = "0Aa .";
   1.720 +    ctype_base::mask res[sizeof(values)];
   1.721 +    ct.is(values, values + sizeof(values), res);
   1.722 +    // '0'
   1.723 +    CPPUNIT_ASSERT( (res[0] & ctype_base::print) != 0 );
   1.724 +    CPPUNIT_ASSERT( (res[0] & ctype_base::digit) != 0 );
   1.725 +    CPPUNIT_ASSERT( (res[0] & ctype_base::xdigit) != 0 );
   1.726 +    // 'A'
   1.727 +    CPPUNIT_ASSERT( (res[1] & ctype_base::print) != 0 );
   1.728 +    CPPUNIT_ASSERT( (res[1] & ctype_base::alpha) != 0 );
   1.729 +    CPPUNIT_ASSERT( (res[1] & ctype_base::xdigit) != 0 );
   1.730 +    CPPUNIT_ASSERT( (res[1] & ctype_base::upper) != 0 );
   1.731 +    // 'a'
   1.732 +    CPPUNIT_ASSERT( (res[2] & ctype_base::print) != 0 );
   1.733 +    CPPUNIT_ASSERT( (res[2] & ctype_base::alpha) != 0 );
   1.734 +    CPPUNIT_ASSERT( (res[2] & ctype_base::xdigit) != 0 );
   1.735 +    CPPUNIT_ASSERT( (res[2] & ctype_base::lower) != 0 );
   1.736 +    CPPUNIT_ASSERT( (res[2] & ctype_base::space) == 0 );
   1.737 +    // ' '
   1.738 +    CPPUNIT_ASSERT( (res[3] & ctype_base::print) != 0 );
   1.739 +    CPPUNIT_ASSERT( (res[3] & ctype_base::space) != 0 );
   1.740 +    CPPUNIT_ASSERT( (res[3] & ctype_base::digit) == 0 );
   1.741 +    // '.'
   1.742 +    CPPUNIT_ASSERT( (res[4] & ctype_base::print) != 0 );
   1.743 +    CPPUNIT_ASSERT( (res[4] & ctype_base::punct) != 0 );
   1.744 +    CPPUNIT_ASSERT( (res[4] & ctype_base::digit) == 0 );
   1.745 +  }
   1.746 +
   1.747 +  //scan_is
   1.748 +  {
   1.749 +    char range[] = "abAc123 .";
   1.750 +    const char *rbeg = range;
   1.751 +    const char *rend = range + sizeof(range);
   1.752 +
   1.753 +    const char *res;
   1.754 +    res = ct.scan_is((ctype_base::mask)(ctype_base::alpha | ctype_base::lower), rbeg, rend);
   1.755 +    CPPUNIT_ASSERT( res != rend );
   1.756 +    CPPUNIT_ASSERT( *res == 'a' );
   1.757 +
   1.758 +    res = ct.scan_is(ctype_base::upper, rbeg, rend);
   1.759 +    CPPUNIT_ASSERT( res != rend );
   1.760 +    CPPUNIT_ASSERT( *res == 'A' );
   1.761 +
   1.762 +    res = ct.scan_is(ctype_base::punct, rbeg, rend);
   1.763 +    CPPUNIT_ASSERT( res != rend );
   1.764 +    CPPUNIT_ASSERT( *res == '.' );
   1.765 +  }
   1.766 +
   1.767 +  //scan_not
   1.768 +  {
   1.769 +    char range[] = "abAc123 .";
   1.770 +    const char *rbeg = range;
   1.771 +    const char *rend = range + sizeof(range);
   1.772 +
   1.773 +    const char *res;
   1.774 +    res = ct.scan_not((ctype_base::mask)(ctype_base::alpha | ctype_base::lower), rbeg, rend);
   1.775 +    CPPUNIT_ASSERT( res != rend );
   1.776 +    CPPUNIT_ASSERT( *res == '1' );
   1.777 +
   1.778 +    res = ct.scan_not(ctype_base::alpha, rbeg, rend);
   1.779 +    CPPUNIT_ASSERT( res != rend );
   1.780 +    CPPUNIT_ASSERT( *res == '1' );
   1.781 +
   1.782 +    res = ct.scan_not(ctype_base::punct, rbeg, rend);
   1.783 +    CPPUNIT_ASSERT( res != rend );
   1.784 +    CPPUNIT_ASSERT( *res == 'a' );
   1.785 +  }
   1.786 +
   1.787 +  //toupper
   1.788 +  {
   1.789 +    CPPUNIT_ASSERT( ct.toupper('a') == 'A' );
   1.790 +    CPPUNIT_ASSERT( ct.toupper('A') == 'A' );
   1.791 +    CPPUNIT_ASSERT( ct.toupper('1') == '1' );
   1.792 +  }
   1.793 +
   1.794 +  //toupper range
   1.795 +  {
   1.796 +    char range[] = "abAc1";
   1.797 +    char expected_range[] = "ABAC1";
   1.798 +    ct.toupper(range, range + sizeof(range));
   1.799 +    CPPUNIT_ASSERT( equal(range, range + sizeof(range), expected_range) );
   1.800 +  }
   1.801 +
   1.802 +  //tolower
   1.803 +  {
   1.804 +    CPPUNIT_ASSERT( ct.tolower('A') == 'a' );
   1.805 +    CPPUNIT_ASSERT( ct.tolower('a') == 'a' );
   1.806 +    CPPUNIT_ASSERT( ct.tolower('1') == '1' );
   1.807 +  }
   1.808 +
   1.809 +  //tolower range
   1.810 +  {
   1.811 +    char range[] = "ABaC1";
   1.812 +    char expected_range[] = "abac1";
   1.813 +    ct.tolower(range, range + sizeof(range));
   1.814 +    CPPUNIT_ASSERT( equal(range, range + sizeof(range), expected_range) );
   1.815 +  }
   1.816 +
   1.817 +  //widen
   1.818 +  {
   1.819 +    CPPUNIT_ASSERT( ct.widen('a') == 'a' );
   1.820 +  }
   1.821 +
   1.822 +  //widen range
   1.823 +  {
   1.824 +    char range[] = "ABaC1";
   1.825 +    char res[sizeof(range)];
   1.826 +    ct.widen(range, range + sizeof(range), res);
   1.827 +    CPPUNIT_ASSERT( equal(range, range + sizeof(range), res) );
   1.828 +  }
   1.829 +
   1.830 +  //narrow
   1.831 +  {
   1.832 +    CPPUNIT_ASSERT( ct.narrow('a', 'b') == 'a' );
   1.833 +  }
   1.834 +
   1.835 +  //narrow range
   1.836 +  {
   1.837 +    char range[] = "ABaC1";
   1.838 +    char res[sizeof(range)];
   1.839 +    ct.narrow(range, range + sizeof(range), 'b', res);
   1.840 +    CPPUNIT_ASSERT( equal(range, range + sizeof(range), res) );
   1.841 +  }
   1.842 +#  endif /* __DMC__ */
   1.843 +}
   1.844 +
   1.845 +template <class _Tp>
   1.846 +void test_supported_locale(LocaleTest inst, _Tp __test) {
   1.847 +  size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]);
   1.848 +  for (size_t i = 0; i < n; ++i) {
   1.849 +    auto_ptr<locale> loc;
   1.850 +#  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
   1.851 +    try {
   1.852 +      loc.reset(new locale(tested_locales[i].name));
   1.853 +    }
   1.854 +    catch (runtime_error const&) {
   1.855 +      //This locale is not supported.
   1.856 +      continue;
   1.857 +    }
   1.858 +#  else
   1.859 +    //Without exception support we only test C locale.
   1.860 +    if (tested_locales[i].name[0] != 'C' ||
   1.861 +        tested_locales[i].name[1] != 0)
   1.862 +      continue;
   1.863 +    loc.reset(new locale(tested_locales[i].name));
   1.864 +#  endif
   1.865 +    CPPUNIT_MESSAGE( loc->name().c_str() );
   1.866 +    (inst.*__test)(*loc, tested_locales[i]);
   1.867 +  }
   1.868 +}
   1.869 +
   1.870 +void LocaleTest::locale_by_name() {
   1.871 +#  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
   1.872 +  /*
   1.873 +   * Check of the 22.1.1.2.7 standard point. Construction of a locale
   1.874 +   * instance from a null pointer or an unknown name should result in
   1.875 +   * a runtime_error exception.
   1.876 +   */
   1.877 +  try {
   1.878 +    locale loc(static_cast<char const*>(0));
   1.879 +    CPPUNIT_ASSERT( false );
   1.880 +  }
   1.881 +  catch (runtime_error const&) {
   1.882 +  }
   1.883 +  catch (...) {
   1.884 +    CPPUNIT_ASSERT( false );
   1.885 +  }
   1.886 +
   1.887 +  try {
   1.888 +    locale loc("yasli_language");
   1.889 +    CPPUNIT_ASSERT( false );
   1.890 +  }
   1.891 +  catch (runtime_error const&) {
   1.892 +  }
   1.893 +  catch (...) {
   1.894 +    CPPUNIT_ASSERT( false );
   1.895 +  }
   1.896 +#  endif
   1.897 +}
   1.898 +
   1.899 +void LocaleTest::loc_has_facet() {
   1.900 +  locale loc("C");
   1.901 +  typedef numpunct<char> implemented_facet;
   1.902 +  CPPUNIT_ASSERT( has_facet<implemented_facet>(loc) );
   1.903 +  /*
   1.904 +  typedef num_put<char, back_insert_iterator<string> > not_implemented_facet;
   1.905 +  CPPUNIT_ASSERT( !has_facet<not_implemented_facet>(loc) );
   1.906 +  */
   1.907 +}
   1.908 +
   1.909 +void LocaleTest::num_put_get()
   1.910 +{ test_supported_locale(*this, &LocaleTest::_num_put_get); }
   1.911 +
   1.912 +void LocaleTest::money_put_get()
   1.913 +{ test_supported_locale(*this, &LocaleTest::_money_put_get); }
   1.914 +
   1.915 +void LocaleTest::money_put_X_bug()
   1.916 +{ test_supported_locale(*this, &LocaleTest::_money_put_X_bug); }
   1.917 +
   1.918 +void LocaleTest::time_put_get()
   1.919 +{ test_supported_locale(*this, &LocaleTest::_time_put_get); }
   1.920 +
   1.921 +void LocaleTest::collate_facet()
   1.922 +{
   1.923 +  {
   1.924 +    CPPUNIT_ASSERT( has_facet<collate<char> >(locale::classic()) );
   1.925 +    collate<char> const& col = use_facet<collate<char> >(locale::classic());
   1.926 +
   1.927 +    char const str1[] = "abcdef1";
   1.928 +    char const str2[] = "abcdef2";
   1.929 +    const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
   1.930 +    const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
   1.931 +
   1.932 +    CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
   1.933 +    CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
   1.934 +
   1.935 +    //Smallest string should be before largest one:
   1.936 +    CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
   1.937 +    CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
   1.938 +  }
   1.939 +
   1.940 +#  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
   1.941 +  try {
   1.942 +    locale loc("fr_FR.ISO-8859-1");
   1.943 +    {
   1.944 +      CPPUNIT_ASSERT( has_facet<collate<char> >(loc) );
   1.945 +      collate<char> const& col = use_facet<collate<char> >(loc);
   1.946 +
   1.947 +      char const str1[] = "abcdef1";
   1.948 +      char const str2[] = "abcdef2";
   1.949 +      const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
   1.950 +      const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
   1.951 +
   1.952 +      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
   1.953 +      CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
   1.954 +
   1.955 +      //Smallest string should be before largest one:
   1.956 +      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
   1.957 +      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
   1.958 +    }
   1.959 +    {
   1.960 +      CPPUNIT_ASSERT( has_facet<collate<char> >(loc) );
   1.961 +      collate<char> const& col = use_facet<collate<char> >(loc);
   1.962 +
   1.963 +      string strs[] = {"abdd", "abçd", "abbd", "abcd"};
   1.964 +
   1.965 +      string transformed[4];
   1.966 +      for (size_t i = 0; i < 4; ++i) {
   1.967 +        transformed[i] = col.transform(strs[i].data(), strs[i].data() + strs[i].size());
   1.968 +      }
   1.969 +
   1.970 +      sort(strs, strs + 4, loc);
   1.971 +      // c and ç are considered same when strxfrm() is done on the string
   1.972 +      CPPUNIT_ASSERT( strs[0] == "abbd" );
   1.973 +      CPPUNIT_ASSERT( strs[1] == "abçd" );
   1.974 +      CPPUNIT_ASSERT( strs[2] == "abcd" );
   1.975 +      CPPUNIT_ASSERT( strs[3] == "abdd" );
   1.976 +
   1.977 +      sort(transformed, transformed + 4);
   1.978 +
   1.979 +      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + strs[0].size()) == transformed[0] );
   1.980 +      CPPUNIT_ASSERT( col.transform(strs[1].data(), strs[1].data() + strs[1].size()) == transformed[1] );
   1.981 +      CPPUNIT_ASSERT( col.transform(strs[2].data(), strs[2].data() + strs[2].size()) == transformed[2] );
   1.982 +      CPPUNIT_ASSERT( col.transform(strs[3].data(), strs[3].data() + strs[3].size()) == transformed[3] );
   1.983 +
   1.984 +      // Check empty string result in empty key.
   1.985 +      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data()).empty() );
   1.986 +
   1.987 +      // Check that only characters that matter are taken into accout to build the key.
   1.988 +      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + 2) == col.transform(strs[1].data(), strs[1].data() + 2) );
   1.989 +    }
   1.990 +#    if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
   1.991 +    {
   1.992 +      CPPUNIT_ASSERT( has_facet<collate<wchar_t> >(loc) );
   1.993 +      collate<wchar_t> const& col = use_facet<collate<wchar_t> >(loc);
   1.994 +
   1.995 +      wchar_t const str1[] = L"abcdef1";
   1.996 +      wchar_t const str2[] = L"abcdef2";
   1.997 +      const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
   1.998 +      const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
   1.999 +
  1.1000 +      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
  1.1001 +      CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
  1.1002 +
  1.1003 +      //Smallest string should be before largest one:
  1.1004 +      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
  1.1005 +      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
  1.1006 +    }
  1.1007 +    {
  1.1008 +      size_t i;
  1.1009 +      CPPUNIT_ASSERT( has_facet<collate<wchar_t> >(loc) );
  1.1010 +      collate<wchar_t> const& col = use_facet<collate<wchar_t> >(loc);
  1.1011 +
  1.1012 +      // Here we would like to use L"abçd" but it looks like all compilers
  1.1013 +      // do not support storage of unicode characters in exe resulting in
  1.1014 +      // compilation error. We avoid this test for the moment.
  1.1015 +      wstring strs[] = {L"abdd", L"abcd", L"abbd", L"abcd"};
  1.1016 +
  1.1017 +      wstring transformed[4];
  1.1018 +      for (i = 0; i < 4; ++i) {
  1.1019 +        transformed[i] = col.transform(strs[i].data(), strs[i].data() + strs[i].size());
  1.1020 +      }
  1.1021 +
  1.1022 +      sort(strs, strs + 4, loc);
  1.1023 +      CPPUNIT_ASSERT( strs[0] == L"abbd" );
  1.1024 +      CPPUNIT_ASSERT( strs[1] == L"abcd" );
  1.1025 +      CPPUNIT_ASSERT( strs[2] == L"abcd" );
  1.1026 +      CPPUNIT_ASSERT( strs[3] == L"abdd" );
  1.1027 +
  1.1028 +      sort(transformed, transformed + 4);
  1.1029 +
  1.1030 +      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + strs[0].size()) == transformed[0] );
  1.1031 +      CPPUNIT_ASSERT( col.transform(strs[1].data(), strs[1].data() + strs[1].size()) == transformed[1] );
  1.1032 +      CPPUNIT_ASSERT( col.transform(strs[2].data(), strs[2].data() + strs[2].size()) == transformed[2] );
  1.1033 +      CPPUNIT_ASSERT( col.transform(strs[3].data(), strs[3].data() + strs[3].size()) == transformed[3] );
  1.1034 +
  1.1035 +      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data()).empty() );
  1.1036 +
  1.1037 +      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + 2) == col.transform(strs[1].data(), strs[1].data() + 2) );
  1.1038 +    }
  1.1039 +#    endif
  1.1040 +  }
  1.1041 +  catch (runtime_error const&) {
  1.1042 +    CPPUNIT_MESSAGE("No french locale to check collate facet");
  1.1043 +  }
  1.1044 +#  endif
  1.1045 +}
  1.1046 +
  1.1047 +void LocaleTest::ctype_facet()
  1.1048 +{ test_supported_locale(*this, &LocaleTest::_ctype_facet); }
  1.1049 +
  1.1050 +void LocaleTest::locale_init_problem() {
  1.1051 +#  if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
  1.1052 +  test_supported_locale(*this, &LocaleTest::_locale_init_problem);
  1.1053 +#  endif
  1.1054 +}
  1.1055 +
  1.1056 +
  1.1057 +/*
  1.1058 + * Creation of a locale instance imply initialization of some STLport internal
  1.1059 + * static objects first. We use a static instance of locale to check that this
  1.1060 + * initialization is done correctly.
  1.1061 + */
  1.1062 +static locale global_loc;
  1.1063 +static locale other_loc("");
  1.1064 +
  1.1065 +#  if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
  1.1066 +void LocaleTest::_locale_init_problem( const locale& loc, const ref_locale&)
  1.1067 +{
  1.1068 +#    if !defined (__APPLE__) && !defined (__FreeBSD__) || \
  1.1069 +        !defined(__GNUC__) || ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__> 3)))
  1.1070 +  typedef codecvt<char,char,mbstate_t> my_facet;
  1.1071 +#    else
  1.1072 +// std::mbstate_t required for gcc 3.3.2 on FreeBSD...
  1.1073 +// I am not sure what key here---FreeBSD or 3.3.2...
  1.1074 +//      - ptr 2005-04-04
  1.1075 +  typedef codecvt<char,char,std::mbstate_t> my_facet;
  1.1076 +#    endif
  1.1077 +
  1.1078 +#    if !(defined (__DMC__) && defined (_DLL))
  1.1079 +  locale loc_ref(global_loc);
  1.1080 +  {
  1.1081 +    locale gloc( loc_ref, new my_facet() );
  1.1082 +    CPPUNIT_ASSERT( has_facet<my_facet>( gloc ) );
  1.1083 +    //The following code is just here to try to confuse the reference counting underlying mecanism:
  1.1084 +    locale::global( locale::classic() );
  1.1085 +    locale::global( gloc );
  1.1086 +  }
  1.1087 +
  1.1088 +#      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
  1.1089 +  try {
  1.1090 +#      endif
  1.1091 +    ostringstream os("test") ;
  1.1092 +    locale loc2( loc, new my_facet() );
  1.1093 +    CPPUNIT_ASSERT( has_facet<my_facet>( loc2 ) );
  1.1094 +    os.imbue( loc2 );
  1.1095 +#      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
  1.1096 +  }
  1.1097 +  catch ( runtime_error& ) {
  1.1098 +    CPPUNIT_ASSERT( false );
  1.1099 +  }
  1.1100 +  catch ( ... ) {
  1.1101 +   CPPUNIT_ASSERT( false );
  1.1102 +  }
  1.1103 +#      endif
  1.1104 +
  1.1105 +#      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
  1.1106 +  try {
  1.1107 +#      endif
  1.1108 +    ostringstream os2("test2");
  1.1109 +#      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
  1.1110 +  }
  1.1111 +  catch ( runtime_error& ) {
  1.1112 +    CPPUNIT_ASSERT( false );
  1.1113 +  }
  1.1114 +  catch ( ... ) {
  1.1115 +    CPPUNIT_ASSERT( false );
  1.1116 +  }
  1.1117 +#      endif
  1.1118 +#    endif /* __DMC__ */
  1.1119 +}
  1.1120 +#  endif
  1.1121 +
  1.1122 +void LocaleTest::default_locale()
  1.1123 +{
  1.1124 +  locale loc( "" );
  1.1125 +}
  1.1126 +
  1.1127 +void LocaleTest::facet_id()
  1.1128 +{
  1.1129 +#if defined (__SYMBIAN32__NO_STATIC_IMPORTS__) || defined (__SYMBIAN32__WSD__)
  1.1130 +#  if defined (STLPORT)
  1.1131 +  locale::id _id_01 = collate<char>::GetFacetLocaleId();
  1.1132 +  CPPUNIT_CHECK( _id_01._M_index == 1 );
  1.1133 +
  1.1134 +  locale::id _id_02 = ctype<char>::GetFacetLocaleId();
  1.1135 +  CPPUNIT_CHECK( _id_02._M_index == 2 );
  1.1136 +
  1.1137 +#    ifndef _STLP_NO_MBSTATE_T
  1.1138 +  locale::id _id_03 = codecvt<char, char, mbstate_t>::GetFacetLocaleId();
  1.1139 +  CPPUNIT_CHECK( _id_03._M_index == 3 );
  1.1140 +#    endif
  1.1141 +
  1.1142 +  locale::id _id_04 = moneypunct<char, true>::GetFacetLocaleId();
  1.1143 +  CPPUNIT_CHECK( _id_04._M_index == 4 );
  1.1144 +
  1.1145 +  locale::id _id_05 = moneypunct<char, false>::GetFacetLocaleId();
  1.1146 +  CPPUNIT_CHECK( _id_05._M_index == 5 );
  1.1147 +
  1.1148 +  locale::id _id_06 = numpunct<char>::GetFacetLocaleId();
  1.1149 +  CPPUNIT_CHECK( _id_06._M_index == 6 );
  1.1150 +
  1.1151 +  locale::id _id_07 = messages<char>::GetFacetLocaleId();
  1.1152 +  CPPUNIT_CHECK( _id_07._M_index == 7 );
  1.1153 +
  1.1154 +  locale::id _id_08 = money_get<char, istreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
  1.1155 +  CPPUNIT_CHECK( _id_08._M_index == 8 );
  1.1156 +
  1.1157 +  /*
  1.1158 +  locale::id _id_09 = money_get<char, const char*>::id;
  1.1159 +  CPPUNIT_CHECK( _id_09._M_index == 9 );
  1.1160 +  */
  1.1161 +
  1.1162 +  locale::id _id_10 = money_put<char, ostreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
  1.1163 +  CPPUNIT_CHECK( _id_10._M_index == 10 );
  1.1164 +
  1.1165 +  /*
  1.1166 +  locale::id _id_11 = money_put<char, char*>::id;
  1.1167 +  CPPUNIT_CHECK( _id_11._M_index == 11 );
  1.1168 +  */
  1.1169 +
  1.1170 +  locale::id _id_12 = num_get<char, istreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
  1.1171 +  CPPUNIT_CHECK( _id_12._M_index == 12 );
  1.1172 +
  1.1173 +  /*
  1.1174 +  locale::id _id_13 = num_get<char, const char*>::id;
  1.1175 +  CPPUNIT_CHECK( _id_13._M_index == 13 );
  1.1176 +  */
  1.1177 +
  1.1178 +  locale::id _id_14 = num_put<char, ostreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
  1.1179 +  CPPUNIT_CHECK( _id_14._M_index == 14 );
  1.1180 +
  1.1181 +  /*
  1.1182 +  locale::id _id_15 = num_put<char, char*>::id;
  1.1183 +  CPPUNIT_CHECK( _id_15._M_index == 15 );
  1.1184 +  */
  1.1185 +
  1.1186 +  locale::id _id_16 = time_get<char, istreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
  1.1187 +  CPPUNIT_CHECK( _id_16._M_index == 16 );
  1.1188 +
  1.1189 +  /*
  1.1190 +  locale::id _id_17 = time_get<char, const char*>::id;
  1.1191 +  CPPUNIT_CHECK( _id_17._M_index == 17 );
  1.1192 +  */
  1.1193 +
  1.1194 +  locale::id _id_18 = time_put<char, ostreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
  1.1195 +  CPPUNIT_CHECK( _id_18._M_index == 18 );
  1.1196 +
  1.1197 +  /*
  1.1198 +  locale::id _id_19 = time_put<char, char*>::id;
  1.1199 +  CPPUNIT_CHECK( _id_19._M_index == 19 );
  1.1200 +  */
  1.1201 +
  1.1202 +#    ifndef _STLP_NO_WCHAR_T
  1.1203 +  locale::id _id_20 = collate<wchar_t>::GetFacetLocaleId();
  1.1204 +  CPPUNIT_CHECK( _id_20._M_index == 20 );
  1.1205 +
  1.1206 +  locale::id _id_21 = ctype<wchar_t>::GetFacetLocaleId();
  1.1207 +  CPPUNIT_CHECK( _id_21._M_index == 21 );
  1.1208 +
  1.1209 +#      ifndef _STLP_NO_MBSTATE_T
  1.1210 +  locale::id _id_22 = codecvt<wchar_t, char, mbstate_t>::GetFacetLocaleId();
  1.1211 +  CPPUNIT_CHECK( _id_22._M_index == 22 );
  1.1212 +#      endif
  1.1213 +  locale::id _id_23 = moneypunct<wchar_t, true>::GetFacetLocaleId();
  1.1214 +  CPPUNIT_CHECK( _id_23._M_index == 23 );
  1.1215 +
  1.1216 +  locale::id _id_24 = moneypunct<wchar_t, false>::GetFacetLocaleId();
  1.1217 +  CPPUNIT_CHECK( _id_24._M_index == 24 );
  1.1218 +
  1.1219 +  locale::id _id_25 = numpunct<wchar_t>::GetFacetLocaleId();
  1.1220 +  CPPUNIT_CHECK( _id_25._M_index == 25 );
  1.1221 +
  1.1222 +  locale::id _id_26 = messages<wchar_t>::GetFacetLocaleId();
  1.1223 +  CPPUNIT_CHECK( _id_26._M_index == 26 );
  1.1224 +
  1.1225 +  locale::id _id_27 = money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
  1.1226 +  CPPUNIT_CHECK( _id_27._M_index == 27 );
  1.1227 +
  1.1228 +  /*
  1.1229 +  locale::id _id_28 = money_get<wchar_t, const wchar_t*>::id;
  1.1230 +  CPPUNIT_CHECK( _id_28._M_index == 28 );
  1.1231 +  */
  1.1232 +
  1.1233 +  locale::id _id_29 = money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
  1.1234 +  CPPUNIT_CHECK( _id_29._M_index == 29 );
  1.1235 +
  1.1236 +  /*
  1.1237 +  locale::id _id_30 = money_put<wchar_t, wchar_t*>::id;
  1.1238 +  CPPUNIT_CHECK( _id_30._M_index == 30 );
  1.1239 +  */
  1.1240 +
  1.1241 +  locale::id _id_31 = num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
  1.1242 +  CPPUNIT_CHECK( _id_31._M_index == 31 );
  1.1243 +
  1.1244 +  /*
  1.1245 +  locale::id _id_32 = num_get<wchar_t, const wchar_t*>::id;
  1.1246 +  CPPUNIT_CHECK( _id_32._M_index == 32 );
  1.1247 +  */
  1.1248 +
  1.1249 +  locale::id _id_33 = num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > ::GetFacetLocaleId();
  1.1250 +  CPPUNIT_CHECK( _id_33._M_index == 33 );
  1.1251 +
  1.1252 +  /*
  1.1253 +  locale::id _id_34 = num_put<wchar_t, wchar_t*>::id;
  1.1254 +  CPPUNIT_CHECK( _id_34._M_index == 34 );
  1.1255 +  */
  1.1256 +
  1.1257 +  locale::id _id_35 = time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
  1.1258 +  CPPUNIT_CHECK( _id_35._M_index == 35 );
  1.1259 +
  1.1260 +  /*
  1.1261 +  locale::id _id_36 = time_get<wchar_t, const wchar_t*>::id;
  1.1262 +  CPPUNIT_CHECK( _id_36._M_index == 36 );
  1.1263 +  */
  1.1264 +
  1.1265 +  locale::id _id_37 = time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
  1.1266 +  CPPUNIT_CHECK( _id_37._M_index == 37 );
  1.1267 +
  1.1268 +  /*
  1.1269 +  locale::id _id_38 = time_put<wchar_t, wchar_t*>::id;
  1.1270 +  CPPUNIT_CHECK( _id_38._M_index == 38 );
  1.1271 +  */
  1.1272 +#    endif
  1.1273 +#  endif
  1.1274 +
  1.1275 +#else
  1.1276 +
  1.1277 +#  if defined (STLPORT)
  1.1278 +  locale::id _id_01 = collate<char>::id;
  1.1279 +  CPPUNIT_CHECK( _id_01._M_index == 1 );
  1.1280 +
  1.1281 +  locale::id _id_02 = ctype<char>::id;
  1.1282 +  CPPUNIT_CHECK( _id_02._M_index == 2 );
  1.1283 +
  1.1284 +#    ifndef _STLP_NO_MBSTATE_T
  1.1285 +  locale::id _id_03 = codecvt<char, char, mbstate_t>::id;
  1.1286 +  CPPUNIT_CHECK( _id_03._M_index == 3 );
  1.1287 +#    endif
  1.1288 +
  1.1289 +  locale::id _id_04 = moneypunct<char, true>::id;
  1.1290 +  CPPUNIT_CHECK( _id_04._M_index == 4 );
  1.1291 +
  1.1292 +  locale::id _id_05 = moneypunct<char, false>::id;
  1.1293 +  CPPUNIT_CHECK( _id_05._M_index == 5 );
  1.1294 +
  1.1295 +  locale::id _id_06 = numpunct<char>::id;
  1.1296 +  CPPUNIT_CHECK( _id_06._M_index == 6 );
  1.1297 +
  1.1298 +  locale::id _id_07 = messages<char>::id;
  1.1299 +  CPPUNIT_CHECK( _id_07._M_index == 7 );
  1.1300 +
  1.1301 +  locale::id _id_08 = money_get<char, istreambuf_iterator<char, char_traits<char> > >::id;
  1.1302 +  CPPUNIT_CHECK( _id_08._M_index == 8 );
  1.1303 +
  1.1304 +  /*
  1.1305 +  locale::id _id_09 = money_get<char, const char*>::id;
  1.1306 +  CPPUNIT_CHECK( _id_09._M_index == 9 );
  1.1307 +  */
  1.1308 +
  1.1309 +  locale::id _id_10 = money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
  1.1310 +  CPPUNIT_CHECK( _id_10._M_index == 10 );
  1.1311 +
  1.1312 +  /*
  1.1313 +  locale::id _id_11 = money_put<char, char*>::id;
  1.1314 +  CPPUNIT_CHECK( _id_11._M_index == 11 );
  1.1315 +  */
  1.1316 +
  1.1317 +  locale::id _id_12 = num_get<char, istreambuf_iterator<char, char_traits<char> > >::id;
  1.1318 +  CPPUNIT_CHECK( _id_12._M_index == 12 );
  1.1319 +
  1.1320 +  /*
  1.1321 +  locale::id _id_13 = num_get<char, const char*>::id;
  1.1322 +  CPPUNIT_CHECK( _id_13._M_index == 13 );
  1.1323 +  */
  1.1324 +
  1.1325 +  locale::id _id_14 = num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
  1.1326 +  CPPUNIT_CHECK( _id_14._M_index == 14 );
  1.1327 +
  1.1328 +  /*
  1.1329 +  locale::id _id_15 = num_put<char, char*>::id;
  1.1330 +  CPPUNIT_CHECK( _id_15._M_index == 15 );
  1.1331 +  */
  1.1332 +
  1.1333 +  locale::id _id_16 = time_get<char, istreambuf_iterator<char, char_traits<char> > >::id;
  1.1334 +  CPPUNIT_CHECK( _id_16._M_index == 16 );
  1.1335 +
  1.1336 +  /*
  1.1337 +  locale::id _id_17 = time_get<char, const char*>::id;
  1.1338 +  CPPUNIT_CHECK( _id_17._M_index == 17 );
  1.1339 +  */
  1.1340 +
  1.1341 +  locale::id _id_18 = time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
  1.1342 +  CPPUNIT_CHECK( _id_18._M_index == 18 );
  1.1343 +
  1.1344 +  /*
  1.1345 +  locale::id _id_19 = time_put<char, char*>::id;
  1.1346 +  CPPUNIT_CHECK( _id_19._M_index == 19 );
  1.1347 +  */
  1.1348 +
  1.1349 +#    ifndef _STLP_NO_WCHAR_T
  1.1350 +  locale::id _id_20 = collate<wchar_t>::id;
  1.1351 +  CPPUNIT_CHECK( _id_20._M_index == 20 );
  1.1352 +
  1.1353 +  locale::id _id_21 = ctype<wchar_t>::id;
  1.1354 +  CPPUNIT_CHECK( _id_21._M_index == 21 );
  1.1355 +
  1.1356 +#      ifndef _STLP_NO_MBSTATE_T
  1.1357 +  locale::id _id_22 = codecvt<wchar_t, char, mbstate_t>::id;
  1.1358 +  CPPUNIT_CHECK( _id_22._M_index == 22 );
  1.1359 +#      endif
  1.1360 +  locale::id _id_23 = moneypunct<wchar_t, true>::id;
  1.1361 +  CPPUNIT_CHECK( _id_23._M_index == 23 );
  1.1362 +
  1.1363 +  locale::id _id_24 = moneypunct<wchar_t, false>::id;
  1.1364 +  CPPUNIT_CHECK( _id_24._M_index == 24 );
  1.1365 +
  1.1366 +  locale::id _id_25 = numpunct<wchar_t>::id;
  1.1367 +  CPPUNIT_CHECK( _id_25._M_index == 25 );
  1.1368 +
  1.1369 +  locale::id _id_26 = messages<wchar_t>::id;
  1.1370 +  CPPUNIT_CHECK( _id_26._M_index == 26 );
  1.1371 +
  1.1372 +  locale::id _id_27 = money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
  1.1373 +  CPPUNIT_CHECK( _id_27._M_index == 27 );
  1.1374 +
  1.1375 +  /*
  1.1376 +  locale::id _id_28 = money_get<wchar_t, const wchar_t*>::id;
  1.1377 +  CPPUNIT_CHECK( _id_28._M_index == 28 );
  1.1378 +  */
  1.1379 +
  1.1380 +  locale::id _id_29 = money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
  1.1381 +  CPPUNIT_CHECK( _id_29._M_index == 29 );
  1.1382 +
  1.1383 +  /*
  1.1384 +  locale::id _id_30 = money_put<wchar_t, wchar_t*>::id;
  1.1385 +  CPPUNIT_CHECK( _id_30._M_index == 30 );
  1.1386 +  */
  1.1387 +
  1.1388 +  locale::id _id_31 = num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
  1.1389 +  CPPUNIT_CHECK( _id_31._M_index == 31 );
  1.1390 +
  1.1391 +  /*
  1.1392 +  locale::id _id_32 = num_get<wchar_t, const wchar_t*>::id;
  1.1393 +  CPPUNIT_CHECK( _id_32._M_index == 32 );
  1.1394 +  */
  1.1395 +
  1.1396 +  locale::id _id_33 = num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > ::id;
  1.1397 +  CPPUNIT_CHECK( _id_33._M_index == 33 );
  1.1398 +
  1.1399 +  /*
  1.1400 +  locale::id _id_34 = num_put<wchar_t, wchar_t*>::id;
  1.1401 +  CPPUNIT_CHECK( _id_34._M_index == 34 );
  1.1402 +  */
  1.1403 +
  1.1404 +  locale::id _id_35 = time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
  1.1405 +  CPPUNIT_CHECK( _id_35._M_index == 35 );
  1.1406 +
  1.1407 +  /*
  1.1408 +  locale::id _id_36 = time_get<wchar_t, const wchar_t*>::id;
  1.1409 +  CPPUNIT_CHECK( _id_36._M_index == 36 );
  1.1410 +  */
  1.1411 +
  1.1412 +  locale::id _id_37 = time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
  1.1413 +  CPPUNIT_CHECK( _id_37._M_index == 37 );
  1.1414 +
  1.1415 +  /*
  1.1416 +  locale::id _id_38 = time_put<wchar_t, wchar_t*>::id;
  1.1417 +  CPPUNIT_CHECK( _id_38._M_index == 38 );
  1.1418 +  */
  1.1419 +#    endif
  1.1420 +#  endif
  1.1421 +#  endif //__WINSCW__
  1.1422 +}
  1.1423 +
  1.1424 +void LocaleTest::combine()
  1.1425 +{
  1.1426 +#  if (!defined (STLPORT) || \
  1.1427 +       (defined (_STLP_USE_EXCEPTIONS) && !defined (_STLP_NO_MEMBER_TEMPLATES) && !defined (_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS)))
  1.1428 +  auto_ptr<locale> loc1, loc2;
  1.1429 +  size_t loc1_index = 0;
  1.1430 +  size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]);
  1.1431 +  for (size_t i = 0; i < n; ++i) {
  1.1432 +    try {
  1.1433 +      locale *ploc = new locale(tested_locales[i].name);
  1.1434 +      if (loc1.get() == 0)
  1.1435 +      {
  1.1436 +        loc1.reset(ploc);
  1.1437 +        loc1_index = i;
  1.1438 +        continue;
  1.1439 +      }
  1.1440 +      else
  1.1441 +      {
  1.1442 +        loc2.reset(ploc);
  1.1443 +      }
  1.1444 +
  1.1445 +      //We can start the test
  1.1446 +      ostringstream ostr;
  1.1447 +      ostr << "combining '" << loc2->name() << "' money facets with '" << loc1->name() << "'";
  1.1448 +      CPPUNIT_MESSAGE( ostr.str().c_str() );
  1.1449 +
  1.1450 +      //We are going to combine money facets as all formats are different.
  1.1451 +      {
  1.1452 +        //We check that resulting locale has correctly acquire loc2 facets.
  1.1453 +        locale loc = loc1->combine<moneypunct<char, true> >(*loc2);
  1.1454 +        loc = loc.combine<moneypunct<char, false> >(*loc2);
  1.1455 +        loc = loc.combine<money_put<char> >(*loc2);
  1.1456 +        loc = loc.combine<money_get<char> >(*loc2);
  1.1457 +
  1.1458 +        //Check loc has the correct facets:
  1.1459 +        _money_put_get2(*loc2, loc, tested_locales[i]);
  1.1460 +
  1.1461 +        //Check loc1 has not been impacted:
  1.1462 +        _money_put_get2(*loc1, *loc1, tested_locales[loc1_index]);
  1.1463 +
  1.1464 +        //Check loc2 has not been impacted:
  1.1465 +        _money_put_get2(*loc2, *loc2, tested_locales[i]);
  1.1466 +      }
  1.1467 +      {
  1.1468 +        //We check that resulting locale has not wrongly acquire loc1 facets that hasn't been combine:
  1.1469 +        locale loc = loc2->combine<numpunct<char> >(*loc1);
  1.1470 +        loc = loc.combine<time_put<char> >(*loc1);
  1.1471 +        loc = loc.combine<time_get<char> >(*loc1);
  1.1472 +
  1.1473 +        //Check loc has the correct facets:
  1.1474 +        _money_put_get2(*loc2, loc, tested_locales[i]);
  1.1475 +
  1.1476 +        //Check loc1 has not been impacted:
  1.1477 +        _money_put_get2(*loc1, *loc1, tested_locales[loc1_index]);
  1.1478 +
  1.1479 +        //Check loc2 has not been impacted:
  1.1480 +        _money_put_get2(*loc2, *loc2, tested_locales[i]);
  1.1481 +      }
  1.1482 +
  1.1483 +      {
  1.1484 +        // Check auto combination do not result in weird reference counting behavior 
  1.1485 +        // (might generate a crash).
  1.1486 +        loc1->combine<numpunct<char> >(*loc1);
  1.1487 +      }
  1.1488 +
  1.1489 +      loc1.reset(loc2.release());
  1.1490 +      loc1_index = i;
  1.1491 +    }
  1.1492 +    catch (runtime_error const&) {
  1.1493 +      //This locale is not supported.
  1.1494 +      continue;
  1.1495 +    }
  1.1496 +  }
  1.1497 +#  endif
  1.1498 +}
  1.1499 +
  1.1500 +#endif