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