genericopenlibs/cppstdlib/stl/test/unit/locale_test.cpp
changeset 0 e4d67989cc36
child 18 47c74d1534e1
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4  */
       
     5 #include <string>
       
     6 
       
     7 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
       
     8 #  include <sstream>
       
     9 #  include <locale>
       
    10 #  include <stdexcept>
       
    11 #  include <memory>
       
    12 #  include <algorithm>
       
    13 //#  include <iostream>
       
    14 
       
    15 #  include "cppunit/cppunit_proxy.h"
       
    16 
       
    17 #  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
       
    18 using namespace std;
       
    19 #  endif
       
    20 
       
    21 struct ref_locale {
       
    22   const char *name;
       
    23   const char *decimal_point;
       
    24   const char *thousands_sep;
       
    25   const char *money_int_prefix;
       
    26   const char *money_int_prefix_old;
       
    27   const char *money_prefix;
       
    28   const char *money_suffix;
       
    29   const char *money_decimal_point;
       
    30   const char *money_thousands_sep;
       
    31 };
       
    32 
       
    33 // Pls, don't write #ifdef _STLP_REAL_LOCALE_IMPLEMENTED here!
       
    34 // It undefined in any case!!!!!
       
    35 
       
    36 static const ref_locale tested_locales[] = {
       
    37 //{  name,         decimal_point, thousands_sep, money_int_prefix, money_int_prefix_old, money_prefix, money_suffix, money_decimal_point, money_thousands_sep},
       
    38   { "fr_FR",       ",",           "\xa0",        "EUR ",           "FRF ",               "",           "",           ",",
       
    39 #  if defined (WIN32) || defined (_WIN32)
       
    40                                                                                                                                           "\xa0" },
       
    41 #  else
       
    42                                                                                                                                           " " },
       
    43 #  endif
       
    44   { "ru_RU.koi8r", ",",           ".",           "RUB ",           "RUR ",               "",           "\xd2\xd5\xc2", ".",               " " },
       
    45   { "en_GB",       ".",           ",",           "GBP ",           "",                   "\xa3",       "",           ".",                 "," },
       
    46   { "en_US",       ".",           ",",           "USD ",           "",                   "$",          "",           ".",                 "," },
       
    47   { "C",           ".",           ",",           "",               "",                   "",           "",           " ",                 " " },
       
    48 };
       
    49 
       
    50 
       
    51 //
       
    52 // TestCase class
       
    53 //
       
    54 class LocaleTest : public CPPUNIT_NS::TestCase
       
    55 {
       
    56   CPPUNIT_TEST_SUITE(LocaleTest);
       
    57 #  if defined (STLPORT) && !defined (_STLP_USE_EXCEPTIONS)
       
    58   CPPUNIT_IGNORE;
       
    59 #  endif
       
    60   CPPUNIT_TEST(locale_by_name);
       
    61   CPPUNIT_STOP_IGNORE;
       
    62   CPPUNIT_TEST(loc_has_facet);
       
    63   CPPUNIT_TEST(num_put_get);
       
    64   CPPUNIT_TEST(money_put_get);
       
    65   CPPUNIT_TEST(money_put_X_bug);
       
    66   CPPUNIT_TEST(time_put_get);
       
    67 #  if defined (__DMC__) && defined (_DLL)
       
    68   CPPUNIT_IGNORE;
       
    69 #  endif
       
    70   CPPUNIT_TEST(collate_facet);
       
    71   CPPUNIT_TEST(ctype_facet);
       
    72 #  if defined (STLPORT) && defined (_STLP_NO_MEMBER_TEMPLATES)
       
    73   CPPUNIT_IGNORE;
       
    74 #  endif
       
    75   CPPUNIT_TEST(locale_init_problem);
       
    76   CPPUNIT_STOP_IGNORE;
       
    77   CPPUNIT_TEST(default_locale);
       
    78 #  if !defined (STLPORT)
       
    79   CPPUNIT_IGNORE;
       
    80 #  endif
       
    81   CPPUNIT_TEST(facet_id);
       
    82   CPPUNIT_STOP_IGNORE;
       
    83 #  if defined (STLPORT) && \
       
    84      (!defined (_STLP_USE_EXCEPTIONS) || defined (_STLP_NO_MEMBER_TEMPLATES) || defined (_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS))
       
    85   CPPUNIT_IGNORE;
       
    86 #  endif
       
    87   CPPUNIT_TEST(combine);
       
    88   CPPUNIT_TEST_SUITE_END();
       
    89 
       
    90 public:
       
    91   void locale_by_name();
       
    92   void loc_has_facet();
       
    93   void num_put_get();
       
    94   void money_put_get();
       
    95   void time_put_get();
       
    96   void collate_facet();
       
    97   void ctype_facet();
       
    98   void locale_init_problem();
       
    99   void money_put_X_bug();
       
   100   void default_locale();
       
   101   void facet_id();
       
   102   void combine();
       
   103 private:
       
   104   void _loc_has_facet( const locale&, const ref_locale& );
       
   105   void _num_put_get( const locale&, const ref_locale& );
       
   106   void _money_put_get( const locale&, const ref_locale& );
       
   107   void _money_put_get2( const locale& loc, const locale& streamLoc, const ref_locale& );
       
   108   void _time_put_get( const locale&, const ref_locale& );
       
   109   void _ctype_facet( const locale&, const ref_locale& );
       
   110   void _locale_init_problem( const locale&, const ref_locale& );
       
   111   void _money_put_X_bug( const locale&, const ref_locale& );
       
   112 };
       
   113 
       
   114 CPPUNIT_TEST_SUITE_REGISTRATION(LocaleTest);
       
   115 
       
   116 //
       
   117 // tests implementation
       
   118 //
       
   119 void LocaleTest::_num_put_get( const locale& loc, const ref_locale& rl ) {
       
   120   CPPUNIT_ASSERT( has_facet<numpunct<char> >(loc) );
       
   121   numpunct<char> const& npct = use_facet<numpunct<char> >(loc);
       
   122   CPPUNIT_ASSERT( npct.decimal_point() == *rl.decimal_point );
       
   123 
       
   124   float val = 1234.56f;
       
   125   ostringstream fostr;
       
   126   fostr.imbue(loc);
       
   127   fostr << val;
       
   128 
       
   129   string ref = "1";
       
   130   if (!npct.grouping().empty()) {
       
   131     ref += npct.thousands_sep();
       
   132   }
       
   133   ref += "234";
       
   134   ref += npct.decimal_point();
       
   135   ref += "56";
       
   136   //cout << "In " << loc.name() << " 1234.56 is written: " << fostr.str() << endl;
       
   137   CPPUNIT_ASSERT( fostr.str() == ref );
       
   138 
       
   139   val = 12345678.9f;
       
   140   ref = "1";
       
   141   ref += npct.decimal_point();
       
   142   ref += "23457e+07";
       
   143   fostr.str("");
       
   144   fostr << val;
       
   145   CPPUNIT_ASSERT( fostr.str() == ref );
       
   146 
       
   147   val = 1000000000.0f;
       
   148   fostr.str("");
       
   149   fostr << val;
       
   150   CPPUNIT_ASSERT( fostr.str() == "1e+09" );
       
   151 
       
   152   val = 1234.0f;
       
   153   ref = "1";
       
   154   if (!npct.grouping().empty()) {
       
   155     ref += npct.thousands_sep();
       
   156   }
       
   157   ref += "234";
       
   158   fostr.str("");
       
   159   fostr << val;
       
   160   CPPUNIT_ASSERT( fostr.str() == ref );
       
   161 
       
   162   val = 10000001.0f;
       
   163   fostr.str("");
       
   164   fostr << val;
       
   165   CPPUNIT_ASSERT( fostr.str() == "1e+07" );
       
   166 }
       
   167 
       
   168 void LocaleTest::_money_put_get( const locale& loc, const ref_locale& rl )
       
   169 {
       
   170   _money_put_get2(loc, loc, rl);
       
   171 }
       
   172 
       
   173 void LocaleTest::_money_put_get2( const locale& loc, const locale& streamLoc, const ref_locale& rl )
       
   174 {
       
   175   CPPUNIT_ASSERT( has_facet<money_put<char> >(loc) );
       
   176   money_put<char> const& fmp = use_facet<money_put<char> >(loc);
       
   177   CPPUNIT_ASSERT( has_facet<money_get<char> >(loc) );
       
   178   money_get<char> const& fmg = use_facet<money_get<char> >(loc);
       
   179 
       
   180   ostringstream ostr;
       
   181   ostr.imbue(streamLoc);
       
   182   ostr << showbase;
       
   183 
       
   184   //Check a positive value (international format)
       
   185   {
       
   186     string str_res;
       
   187     //money_put
       
   188     {
       
   189       CPPUNIT_ASSERT( (has_facet<moneypunct<char, true> >(loc)) );
       
   190       moneypunct<char, true> const& intl_fmp = use_facet<moneypunct<char, true> >(loc);
       
   191 
       
   192       ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, true, ostr, ' ', 123456);
       
   193 
       
   194       CPPUNIT_ASSERT( !res.failed() );
       
   195       str_res = ostr.str();
       
   196 
       
   197       size_t fieldIndex = 0;
       
   198       size_t index = 0;
       
   199 
       
   200       //On a positive value we skip the sign field if exists:
       
   201       if (intl_fmp.pos_format().field[fieldIndex] == money_base::sign) {
       
   202         ++fieldIndex;
       
   203       }
       
   204       // international currency abbreviation, if it is before value
       
   205 
       
   206       /*
       
   207        * int_curr_symbol
       
   208        *
       
   209        *   The international currency symbol. The operand is a four-character
       
   210        *   string, with the first three characters containing the alphabetic
       
   211        *   international currency symbol in accordance with those specified
       
   212        *   in the ISO 4217 specification. The fourth character is the character used
       
   213        *   to separate the international currency symbol from the monetary quantity.
       
   214        *
       
   215        * (http://www.opengroup.org/onlinepubs/7990989775/xbd/locale.html)
       
   216        */
       
   217       string::size_type p = strlen( rl.money_int_prefix );
       
   218       if (p != 0) {
       
   219         CPPUNIT_ASSERT( intl_fmp.pos_format().field[fieldIndex] == money_base::symbol );
       
   220         string::size_type p_old = strlen( rl.money_int_prefix_old );
       
   221         CPPUNIT_ASSERT( (str_res.substr(index, p) == rl.money_int_prefix) ||
       
   222                         ((p_old != 0) && (str_res.substr(index, p_old) ==  rl.money_int_prefix_old)) );
       
   223         if ( str_res.substr(index, p) == rl.money_int_prefix ) {
       
   224           index += p;
       
   225         } else {
       
   226           index += p_old;
       
   227         }
       
   228         ++fieldIndex;
       
   229       }
       
   230 
       
   231       // space after currency
       
   232       if (intl_fmp.pos_format().field[fieldIndex] == money_base::space ||
       
   233           intl_fmp.pos_format().field[fieldIndex] == money_base::none) {
       
   234         // iternational currency symobol has four chars, one of these chars
       
   235         // is separator, so if format has space on this place, it should
       
   236         // be skipped.
       
   237         ++fieldIndex;
       
   238       }
       
   239 
       
   240       // sign
       
   241       if (intl_fmp.pos_format().field[fieldIndex] == money_base::sign) {
       
   242         ++fieldIndex;
       
   243       }
       
   244 
       
   245       // value
       
   246       CPPUNIT_ASSERT( str_res[index++] == '1' );
       
   247       if (!intl_fmp.grouping().empty()) {
       
   248         CPPUNIT_ASSERT( str_res[index++] == /* intl_fmp.thousands_sep() */ *rl.money_thousands_sep );
       
   249       }
       
   250       CPPUNIT_ASSERT( str_res[index++] == '2' );
       
   251       CPPUNIT_ASSERT( str_res[index++] == '3' );
       
   252       CPPUNIT_ASSERT( str_res[index++] == '4' );
       
   253       if (intl_fmp.frac_digits() != 0) {
       
   254         CPPUNIT_ASSERT( str_res[index++] == /* intl_fmp.decimal_point() */ *rl.money_decimal_point );
       
   255       }
       
   256       CPPUNIT_ASSERT( str_res[index++] == '5' );
       
   257       CPPUNIT_ASSERT( str_res[index++] == '6' );
       
   258       ++fieldIndex;
       
   259 
       
   260       // sign
       
   261       if (intl_fmp.pos_format().field[fieldIndex] == money_base::sign) {
       
   262         ++fieldIndex;
       
   263       }
       
   264 
       
   265       // space
       
   266       if (intl_fmp.pos_format().field[fieldIndex] == money_base::space ) {
       
   267         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   268         ++fieldIndex;
       
   269       }
       
   270 
       
   271       // sign
       
   272       if (intl_fmp.pos_format().field[fieldIndex] == money_base::sign) {
       
   273         ++fieldIndex;
       
   274       }
       
   275 
       
   276       //as space cannot be last the only left format can be none:
       
   277       while ( fieldIndex < 3 ) {
       
   278         CPPUNIT_ASSERT( intl_fmp.pos_format().field[fieldIndex] == money_base::none );
       
   279         ++fieldIndex;
       
   280       }
       
   281     }
       
   282 
       
   283     //money_get
       
   284     {
       
   285       ios_base::iostate err = ios_base::goodbit;
       
   286       string digits;
       
   287 
       
   288       istringstream istr(str_res);
       
   289       ostr.str( "" );
       
   290       ostr.clear();
       
   291       fmg.get(istr, istreambuf_iterator<char, char_traits<char> >(), true, ostr, err, digits);
       
   292       CPPUNIT_ASSERT( (err & (ios_base::failbit | ios_base::badbit)) == 0 );
       
   293       CPPUNIT_ASSERT( digits == "123456" );
       
   294     }
       
   295   }
       
   296 
       
   297   ostr.str("");
       
   298   //Check a negative value (national format)
       
   299   {
       
   300     CPPUNIT_ASSERT( (has_facet<moneypunct<char, false> >(loc)) );
       
   301     moneypunct<char, false> const& dom_fmp = use_facet<moneypunct<char, false> >(loc);
       
   302     string str_res;
       
   303     //Check money_put
       
   304     {
       
   305       ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, false, ostr, ' ', -123456);
       
   306 
       
   307       CPPUNIT_ASSERT( !res.failed() );
       
   308       str_res = ostr.str();
       
   309 
       
   310       size_t fieldIndex = 0;
       
   311       size_t index = 0;
       
   312 
       
   313       if (dom_fmp.neg_format().field[fieldIndex] == money_base::sign) {
       
   314         CPPUNIT_ASSERT( str_res.substr(index, dom_fmp.negative_sign().size()) == dom_fmp.negative_sign() );
       
   315         index += dom_fmp.negative_sign().size();
       
   316         ++fieldIndex;
       
   317       }
       
   318 
       
   319       string::size_type p = strlen( rl.money_prefix );
       
   320       if (p != 0) {
       
   321         CPPUNIT_ASSERT( str_res.substr(index, p) == rl.money_prefix );
       
   322         index += p;
       
   323         ++fieldIndex;
       
   324       }
       
   325       if (dom_fmp.neg_format().field[fieldIndex] == money_base::space ||
       
   326           dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
       
   327         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   328         ++fieldIndex;
       
   329       }
       
   330 
       
   331       CPPUNIT_ASSERT( str_res[index++] == '1' );
       
   332       if (!dom_fmp.grouping().empty()) {
       
   333         CPPUNIT_ASSERT( str_res[index++] == dom_fmp.thousands_sep() );
       
   334       }
       
   335       CPPUNIT_ASSERT( str_res[index++] == '2' );
       
   336       CPPUNIT_ASSERT( str_res[index++] == '3' );
       
   337       CPPUNIT_ASSERT( str_res[index++] == '4' );
       
   338       if (dom_fmp.frac_digits() != 0) {
       
   339         CPPUNIT_ASSERT( str_res[index++] == dom_fmp.decimal_point() );
       
   340       }
       
   341       CPPUNIT_ASSERT( str_res[index++] == '5' );
       
   342       CPPUNIT_ASSERT( str_res[index++] == '6' );
       
   343       ++fieldIndex;
       
   344 
       
   345       //space cannot be last:
       
   346       if ((fieldIndex < 3) &&
       
   347           dom_fmp.neg_format().field[fieldIndex] == money_base::space) {
       
   348         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   349         ++fieldIndex;
       
   350       }
       
   351 
       
   352       if (fieldIndex == 3) {
       
   353         //If none is last we should not add anything to the resulting string:
       
   354         if (dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
       
   355           CPPUNIT_ASSERT( index == str_res.size() );
       
   356         } else {
       
   357           CPPUNIT_ASSERT( dom_fmp.neg_format().field[fieldIndex] == money_base::symbol );
       
   358           CPPUNIT_ASSERT( str_res.substr(index, strlen(rl.money_suffix)) == rl.money_suffix );
       
   359         }
       
   360       }
       
   361     }
       
   362 
       
   363     //money_get
       
   364     {
       
   365       ios_base::iostate err = ios_base::goodbit;
       
   366 #  if defined (STLPORT)
       
   367       _STLP_LONGEST_FLOAT_TYPE val;
       
   368 #  else
       
   369       long double val;
       
   370 #  endif
       
   371 
       
   372       istringstream istr(str_res);
       
   373       fmg.get(istr, istreambuf_iterator<char, char_traits<char> >(), false, ostr, err, val);
       
   374       CPPUNIT_ASSERT( (err & (ios_base::failbit | ios_base::badbit)) == 0 );
       
   375       if (dom_fmp.negative_sign().empty()) {
       
   376         //Without negative sign there is no way to guess the resulting amount sign ("C" locale):
       
   377         CPPUNIT_ASSERT( val == 123456 );
       
   378       }
       
   379       else {
       
   380         CPPUNIT_ASSERT( val == -123456 );
       
   381       }
       
   382     }
       
   383   }
       
   384   ostr.str("");
       
   385   //Check a negative value (national format)
       
   386   {
       
   387     CPPUNIT_ASSERT( (has_facet<moneypunct<char, false> >(loc)) );
       
   388     moneypunct<char, true> const& dom_fmp = use_facet<moneypunct<char, true> >(loc);
       
   389     string str_res;
       
   390     //Check money_put
       
   391     {
       
   392       ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, true, ostr, ' ', -123456);
       
   393 
       
   394       CPPUNIT_ASSERT( !res.failed() );
       
   395       str_res = ostr.str();
       
   396 
       
   397       size_t fieldIndex = 0;
       
   398       size_t index = 0;
       
   399 
       
   400       if (dom_fmp.neg_format().field[fieldIndex] == money_base::sign) {
       
   401         CPPUNIT_ASSERT( str_res.substr(index, dom_fmp.negative_sign().size()) == dom_fmp.negative_sign() );
       
   402         index += dom_fmp.negative_sign().size();
       
   403         ++fieldIndex;
       
   404       }
       
   405 
       
   406       string::size_type p = strlen( rl.money_prefix );
       
   407       if (p != 0) {
       
   408         CPPUNIT_ASSERT( str_res.substr(index, p) == rl.money_prefix );
       
   409         index += p;
       
   410         ++fieldIndex;
       
   411       }
       
   412       if (dom_fmp.neg_format().field[fieldIndex] == money_base::space ||
       
   413           dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
       
   414         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   415         ++fieldIndex;
       
   416       }
       
   417 
       
   418       CPPUNIT_ASSERT( str_res[index++] == '1' );
       
   419       if (!dom_fmp.grouping().empty()) {
       
   420         CPPUNIT_ASSERT( str_res[index++] == dom_fmp.thousands_sep() );
       
   421       }
       
   422       CPPUNIT_ASSERT( str_res[index++] == '2' );
       
   423       CPPUNIT_ASSERT( str_res[index++] == '3' );
       
   424       CPPUNIT_ASSERT( str_res[index++] == '4' );
       
   425       if (dom_fmp.frac_digits() != 0) {
       
   426         CPPUNIT_ASSERT( str_res[index++] == dom_fmp.decimal_point() );
       
   427       }
       
   428       CPPUNIT_ASSERT( str_res[index++] == '5' );
       
   429       CPPUNIT_ASSERT( str_res[index++] == '6' );
       
   430       ++fieldIndex;
       
   431 
       
   432       //space cannot be last:
       
   433       if ((fieldIndex < 3) &&
       
   434           dom_fmp.neg_format().field[fieldIndex] == money_base::space) {
       
   435         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   436         ++fieldIndex;
       
   437       }
       
   438 
       
   439       if (fieldIndex == 3) {
       
   440         //If none is last we should not add anything to the resulting string:
       
   441         if (dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
       
   442           CPPUNIT_ASSERT( index == str_res.size() );
       
   443         } else {
       
   444           CPPUNIT_ASSERT( dom_fmp.neg_format().field[fieldIndex] == money_base::symbol );
       
   445           CPPUNIT_ASSERT( str_res.substr(index, strlen(rl.money_suffix)) == rl.money_suffix );
       
   446         }
       
   447       }
       
   448     }
       
   449 
       
   450     //money_get
       
   451     {
       
   452       ios_base::iostate err = ios_base::goodbit;
       
   453 #  if defined (STLPORT)
       
   454       _STLP_LONGEST_FLOAT_TYPE val;
       
   455 #  else
       
   456       long double val;
       
   457 #  endif
       
   458 
       
   459       istringstream istr(str_res);
       
   460       fmg.get(istr, istreambuf_iterator<char, char_traits<char> >(), false, ostr, err, val);
       
   461       CPPUNIT_ASSERT( (err & (ios_base::failbit | ios_base::badbit)) == 0 );
       
   462       if (dom_fmp.negative_sign().empty()) {
       
   463         //Without negative sign there is no way to guess the resulting amount sign ("C" locale):
       
   464         CPPUNIT_ASSERT( val == 123456 );
       
   465       }
       
   466       else {
       
   467         CPPUNIT_ASSERT( val == -123456 );
       
   468       }
       
   469     }
       
   470   }
       
   471 }
       
   472 
       
   473 
       
   474 // Test for bug in case when number of digits in value less then number
       
   475 // of digits in fraction. I.e. '9' should be printed as '0.09',
       
   476 // if x.frac_digits() == 2.
       
   477 
       
   478 void LocaleTest::_money_put_X_bug( const locale& loc, const ref_locale& rl )
       
   479 {
       
   480   CPPUNIT_ASSERT( has_facet<money_put<char> >(loc) );
       
   481   money_put<char> const& fmp = use_facet<money_put<char> >(loc);
       
   482 
       
   483   ostringstream ostr;
       
   484   ostr.imbue(loc);
       
   485   ostr << showbase;
       
   486 
       
   487   // ostr.str("");
       
   488   // Check value with one decimal digit:
       
   489   {
       
   490     CPPUNIT_ASSERT( (has_facet<moneypunct<char, false> >(loc)) );
       
   491     moneypunct<char, false> const& dom_fmp = use_facet<moneypunct<char, false> >(loc);
       
   492     string str_res;
       
   493     // Check money_put
       
   494     {
       
   495       ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, false, ostr, ' ', 9);
       
   496 
       
   497       CPPUNIT_ASSERT( !res.failed() );
       
   498       str_res = ostr.str();
       
   499 
       
   500       size_t fieldIndex = 0;
       
   501       size_t index = 0;
       
   502 
       
   503       if (dom_fmp.pos_format().field[fieldIndex] == money_base::sign) {
       
   504         CPPUNIT_ASSERT( str_res.substr(index, dom_fmp.positive_sign().size()) == dom_fmp.positive_sign() );
       
   505         index += dom_fmp.positive_sign().size();
       
   506         ++fieldIndex;
       
   507       }
       
   508 
       
   509       string::size_type p = strlen( rl.money_prefix );
       
   510       if (p != 0) {
       
   511         CPPUNIT_ASSERT( str_res.substr(index, p) == rl.money_prefix );
       
   512         index += p;
       
   513         ++fieldIndex;
       
   514       }
       
   515       if (dom_fmp.neg_format().field[fieldIndex] == money_base::space ||
       
   516           dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
       
   517         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   518         ++fieldIndex;
       
   519       }
       
   520       if (dom_fmp.frac_digits() != 0) {
       
   521         CPPUNIT_ASSERT( str_res[index++] == '0' );
       
   522         CPPUNIT_ASSERT( str_res[index++] == dom_fmp.decimal_point() );
       
   523         for ( int fd = 1; fd < dom_fmp.frac_digits(); ++fd ) {
       
   524           CPPUNIT_ASSERT( str_res[index++] == '0' );
       
   525         }
       
   526       }
       
   527       CPPUNIT_ASSERT( str_res[index++] == '9' );
       
   528       ++fieldIndex;
       
   529 
       
   530       //space cannot be last:
       
   531       if ((fieldIndex < 3) &&
       
   532           dom_fmp.neg_format().field[fieldIndex] == money_base::space) {
       
   533         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   534         ++fieldIndex;
       
   535       }
       
   536 
       
   537       if (fieldIndex == 3) {
       
   538         //If none is last we should not add anything to the resulting string:
       
   539         if (dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
       
   540           CPPUNIT_ASSERT( index == str_res.size() );
       
   541         } else {
       
   542           CPPUNIT_ASSERT( dom_fmp.neg_format().field[fieldIndex] == money_base::symbol );
       
   543           CPPUNIT_ASSERT( str_res.substr(index, strlen(rl.money_suffix)) == rl.money_suffix );
       
   544         }
       
   545       }
       
   546     }
       
   547   }
       
   548 
       
   549   ostr.str("");
       
   550   // Check value with two decimal digit:
       
   551   {
       
   552     CPPUNIT_ASSERT( (has_facet<moneypunct<char, false> >(loc)) );
       
   553     moneypunct<char, false> const& dom_fmp = use_facet<moneypunct<char, false> >(loc);
       
   554     string str_res;
       
   555     // Check money_put
       
   556     {
       
   557       ostreambuf_iterator<char, char_traits<char> > res = fmp.put(ostr, false, ostr, ' ', 90);
       
   558 
       
   559       CPPUNIT_ASSERT( !res.failed() );
       
   560       str_res = ostr.str();
       
   561 
       
   562       size_t fieldIndex = 0;
       
   563       size_t index = 0;
       
   564 
       
   565       if (dom_fmp.pos_format().field[fieldIndex] == money_base::sign) {
       
   566         CPPUNIT_ASSERT( str_res.substr(index, dom_fmp.positive_sign().size()) == dom_fmp.positive_sign() );
       
   567         index += dom_fmp.positive_sign().size();
       
   568         ++fieldIndex;
       
   569       }
       
   570 
       
   571       string::size_type p = strlen( rl.money_prefix );
       
   572       if (p != 0) {
       
   573         CPPUNIT_ASSERT( str_res.substr(index, p) == rl.money_prefix );
       
   574         index += p;
       
   575         ++fieldIndex;
       
   576       }
       
   577       if (dom_fmp.neg_format().field[fieldIndex] == money_base::space ||
       
   578           dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
       
   579         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   580         ++fieldIndex;
       
   581       }
       
   582       if (dom_fmp.frac_digits() != 0) {
       
   583         CPPUNIT_ASSERT( str_res[index++] == '0' );
       
   584         CPPUNIT_ASSERT( str_res[index++] == dom_fmp.decimal_point() );
       
   585         for ( int fd = 1; fd < dom_fmp.frac_digits() - 1; ++fd ) {
       
   586           CPPUNIT_ASSERT( str_res[index++] == '0' );
       
   587         }
       
   588       }
       
   589       CPPUNIT_ASSERT( str_res[index++] == '9' );
       
   590       if (dom_fmp.frac_digits() != 0) {
       
   591         CPPUNIT_ASSERT( str_res[index++] == '0' );
       
   592       }
       
   593       ++fieldIndex;
       
   594 
       
   595       //space cannot be last:
       
   596       if ((fieldIndex < 3) &&
       
   597           dom_fmp.neg_format().field[fieldIndex] == money_base::space) {
       
   598         CPPUNIT_ASSERT( str_res[index++] == ' ' );
       
   599         ++fieldIndex;
       
   600       }
       
   601 
       
   602       if (fieldIndex == 3) {
       
   603         //If none is last we should not add anything to the resulting string:
       
   604         if (dom_fmp.neg_format().field[fieldIndex] == money_base::none) {
       
   605           CPPUNIT_ASSERT( index == str_res.size() );
       
   606         } else {
       
   607           CPPUNIT_ASSERT( dom_fmp.neg_format().field[fieldIndex] == money_base::symbol );
       
   608           CPPUNIT_ASSERT( str_res.substr(index, strlen(rl.money_suffix)) == rl.money_suffix );
       
   609         }
       
   610       }
       
   611     }
       
   612   }
       
   613 }
       
   614 
       
   615 void LocaleTest::_time_put_get( const locale& loc, const ref_locale&)
       
   616 {
       
   617   CPPUNIT_ASSERT( has_facet<time_put<char> >(loc) );
       
   618   const time_put<char>& tmp = use_facet<time_put<char> >(loc);
       
   619 
       
   620   struct tm xmas = { 0, 0, 12, 25, 11, 93 };
       
   621   ostringstream ostr;
       
   622   ostr.imbue(loc);
       
   623   string format = "%B %d %Y";
       
   624 
       
   625   time_put<char>::iter_type ret = tmp.put(ostr, ostr, ' ', &xmas, format.data(), format.data() + format.size());
       
   626   CPPUNIT_ASSERT( !ret.failed() );
       
   627 
       
   628   /*
       
   629    * In other words, user conformation is required for reliable parsing
       
   630    * of user-entered dates and times, but machine-generated formats can be
       
   631    * parsed reliably. This allows parsers to be aggressive about interpreting
       
   632    * user variations on standard format.
       
   633    *
       
   634    *                                             ISO/IEC 14882, 22.2.5.1
       
   635    */
       
   636   CPPUNIT_ASSERT( has_facet<time_get<char> >(loc) );
       
   637   const time_get<char>& tmg = use_facet<time_get<char> >(loc);
       
   638   basic_ios<char> io(0);
       
   639   io.imbue(loc);
       
   640 
       
   641   istringstream istr( ostr.str() );
       
   642   istreambuf_iterator<char, char_traits<char> > i( istr );
       
   643   istreambuf_iterator<char, char_traits<char> > e;
       
   644   ios_base::iostate err = ios_base::goodbit;
       
   645   struct tm other = { 15, 20, 9, 14, 7, 105 };
       
   646 
       
   647   i = tmg.get_monthname( i, e, io, err, &other );
       
   648   CPPUNIT_ASSERT( err == ios_base::goodbit );
       
   649   CPPUNIT_ASSERT( other.tm_mon == xmas.tm_mon );
       
   650 
       
   651   ++i; ++i; ++i; ++i; // skip day of month and spaces around it
       
   652   i = tmg.get_year( i, e, io, err, &other );
       
   653 
       
   654   CPPUNIT_ASSERT( err == ios_base::eofbit );
       
   655   CPPUNIT_ASSERT( other.tm_year == xmas.tm_year );
       
   656 
       
   657   ostringstream ostrX;
       
   658   ostrX.imbue(loc);
       
   659   format = "%x %X";
       
   660 
       
   661   ret = tmp.put(ostrX, ostrX, ' ', &xmas, format.data(), format.data() + format.size());
       
   662   CPPUNIT_ASSERT( !ret.failed() );
       
   663 
       
   664   istringstream istrX( ostrX.str() );
       
   665   istreambuf_iterator<char, char_traits<char> > j( istrX );
       
   666 
       
   667   err = ios_base::goodbit;
       
   668 
       
   669   struct tm yet_more = { 15, 20, 9, 14, 7, 105 };
       
   670 
       
   671   j = tmg.get_date( j, e, io, err, &yet_more );
       
   672 
       
   673   CPPUNIT_ASSERT( err == ios_base::goodbit );
       
   674 
       
   675   CPPUNIT_ASSERT( yet_more.tm_sec != xmas.tm_sec );
       
   676   CPPUNIT_ASSERT( yet_more.tm_min != xmas.tm_min );
       
   677   CPPUNIT_ASSERT( yet_more.tm_hour != xmas.tm_hour );
       
   678   CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday );
       
   679   CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon );
       
   680   CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year );
       
   681 
       
   682   ++j; // skip space
       
   683 
       
   684   j = tmg.get_time( j, e, io, err, &yet_more );
       
   685 
       
   686   CPPUNIT_ASSERT( err == ios_base::eofbit || err == ios_base::goodbit );
       
   687 
       
   688   CPPUNIT_ASSERT( yet_more.tm_sec == xmas.tm_sec );
       
   689   CPPUNIT_ASSERT( yet_more.tm_min == xmas.tm_min );
       
   690   CPPUNIT_ASSERT( yet_more.tm_hour == xmas.tm_hour );
       
   691   CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday );
       
   692   CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon );
       
   693   CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year );
       
   694 }
       
   695 
       
   696 void LocaleTest::_ctype_facet( const locale& loc, const ref_locale&)
       
   697 {
       
   698 #  if !(defined (__DMC__) && defined (_DLL))
       
   699   CPPUNIT_ASSERT( has_facet<ctype<char> >(loc) );
       
   700   ctype<char> const& ct = use_facet<ctype<char> >(loc);
       
   701 
       
   702   //is
       
   703   {
       
   704     CPPUNIT_ASSERT( ct.is(ctype_base::digit, '0') );
       
   705     CPPUNIT_ASSERT( ct.is(ctype_base::upper, 'A') );
       
   706     CPPUNIT_ASSERT( ct.is(ctype_base::lower, 'a') );
       
   707     CPPUNIT_ASSERT( ct.is(ctype_base::alpha, 'A') );
       
   708     CPPUNIT_ASSERT( ct.is(ctype_base::space, ' ') );
       
   709     CPPUNIT_ASSERT( !ct.is(ctype_base::space, '2') );
       
   710     CPPUNIT_ASSERT( ct.is(ctype_base::punct, '.') );
       
   711     CPPUNIT_ASSERT( ct.is(ctype_base::xdigit, 'a') );
       
   712   }
       
   713 
       
   714   //is range
       
   715   {
       
   716     char values[] = "0Aa .";
       
   717     ctype_base::mask res[sizeof(values)];
       
   718     ct.is(values, values + sizeof(values), res);
       
   719     // '0'
       
   720     CPPUNIT_ASSERT( (res[0] & ctype_base::print) != 0 );
       
   721     CPPUNIT_ASSERT( (res[0] & ctype_base::digit) != 0 );
       
   722     CPPUNIT_ASSERT( (res[0] & ctype_base::xdigit) != 0 );
       
   723     // 'A'
       
   724     CPPUNIT_ASSERT( (res[1] & ctype_base::print) != 0 );
       
   725     CPPUNIT_ASSERT( (res[1] & ctype_base::alpha) != 0 );
       
   726     CPPUNIT_ASSERT( (res[1] & ctype_base::xdigit) != 0 );
       
   727     CPPUNIT_ASSERT( (res[1] & ctype_base::upper) != 0 );
       
   728     // 'a'
       
   729     CPPUNIT_ASSERT( (res[2] & ctype_base::print) != 0 );
       
   730     CPPUNIT_ASSERT( (res[2] & ctype_base::alpha) != 0 );
       
   731     CPPUNIT_ASSERT( (res[2] & ctype_base::xdigit) != 0 );
       
   732     CPPUNIT_ASSERT( (res[2] & ctype_base::lower) != 0 );
       
   733     CPPUNIT_ASSERT( (res[2] & ctype_base::space) == 0 );
       
   734     // ' '
       
   735     CPPUNIT_ASSERT( (res[3] & ctype_base::print) != 0 );
       
   736     CPPUNIT_ASSERT( (res[3] & ctype_base::space) != 0 );
       
   737     CPPUNIT_ASSERT( (res[3] & ctype_base::digit) == 0 );
       
   738     // '.'
       
   739     CPPUNIT_ASSERT( (res[4] & ctype_base::print) != 0 );
       
   740     CPPUNIT_ASSERT( (res[4] & ctype_base::punct) != 0 );
       
   741     CPPUNIT_ASSERT( (res[4] & ctype_base::digit) == 0 );
       
   742   }
       
   743 
       
   744   //scan_is
       
   745   {
       
   746     char range[] = "abAc123 .";
       
   747     const char *rbeg = range;
       
   748     const char *rend = range + sizeof(range);
       
   749 
       
   750     const char *res;
       
   751     res = ct.scan_is((ctype_base::mask)(ctype_base::alpha | ctype_base::lower), rbeg, rend);
       
   752     CPPUNIT_ASSERT( res != rend );
       
   753     CPPUNIT_ASSERT( *res == 'a' );
       
   754 
       
   755     res = ct.scan_is(ctype_base::upper, rbeg, rend);
       
   756     CPPUNIT_ASSERT( res != rend );
       
   757     CPPUNIT_ASSERT( *res == 'A' );
       
   758 
       
   759     res = ct.scan_is(ctype_base::punct, rbeg, rend);
       
   760     CPPUNIT_ASSERT( res != rend );
       
   761     CPPUNIT_ASSERT( *res == '.' );
       
   762   }
       
   763 
       
   764   //scan_not
       
   765   {
       
   766     char range[] = "abAc123 .";
       
   767     const char *rbeg = range;
       
   768     const char *rend = range + sizeof(range);
       
   769 
       
   770     const char *res;
       
   771     res = ct.scan_not((ctype_base::mask)(ctype_base::alpha | ctype_base::lower), rbeg, rend);
       
   772     CPPUNIT_ASSERT( res != rend );
       
   773     CPPUNIT_ASSERT( *res == '1' );
       
   774 
       
   775     res = ct.scan_not(ctype_base::alpha, rbeg, rend);
       
   776     CPPUNIT_ASSERT( res != rend );
       
   777     CPPUNIT_ASSERT( *res == '1' );
       
   778 
       
   779     res = ct.scan_not(ctype_base::punct, rbeg, rend);
       
   780     CPPUNIT_ASSERT( res != rend );
       
   781     CPPUNIT_ASSERT( *res == 'a' );
       
   782   }
       
   783 
       
   784   //toupper
       
   785   {
       
   786     CPPUNIT_ASSERT( ct.toupper('a') == 'A' );
       
   787     CPPUNIT_ASSERT( ct.toupper('A') == 'A' );
       
   788     CPPUNIT_ASSERT( ct.toupper('1') == '1' );
       
   789   }
       
   790 
       
   791   //toupper range
       
   792   {
       
   793     char range[] = "abAc1";
       
   794     char expected_range[] = "ABAC1";
       
   795     ct.toupper(range, range + sizeof(range));
       
   796     CPPUNIT_ASSERT( equal(range, range + sizeof(range), expected_range) );
       
   797   }
       
   798 
       
   799   //tolower
       
   800   {
       
   801     CPPUNIT_ASSERT( ct.tolower('A') == 'a' );
       
   802     CPPUNIT_ASSERT( ct.tolower('a') == 'a' );
       
   803     CPPUNIT_ASSERT( ct.tolower('1') == '1' );
       
   804   }
       
   805 
       
   806   //tolower range
       
   807   {
       
   808     char range[] = "ABaC1";
       
   809     char expected_range[] = "abac1";
       
   810     ct.tolower(range, range + sizeof(range));
       
   811     CPPUNIT_ASSERT( equal(range, range + sizeof(range), expected_range) );
       
   812   }
       
   813 
       
   814   //widen
       
   815   {
       
   816     CPPUNIT_ASSERT( ct.widen('a') == 'a' );
       
   817   }
       
   818 
       
   819   //widen range
       
   820   {
       
   821     char range[] = "ABaC1";
       
   822     char res[sizeof(range)];
       
   823     ct.widen(range, range + sizeof(range), res);
       
   824     CPPUNIT_ASSERT( equal(range, range + sizeof(range), res) );
       
   825   }
       
   826 
       
   827   //narrow
       
   828   {
       
   829     CPPUNIT_ASSERT( ct.narrow('a', 'b') == 'a' );
       
   830   }
       
   831 
       
   832   //narrow range
       
   833   {
       
   834     char range[] = "ABaC1";
       
   835     char res[sizeof(range)];
       
   836     ct.narrow(range, range + sizeof(range), 'b', res);
       
   837     CPPUNIT_ASSERT( equal(range, range + sizeof(range), res) );
       
   838   }
       
   839 #  endif /* __DMC__ */
       
   840 }
       
   841 
       
   842 template <class _Tp>
       
   843 void test_supported_locale(LocaleTest inst, _Tp __test) {
       
   844   size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]);
       
   845   for (size_t i = 0; i < n; ++i) {
       
   846     auto_ptr<locale> loc;
       
   847 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
       
   848     try {
       
   849       loc.reset(new locale(tested_locales[i].name));
       
   850     }
       
   851     catch (runtime_error const&) {
       
   852       //This locale is not supported.
       
   853       continue;
       
   854     }
       
   855 #  else
       
   856     //Without exception support we only test C locale.
       
   857     if (tested_locales[i].name[0] != 'C' ||
       
   858         tested_locales[i].name[1] != 0)
       
   859       continue;
       
   860     loc.reset(new locale(tested_locales[i].name));
       
   861 #  endif
       
   862     CPPUNIT_MESSAGE( loc->name().c_str() );
       
   863     (inst.*__test)(*loc, tested_locales[i]);
       
   864   }
       
   865 }
       
   866 
       
   867 void LocaleTest::locale_by_name() {
       
   868 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
       
   869   /*
       
   870    * Check of the 22.1.1.2.7 standard point. Construction of a locale
       
   871    * instance from a null pointer or an unknown name should result in
       
   872    * a runtime_error exception.
       
   873    */
       
   874   try {
       
   875     locale loc(static_cast<char const*>(0));
       
   876     CPPUNIT_ASSERT( false );
       
   877   }
       
   878   catch (runtime_error const&) {
       
   879   }
       
   880   catch (...) {
       
   881     CPPUNIT_ASSERT( false );
       
   882   }
       
   883 
       
   884   try {
       
   885     locale loc("yasli_language");
       
   886     CPPUNIT_ASSERT( false );
       
   887   }
       
   888   catch (runtime_error const&) {
       
   889   }
       
   890   catch (...) {
       
   891     CPPUNIT_ASSERT( false );
       
   892   }
       
   893 #  endif
       
   894 }
       
   895 
       
   896 void LocaleTest::loc_has_facet() {
       
   897   locale loc("C");
       
   898   typedef numpunct<char> implemented_facet;
       
   899   CPPUNIT_ASSERT( has_facet<implemented_facet>(loc) );
       
   900   /*
       
   901   typedef num_put<char, back_insert_iterator<string> > not_implemented_facet;
       
   902   CPPUNIT_ASSERT( !has_facet<not_implemented_facet>(loc) );
       
   903   */
       
   904 }
       
   905 
       
   906 void LocaleTest::num_put_get()
       
   907 { test_supported_locale(*this, &LocaleTest::_num_put_get); }
       
   908 
       
   909 void LocaleTest::money_put_get()
       
   910 { test_supported_locale(*this, &LocaleTest::_money_put_get); }
       
   911 
       
   912 void LocaleTest::money_put_X_bug()
       
   913 { test_supported_locale(*this, &LocaleTest::_money_put_X_bug); }
       
   914 
       
   915 void LocaleTest::time_put_get()
       
   916 { test_supported_locale(*this, &LocaleTest::_time_put_get); }
       
   917 
       
   918 void LocaleTest::collate_facet()
       
   919 {
       
   920   {
       
   921     CPPUNIT_ASSERT( has_facet<collate<char> >(locale::classic()) );
       
   922     collate<char> const& col = use_facet<collate<char> >(locale::classic());
       
   923 
       
   924     char const str1[] = "abcdef1";
       
   925     char const str2[] = "abcdef2";
       
   926     const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
       
   927     const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
       
   928 
       
   929     CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
       
   930     CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
       
   931 
       
   932     //Smallest string should be before largest one:
       
   933     CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
       
   934     CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
       
   935   }
       
   936 
       
   937 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
       
   938   try {
       
   939     locale loc("fr_FR.ISO-8859-1");
       
   940     {
       
   941       CPPUNIT_ASSERT( has_facet<collate<char> >(loc) );
       
   942       collate<char> const& col = use_facet<collate<char> >(loc);
       
   943 
       
   944       char const str1[] = "abcdef1";
       
   945       char const str2[] = "abcdef2";
       
   946       const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
       
   947       const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
       
   948 
       
   949       CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
       
   950       CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
       
   951 
       
   952       //Smallest string should be before largest one:
       
   953       CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
       
   954       CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
       
   955     }
       
   956     {
       
   957       CPPUNIT_ASSERT( has_facet<collate<char> >(loc) );
       
   958       collate<char> const& col = use_facet<collate<char> >(loc);
       
   959 
       
   960       string strs[] = {"abdd", "abçd", "abbd", "abcd"};
       
   961 
       
   962       string transformed[4];
       
   963       for (size_t i = 0; i < 4; ++i) {
       
   964         transformed[i] = col.transform(strs[i].data(), strs[i].data() + strs[i].size());
       
   965       }
       
   966 
       
   967       sort(strs, strs + 4, loc);
       
   968       // c and ç are considered same when strxfrm() is done on the string
       
   969       CPPUNIT_ASSERT( strs[0] == "abbd" );
       
   970       CPPUNIT_ASSERT( strs[1] == "abçd" );
       
   971       CPPUNIT_ASSERT( strs[2] == "abcd" );
       
   972       CPPUNIT_ASSERT( strs[3] == "abdd" );
       
   973 
       
   974       sort(transformed, transformed + 4);
       
   975 
       
   976       CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + strs[0].size()) == transformed[0] );
       
   977       CPPUNIT_ASSERT( col.transform(strs[1].data(), strs[1].data() + strs[1].size()) == transformed[1] );
       
   978       CPPUNIT_ASSERT( col.transform(strs[2].data(), strs[2].data() + strs[2].size()) == transformed[2] );
       
   979       CPPUNIT_ASSERT( col.transform(strs[3].data(), strs[3].data() + strs[3].size()) == transformed[3] );
       
   980 
       
   981       // Check empty string result in empty key.
       
   982       CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data()).empty() );
       
   983 
       
   984       // Check that only characters that matter are taken into accout to build the key.
       
   985       CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + 2) == col.transform(strs[1].data(), strs[1].data() + 2) );
       
   986     }
       
   987 #    if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
       
   988     {
       
   989       CPPUNIT_ASSERT( has_facet<collate<wchar_t> >(loc) );
       
   990       collate<wchar_t> const& col = use_facet<collate<wchar_t> >(loc);
       
   991 
       
   992       wchar_t const str1[] = L"abcdef1";
       
   993       wchar_t const str2[] = L"abcdef2";
       
   994       const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
       
   995       const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
       
   996 
       
   997       CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
       
   998       CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
       
   999 
       
  1000       //Smallest string should be before largest one:
       
  1001       CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
       
  1002       CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
       
  1003     }
       
  1004     {
       
  1005       size_t i;
       
  1006       CPPUNIT_ASSERT( has_facet<collate<wchar_t> >(loc) );
       
  1007       collate<wchar_t> const& col = use_facet<collate<wchar_t> >(loc);
       
  1008 
       
  1009       // Here we would like to use L"abçd" but it looks like all compilers
       
  1010       // do not support storage of unicode characters in exe resulting in
       
  1011       // compilation error. We avoid this test for the moment.
       
  1012       wstring strs[] = {L"abdd", L"abcd", L"abbd", L"abcd"};
       
  1013 
       
  1014       wstring transformed[4];
       
  1015       for (i = 0; i < 4; ++i) {
       
  1016         transformed[i] = col.transform(strs[i].data(), strs[i].data() + strs[i].size());
       
  1017       }
       
  1018 
       
  1019       sort(strs, strs + 4, loc);
       
  1020       CPPUNIT_ASSERT( strs[0] == L"abbd" );
       
  1021       CPPUNIT_ASSERT( strs[1] == L"abcd" );
       
  1022       CPPUNIT_ASSERT( strs[2] == L"abcd" );
       
  1023       CPPUNIT_ASSERT( strs[3] == L"abdd" );
       
  1024 
       
  1025       sort(transformed, transformed + 4);
       
  1026 
       
  1027       CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + strs[0].size()) == transformed[0] );
       
  1028       CPPUNIT_ASSERT( col.transform(strs[1].data(), strs[1].data() + strs[1].size()) == transformed[1] );
       
  1029       CPPUNIT_ASSERT( col.transform(strs[2].data(), strs[2].data() + strs[2].size()) == transformed[2] );
       
  1030       CPPUNIT_ASSERT( col.transform(strs[3].data(), strs[3].data() + strs[3].size()) == transformed[3] );
       
  1031 
       
  1032       CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data()).empty() );
       
  1033 
       
  1034       CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + 2) == col.transform(strs[1].data(), strs[1].data() + 2) );
       
  1035     }
       
  1036 #    endif
       
  1037   }
       
  1038   catch (runtime_error const&) {
       
  1039     CPPUNIT_MESSAGE("No french locale to check collate facet");
       
  1040   }
       
  1041 #  endif
       
  1042 }
       
  1043 
       
  1044 void LocaleTest::ctype_facet()
       
  1045 { test_supported_locale(*this, &LocaleTest::_ctype_facet); }
       
  1046 
       
  1047 void LocaleTest::locale_init_problem() {
       
  1048 #  if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
       
  1049   test_supported_locale(*this, &LocaleTest::_locale_init_problem);
       
  1050 #  endif
       
  1051 }
       
  1052 
       
  1053 
       
  1054 /*
       
  1055  * Creation of a locale instance imply initialization of some STLport internal
       
  1056  * static objects first. We use a static instance of locale to check that this
       
  1057  * initialization is done correctly.
       
  1058  */
       
  1059 static locale global_loc;
       
  1060 static locale other_loc("");
       
  1061 
       
  1062 #  if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
       
  1063 void LocaleTest::_locale_init_problem( const locale& loc, const ref_locale&)
       
  1064 {
       
  1065 #    if !defined (__APPLE__) && !defined (__FreeBSD__) || \
       
  1066         !defined(__GNUC__) || ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__> 3)))
       
  1067   typedef codecvt<char,char,mbstate_t> my_facet;
       
  1068 #    else
       
  1069 // std::mbstate_t required for gcc 3.3.2 on FreeBSD...
       
  1070 // I am not sure what key here---FreeBSD or 3.3.2...
       
  1071 //      - ptr 2005-04-04
       
  1072   typedef codecvt<char,char,std::mbstate_t> my_facet;
       
  1073 #    endif
       
  1074 
       
  1075 #    if !(defined (__DMC__) && defined (_DLL))
       
  1076   locale loc_ref(global_loc);
       
  1077   {
       
  1078     locale gloc( loc_ref, new my_facet() );
       
  1079     CPPUNIT_ASSERT( has_facet<my_facet>( gloc ) );
       
  1080     //The following code is just here to try to confuse the reference counting underlying mecanism:
       
  1081     locale::global( locale::classic() );
       
  1082     locale::global( gloc );
       
  1083   }
       
  1084 
       
  1085 #      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
       
  1086   try {
       
  1087 #      endif
       
  1088     ostringstream os("test") ;
       
  1089     locale loc2( loc, new my_facet() );
       
  1090     CPPUNIT_ASSERT( has_facet<my_facet>( loc2 ) );
       
  1091     os.imbue( loc2 );
       
  1092 #      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
       
  1093   }
       
  1094   catch ( runtime_error& ) {
       
  1095     CPPUNIT_ASSERT( false );
       
  1096   }
       
  1097   catch ( ... ) {
       
  1098    CPPUNIT_ASSERT( false );
       
  1099   }
       
  1100 #      endif
       
  1101 
       
  1102 #      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
       
  1103   try {
       
  1104 #      endif
       
  1105     ostringstream os2("test2");
       
  1106 #      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
       
  1107   }
       
  1108   catch ( runtime_error& ) {
       
  1109     CPPUNIT_ASSERT( false );
       
  1110   }
       
  1111   catch ( ... ) {
       
  1112     CPPUNIT_ASSERT( false );
       
  1113   }
       
  1114 #      endif
       
  1115 #    endif /* __DMC__ */
       
  1116 }
       
  1117 #  endif
       
  1118 
       
  1119 void LocaleTest::default_locale()
       
  1120 {
       
  1121   locale loc( "" );
       
  1122 }
       
  1123 
       
  1124 void LocaleTest::facet_id()
       
  1125 {
       
  1126 #if defined (__SYMBIAN32__NO_STATIC_IMPORTS__) || defined (__SYMBIAN32__WSD__)
       
  1127 #  if defined (STLPORT)
       
  1128   locale::id _id_01 = collate<char>::GetFacetLocaleId();
       
  1129   CPPUNIT_CHECK( _id_01._M_index == 1 );
       
  1130 
       
  1131   locale::id _id_02 = ctype<char>::GetFacetLocaleId();
       
  1132   CPPUNIT_CHECK( _id_02._M_index == 2 );
       
  1133 
       
  1134 #    ifndef _STLP_NO_MBSTATE_T
       
  1135   locale::id _id_03 = codecvt<char, char, mbstate_t>::GetFacetLocaleId();
       
  1136   CPPUNIT_CHECK( _id_03._M_index == 3 );
       
  1137 #    endif
       
  1138 
       
  1139   locale::id _id_04 = moneypunct<char, true>::GetFacetLocaleId();
       
  1140   CPPUNIT_CHECK( _id_04._M_index == 4 );
       
  1141 
       
  1142   locale::id _id_05 = moneypunct<char, false>::GetFacetLocaleId();
       
  1143   CPPUNIT_CHECK( _id_05._M_index == 5 );
       
  1144 
       
  1145   locale::id _id_06 = numpunct<char>::GetFacetLocaleId();
       
  1146   CPPUNIT_CHECK( _id_06._M_index == 6 );
       
  1147 
       
  1148   locale::id _id_07 = messages<char>::GetFacetLocaleId();
       
  1149   CPPUNIT_CHECK( _id_07._M_index == 7 );
       
  1150 
       
  1151   locale::id _id_08 = money_get<char, istreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
       
  1152   CPPUNIT_CHECK( _id_08._M_index == 8 );
       
  1153 
       
  1154   /*
       
  1155   locale::id _id_09 = money_get<char, const char*>::id;
       
  1156   CPPUNIT_CHECK( _id_09._M_index == 9 );
       
  1157   */
       
  1158 
       
  1159   locale::id _id_10 = money_put<char, ostreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
       
  1160   CPPUNIT_CHECK( _id_10._M_index == 10 );
       
  1161 
       
  1162   /*
       
  1163   locale::id _id_11 = money_put<char, char*>::id;
       
  1164   CPPUNIT_CHECK( _id_11._M_index == 11 );
       
  1165   */
       
  1166 
       
  1167   locale::id _id_12 = num_get<char, istreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
       
  1168   CPPUNIT_CHECK( _id_12._M_index == 12 );
       
  1169 
       
  1170   /*
       
  1171   locale::id _id_13 = num_get<char, const char*>::id;
       
  1172   CPPUNIT_CHECK( _id_13._M_index == 13 );
       
  1173   */
       
  1174 
       
  1175   locale::id _id_14 = num_put<char, ostreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
       
  1176   CPPUNIT_CHECK( _id_14._M_index == 14 );
       
  1177 
       
  1178   /*
       
  1179   locale::id _id_15 = num_put<char, char*>::id;
       
  1180   CPPUNIT_CHECK( _id_15._M_index == 15 );
       
  1181   */
       
  1182 
       
  1183   locale::id _id_16 = time_get<char, istreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
       
  1184   CPPUNIT_CHECK( _id_16._M_index == 16 );
       
  1185 
       
  1186   /*
       
  1187   locale::id _id_17 = time_get<char, const char*>::id;
       
  1188   CPPUNIT_CHECK( _id_17._M_index == 17 );
       
  1189   */
       
  1190 
       
  1191   locale::id _id_18 = time_put<char, ostreambuf_iterator<char, char_traits<char> > >::GetFacetLocaleId();
       
  1192   CPPUNIT_CHECK( _id_18._M_index == 18 );
       
  1193 
       
  1194   /*
       
  1195   locale::id _id_19 = time_put<char, char*>::id;
       
  1196   CPPUNIT_CHECK( _id_19._M_index == 19 );
       
  1197   */
       
  1198 
       
  1199 #    ifndef _STLP_NO_WCHAR_T
       
  1200   locale::id _id_20 = collate<wchar_t>::GetFacetLocaleId();
       
  1201   CPPUNIT_CHECK( _id_20._M_index == 20 );
       
  1202 
       
  1203   locale::id _id_21 = ctype<wchar_t>::GetFacetLocaleId();
       
  1204   CPPUNIT_CHECK( _id_21._M_index == 21 );
       
  1205 
       
  1206 #      ifndef _STLP_NO_MBSTATE_T
       
  1207   locale::id _id_22 = codecvt<wchar_t, char, mbstate_t>::GetFacetLocaleId();
       
  1208   CPPUNIT_CHECK( _id_22._M_index == 22 );
       
  1209 #      endif
       
  1210   locale::id _id_23 = moneypunct<wchar_t, true>::GetFacetLocaleId();
       
  1211   CPPUNIT_CHECK( _id_23._M_index == 23 );
       
  1212 
       
  1213   locale::id _id_24 = moneypunct<wchar_t, false>::GetFacetLocaleId();
       
  1214   CPPUNIT_CHECK( _id_24._M_index == 24 );
       
  1215 
       
  1216   locale::id _id_25 = numpunct<wchar_t>::GetFacetLocaleId();
       
  1217   CPPUNIT_CHECK( _id_25._M_index == 25 );
       
  1218 
       
  1219   locale::id _id_26 = messages<wchar_t>::GetFacetLocaleId();
       
  1220   CPPUNIT_CHECK( _id_26._M_index == 26 );
       
  1221 
       
  1222   locale::id _id_27 = money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
       
  1223   CPPUNIT_CHECK( _id_27._M_index == 27 );
       
  1224 
       
  1225   /*
       
  1226   locale::id _id_28 = money_get<wchar_t, const wchar_t*>::id;
       
  1227   CPPUNIT_CHECK( _id_28._M_index == 28 );
       
  1228   */
       
  1229 
       
  1230   locale::id _id_29 = money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
       
  1231   CPPUNIT_CHECK( _id_29._M_index == 29 );
       
  1232 
       
  1233   /*
       
  1234   locale::id _id_30 = money_put<wchar_t, wchar_t*>::id;
       
  1235   CPPUNIT_CHECK( _id_30._M_index == 30 );
       
  1236   */
       
  1237 
       
  1238   locale::id _id_31 = num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
       
  1239   CPPUNIT_CHECK( _id_31._M_index == 31 );
       
  1240 
       
  1241   /*
       
  1242   locale::id _id_32 = num_get<wchar_t, const wchar_t*>::id;
       
  1243   CPPUNIT_CHECK( _id_32._M_index == 32 );
       
  1244   */
       
  1245 
       
  1246   locale::id _id_33 = num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > ::GetFacetLocaleId();
       
  1247   CPPUNIT_CHECK( _id_33._M_index == 33 );
       
  1248 
       
  1249   /*
       
  1250   locale::id _id_34 = num_put<wchar_t, wchar_t*>::id;
       
  1251   CPPUNIT_CHECK( _id_34._M_index == 34 );
       
  1252   */
       
  1253 
       
  1254   locale::id _id_35 = time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
       
  1255   CPPUNIT_CHECK( _id_35._M_index == 35 );
       
  1256 
       
  1257   /*
       
  1258   locale::id _id_36 = time_get<wchar_t, const wchar_t*>::id;
       
  1259   CPPUNIT_CHECK( _id_36._M_index == 36 );
       
  1260   */
       
  1261 
       
  1262   locale::id _id_37 = time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::GetFacetLocaleId();
       
  1263   CPPUNIT_CHECK( _id_37._M_index == 37 );
       
  1264 
       
  1265   /*
       
  1266   locale::id _id_38 = time_put<wchar_t, wchar_t*>::id;
       
  1267   CPPUNIT_CHECK( _id_38._M_index == 38 );
       
  1268   */
       
  1269 #    endif
       
  1270 #  endif
       
  1271 
       
  1272 #else
       
  1273 
       
  1274 #  if defined (STLPORT)
       
  1275   locale::id _id_01 = collate<char>::id;
       
  1276   CPPUNIT_CHECK( _id_01._M_index == 1 );
       
  1277 
       
  1278   locale::id _id_02 = ctype<char>::id;
       
  1279   CPPUNIT_CHECK( _id_02._M_index == 2 );
       
  1280 
       
  1281 #    ifndef _STLP_NO_MBSTATE_T
       
  1282   locale::id _id_03 = codecvt<char, char, mbstate_t>::id;
       
  1283   CPPUNIT_CHECK( _id_03._M_index == 3 );
       
  1284 #    endif
       
  1285 
       
  1286   locale::id _id_04 = moneypunct<char, true>::id;
       
  1287   CPPUNIT_CHECK( _id_04._M_index == 4 );
       
  1288 
       
  1289   locale::id _id_05 = moneypunct<char, false>::id;
       
  1290   CPPUNIT_CHECK( _id_05._M_index == 5 );
       
  1291 
       
  1292   locale::id _id_06 = numpunct<char>::id;
       
  1293   CPPUNIT_CHECK( _id_06._M_index == 6 );
       
  1294 
       
  1295   locale::id _id_07 = messages<char>::id;
       
  1296   CPPUNIT_CHECK( _id_07._M_index == 7 );
       
  1297 
       
  1298   locale::id _id_08 = money_get<char, istreambuf_iterator<char, char_traits<char> > >::id;
       
  1299   CPPUNIT_CHECK( _id_08._M_index == 8 );
       
  1300 
       
  1301   /*
       
  1302   locale::id _id_09 = money_get<char, const char*>::id;
       
  1303   CPPUNIT_CHECK( _id_09._M_index == 9 );
       
  1304   */
       
  1305 
       
  1306   locale::id _id_10 = money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
       
  1307   CPPUNIT_CHECK( _id_10._M_index == 10 );
       
  1308 
       
  1309   /*
       
  1310   locale::id _id_11 = money_put<char, char*>::id;
       
  1311   CPPUNIT_CHECK( _id_11._M_index == 11 );
       
  1312   */
       
  1313 
       
  1314   locale::id _id_12 = num_get<char, istreambuf_iterator<char, char_traits<char> > >::id;
       
  1315   CPPUNIT_CHECK( _id_12._M_index == 12 );
       
  1316 
       
  1317   /*
       
  1318   locale::id _id_13 = num_get<char, const char*>::id;
       
  1319   CPPUNIT_CHECK( _id_13._M_index == 13 );
       
  1320   */
       
  1321 
       
  1322   locale::id _id_14 = num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
       
  1323   CPPUNIT_CHECK( _id_14._M_index == 14 );
       
  1324 
       
  1325   /*
       
  1326   locale::id _id_15 = num_put<char, char*>::id;
       
  1327   CPPUNIT_CHECK( _id_15._M_index == 15 );
       
  1328   */
       
  1329 
       
  1330   locale::id _id_16 = time_get<char, istreambuf_iterator<char, char_traits<char> > >::id;
       
  1331   CPPUNIT_CHECK( _id_16._M_index == 16 );
       
  1332 
       
  1333   /*
       
  1334   locale::id _id_17 = time_get<char, const char*>::id;
       
  1335   CPPUNIT_CHECK( _id_17._M_index == 17 );
       
  1336   */
       
  1337 
       
  1338   locale::id _id_18 = time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
       
  1339   CPPUNIT_CHECK( _id_18._M_index == 18 );
       
  1340 
       
  1341   /*
       
  1342   locale::id _id_19 = time_put<char, char*>::id;
       
  1343   CPPUNIT_CHECK( _id_19._M_index == 19 );
       
  1344   */
       
  1345 
       
  1346 #    ifndef _STLP_NO_WCHAR_T
       
  1347   locale::id _id_20 = collate<wchar_t>::id;
       
  1348   CPPUNIT_CHECK( _id_20._M_index == 20 );
       
  1349 
       
  1350   locale::id _id_21 = ctype<wchar_t>::id;
       
  1351   CPPUNIT_CHECK( _id_21._M_index == 21 );
       
  1352 
       
  1353 #      ifndef _STLP_NO_MBSTATE_T
       
  1354   locale::id _id_22 = codecvt<wchar_t, char, mbstate_t>::id;
       
  1355   CPPUNIT_CHECK( _id_22._M_index == 22 );
       
  1356 #      endif
       
  1357   locale::id _id_23 = moneypunct<wchar_t, true>::id;
       
  1358   CPPUNIT_CHECK( _id_23._M_index == 23 );
       
  1359 
       
  1360   locale::id _id_24 = moneypunct<wchar_t, false>::id;
       
  1361   CPPUNIT_CHECK( _id_24._M_index == 24 );
       
  1362 
       
  1363   locale::id _id_25 = numpunct<wchar_t>::id;
       
  1364   CPPUNIT_CHECK( _id_25._M_index == 25 );
       
  1365 
       
  1366   locale::id _id_26 = messages<wchar_t>::id;
       
  1367   CPPUNIT_CHECK( _id_26._M_index == 26 );
       
  1368 
       
  1369   locale::id _id_27 = money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
       
  1370   CPPUNIT_CHECK( _id_27._M_index == 27 );
       
  1371 
       
  1372   /*
       
  1373   locale::id _id_28 = money_get<wchar_t, const wchar_t*>::id;
       
  1374   CPPUNIT_CHECK( _id_28._M_index == 28 );
       
  1375   */
       
  1376 
       
  1377   locale::id _id_29 = money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
       
  1378   CPPUNIT_CHECK( _id_29._M_index == 29 );
       
  1379 
       
  1380   /*
       
  1381   locale::id _id_30 = money_put<wchar_t, wchar_t*>::id;
       
  1382   CPPUNIT_CHECK( _id_30._M_index == 30 );
       
  1383   */
       
  1384 
       
  1385   locale::id _id_31 = num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
       
  1386   CPPUNIT_CHECK( _id_31._M_index == 31 );
       
  1387 
       
  1388   /*
       
  1389   locale::id _id_32 = num_get<wchar_t, const wchar_t*>::id;
       
  1390   CPPUNIT_CHECK( _id_32._M_index == 32 );
       
  1391   */
       
  1392 
       
  1393   locale::id _id_33 = num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > ::id;
       
  1394   CPPUNIT_CHECK( _id_33._M_index == 33 );
       
  1395 
       
  1396   /*
       
  1397   locale::id _id_34 = num_put<wchar_t, wchar_t*>::id;
       
  1398   CPPUNIT_CHECK( _id_34._M_index == 34 );
       
  1399   */
       
  1400 
       
  1401   locale::id _id_35 = time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
       
  1402   CPPUNIT_CHECK( _id_35._M_index == 35 );
       
  1403 
       
  1404   /*
       
  1405   locale::id _id_36 = time_get<wchar_t, const wchar_t*>::id;
       
  1406   CPPUNIT_CHECK( _id_36._M_index == 36 );
       
  1407   */
       
  1408 
       
  1409   locale::id _id_37 = time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
       
  1410   CPPUNIT_CHECK( _id_37._M_index == 37 );
       
  1411 
       
  1412   /*
       
  1413   locale::id _id_38 = time_put<wchar_t, wchar_t*>::id;
       
  1414   CPPUNIT_CHECK( _id_38._M_index == 38 );
       
  1415   */
       
  1416 #    endif
       
  1417 #  endif
       
  1418 #  endif //__WINSCW__
       
  1419 }
       
  1420 
       
  1421 void LocaleTest::combine()
       
  1422 {
       
  1423 #  if (!defined (STLPORT) || \
       
  1424        (defined (_STLP_USE_EXCEPTIONS) && !defined (_STLP_NO_MEMBER_TEMPLATES) && !defined (_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS)))
       
  1425   auto_ptr<locale> loc1, loc2;
       
  1426   size_t loc1_index = 0;
       
  1427   size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]);
       
  1428   for (size_t i = 0; i < n; ++i) {
       
  1429     try {
       
  1430       locale *ploc = new locale(tested_locales[i].name);
       
  1431       if (loc1.get() == 0)
       
  1432       {
       
  1433         loc1.reset(ploc);
       
  1434         loc1_index = i;
       
  1435         continue;
       
  1436       }
       
  1437       else
       
  1438       {
       
  1439         loc2.reset(ploc);
       
  1440       }
       
  1441 
       
  1442       //We can start the test
       
  1443       ostringstream ostr;
       
  1444       ostr << "combining '" << loc2->name() << "' money facets with '" << loc1->name() << "'";
       
  1445       CPPUNIT_MESSAGE( ostr.str().c_str() );
       
  1446 
       
  1447       //We are going to combine money facets as all formats are different.
       
  1448       {
       
  1449         //We check that resulting locale has correctly acquire loc2 facets.
       
  1450         locale loc = loc1->combine<moneypunct<char, true> >(*loc2);
       
  1451         loc = loc.combine<moneypunct<char, false> >(*loc2);
       
  1452         loc = loc.combine<money_put<char> >(*loc2);
       
  1453         loc = loc.combine<money_get<char> >(*loc2);
       
  1454 
       
  1455         //Check loc has the correct facets:
       
  1456         _money_put_get2(*loc2, loc, tested_locales[i]);
       
  1457 
       
  1458         //Check loc1 has not been impacted:
       
  1459         _money_put_get2(*loc1, *loc1, tested_locales[loc1_index]);
       
  1460 
       
  1461         //Check loc2 has not been impacted:
       
  1462         _money_put_get2(*loc2, *loc2, tested_locales[i]);
       
  1463       }
       
  1464       {
       
  1465         //We check that resulting locale has not wrongly acquire loc1 facets that hasn't been combine:
       
  1466         locale loc = loc2->combine<numpunct<char> >(*loc1);
       
  1467         loc = loc.combine<time_put<char> >(*loc1);
       
  1468         loc = loc.combine<time_get<char> >(*loc1);
       
  1469 
       
  1470         //Check loc has the correct facets:
       
  1471         _money_put_get2(*loc2, loc, tested_locales[i]);
       
  1472 
       
  1473         //Check loc1 has not been impacted:
       
  1474         _money_put_get2(*loc1, *loc1, tested_locales[loc1_index]);
       
  1475 
       
  1476         //Check loc2 has not been impacted:
       
  1477         _money_put_get2(*loc2, *loc2, tested_locales[i]);
       
  1478       }
       
  1479 
       
  1480       {
       
  1481         // Check auto combination do not result in weird reference counting behavior 
       
  1482         // (might generate a crash).
       
  1483         loc1->combine<numpunct<char> >(*loc1);
       
  1484       }
       
  1485 
       
  1486       loc1.reset(loc2.release());
       
  1487       loc1_index = i;
       
  1488     }
       
  1489     catch (runtime_error const&) {
       
  1490       //This locale is not supported.
       
  1491       continue;
       
  1492     }
       
  1493   }
       
  1494 #  endif
       
  1495 }
       
  1496 
       
  1497 #endif