Home | History | Annotate | Line # | Download | only in cxx
t-locale.cc revision 1.1.1.1.8.1
      1          1.1  mrg /* Test locale support in C++ functions.
      2          1.1  mrg 
      3          1.1  mrg Copyright 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
      4          1.1  mrg 
      5  1.1.1.1.8.1  tls This file is part of the GNU MP Library test suite.
      6          1.1  mrg 
      7  1.1.1.1.8.1  tls The GNU MP Library test suite is free software; you can redistribute it
      8  1.1.1.1.8.1  tls and/or modify it under the terms of the GNU General Public License as
      9  1.1.1.1.8.1  tls published by the Free Software Foundation; either version 3 of the License,
     10  1.1.1.1.8.1  tls or (at your option) any later version.
     11  1.1.1.1.8.1  tls 
     12  1.1.1.1.8.1  tls The GNU MP Library test suite is distributed in the hope that it will be
     13  1.1.1.1.8.1  tls useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1.1.1.8.1  tls MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15  1.1.1.1.8.1  tls Public License for more details.
     16          1.1  mrg 
     17  1.1.1.1.8.1  tls You should have received a copy of the GNU General Public License along with
     18  1.1.1.1.8.1  tls the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
     19          1.1  mrg 
     20          1.1  mrg #include <clocale>
     21          1.1  mrg #include <iostream>
     22          1.1  mrg #include <cstdlib>
     23          1.1  mrg 
     24          1.1  mrg #include "gmp.h"
     25          1.1  mrg #include "gmp-impl.h"
     26          1.1  mrg #include "tests.h"
     27          1.1  mrg 
     28          1.1  mrg using namespace std;
     29          1.1  mrg 
     30          1.1  mrg 
     31          1.1  mrg extern "C" {
     32          1.1  mrg   char point_string[2];
     33          1.1  mrg }
     34          1.1  mrg 
     35          1.1  mrg #if HAVE_STD__LOCALE
     36          1.1  mrg // Like std::numpunct, but with decimal_point coming from point_string[].
     37          1.1  mrg class my_numpunct : public numpunct<char> {
     38          1.1  mrg  public:
     39          1.1  mrg   explicit my_numpunct (size_t r = 0) : numpunct<char>(r) { }
     40          1.1  mrg  protected:
     41          1.1  mrg   char do_decimal_point() const { return point_string[0]; }
     42          1.1  mrg };
     43          1.1  mrg #endif
     44          1.1  mrg 
     45          1.1  mrg void
     46          1.1  mrg set_point (char c)
     47          1.1  mrg {
     48          1.1  mrg   point_string[0] = c;
     49          1.1  mrg 
     50          1.1  mrg #if HAVE_STD__LOCALE
     51          1.1  mrg   locale loc (locale::classic(), new my_numpunct ());
     52          1.1  mrg   locale::global (loc);
     53          1.1  mrg #endif
     54          1.1  mrg }
     55          1.1  mrg 
     56          1.1  mrg 
     57          1.1  mrg void
     58          1.1  mrg check_input (void)
     59          1.1  mrg {
     60          1.1  mrg   static const struct {
     61          1.1  mrg     const char  *str1;
     62          1.1  mrg     const char  *str2;
     63          1.1  mrg     double      want;
     64          1.1  mrg   } data[] = {
     65          1.1  mrg 
     66          1.1  mrg     { "1","",   1.0 },
     67          1.1  mrg     { "1","0",  1.0 },
     68          1.1  mrg     { "1","00", 1.0 },
     69          1.1  mrg 
     70          1.1  mrg     { "","5",    0.5 },
     71          1.1  mrg     { "0","5",   0.5 },
     72          1.1  mrg     { "00","5",  0.5 },
     73          1.1  mrg     { "00","50", 0.5 },
     74          1.1  mrg 
     75          1.1  mrg     { "1","5",    1.5 },
     76          1.1  mrg     { "1","5e1", 15.0 },
     77          1.1  mrg   };
     78          1.1  mrg 
     79          1.1  mrg   static char point[] = {
     80          1.1  mrg     '.', ',', 'x', '\xFF'
     81          1.1  mrg   };
     82          1.1  mrg 
     83          1.1  mrg   mpf_t  got;
     84          1.1  mrg   mpf_init (got);
     85          1.1  mrg 
     86          1.1  mrg   for (size_t i = 0; i < numberof (point); i++)
     87          1.1  mrg     {
     88          1.1  mrg       set_point (point[i]);
     89          1.1  mrg 
     90          1.1  mrg       for (int neg = 0; neg <= 1; neg++)
     91          1.1  mrg         {
     92          1.1  mrg           for (size_t j = 0; j < numberof (data); j++)
     93          1.1  mrg             {
     94          1.1  mrg               string str = string(data[j].str1)+point[i]+string(data[j].str2);
     95          1.1  mrg               if (neg)
     96          1.1  mrg                 str = "-" + str;
     97          1.1  mrg 
     98          1.1  mrg               istringstream is (str.c_str());
     99          1.1  mrg 
    100          1.1  mrg               mpf_set_ui (got, 123);   // dummy initial value
    101          1.1  mrg 
    102          1.1  mrg               if (! (is >> got))
    103          1.1  mrg                 {
    104          1.1  mrg                   cout << "istream mpf_t operator>> error\n";
    105          1.1  mrg                   cout << "  point " << point[i] << "\n";
    106          1.1  mrg                   cout << "  str   \"" << str << "\"\n";
    107          1.1  mrg                   cout << "  localeconv point \""
    108          1.1  mrg                        << localeconv()->decimal_point << "\"\n";
    109          1.1  mrg                   abort ();
    110          1.1  mrg                 }
    111          1.1  mrg 
    112          1.1  mrg               double want = data[j].want;
    113          1.1  mrg               if (neg)
    114          1.1  mrg                 want = -want;
    115          1.1  mrg               if (mpf_cmp_d (got, want) != 0)
    116          1.1  mrg                 {
    117          1.1  mrg                   cout << "istream mpf_t operator>> wrong\n";
    118          1.1  mrg                   cout << "  point " << point[i] << "\n";
    119          1.1  mrg                   cout << "  str   \"" << str << "\"\n";
    120          1.1  mrg                   cout << "  got   " << got << "\n";
    121          1.1  mrg                   cout << "  want  " << want << "\n";
    122          1.1  mrg                   cout << "  localeconv point \""
    123          1.1  mrg                        << localeconv()->decimal_point << "\"\n";
    124          1.1  mrg                   abort ();
    125          1.1  mrg                 }
    126          1.1  mrg             }
    127          1.1  mrg         }
    128          1.1  mrg     }
    129          1.1  mrg 
    130          1.1  mrg   mpf_clear (got);
    131          1.1  mrg }
    132          1.1  mrg 
    133          1.1  mrg void
    134          1.1  mrg check_output (void)
    135          1.1  mrg {
    136          1.1  mrg   static char point[] = {
    137          1.1  mrg     '.', ',', 'x', '\xFF'
    138          1.1  mrg   };
    139          1.1  mrg 
    140          1.1  mrg   for (size_t i = 0; i < numberof (point); i++)
    141          1.1  mrg     {
    142          1.1  mrg       set_point (point[i]);
    143          1.1  mrg       ostringstream  got;
    144          1.1  mrg 
    145          1.1  mrg       mpf_t  f;
    146          1.1  mrg       mpf_init (f);
    147          1.1  mrg       mpf_set_d (f, 1.5);
    148          1.1  mrg       got << f;
    149          1.1  mrg       mpf_clear (f);
    150          1.1  mrg 
    151          1.1  mrg       string  want = string("1") + point[i] + string("5");
    152          1.1  mrg 
    153          1.1  mrg       if (want.compare (got.str()) != 0)
    154          1.1  mrg         {
    155          1.1  mrg           cout << "ostream mpf_t operator<< doesn't respect locale\n";
    156          1.1  mrg           cout << "  point " << point[i] << "\n";
    157          1.1  mrg           cout << "  got   \"" << got.str() << "\"\n";
    158          1.1  mrg           cout << "  want  \"" << want      << "\"\n";
    159          1.1  mrg           abort ();
    160          1.1  mrg         }
    161          1.1  mrg     }
    162          1.1  mrg }
    163          1.1  mrg 
    164          1.1  mrg int
    165          1.1  mrg replacement_works (void)
    166          1.1  mrg {
    167          1.1  mrg   set_point ('x');
    168          1.1  mrg   mpf_t  f;
    169          1.1  mrg   mpf_init (f);
    170          1.1  mrg   mpf_set_d (f, 1.5);
    171          1.1  mrg   ostringstream s;
    172          1.1  mrg   s << f;
    173          1.1  mrg   mpf_clear (f);
    174          1.1  mrg 
    175          1.1  mrg   return (s.str().compare("1x5") == 0);
    176          1.1  mrg }
    177          1.1  mrg 
    178          1.1  mrg int
    179          1.1  mrg main (void)
    180          1.1  mrg {
    181          1.1  mrg   tests_start ();
    182          1.1  mrg 
    183          1.1  mrg   if (replacement_works())
    184          1.1  mrg     {
    185          1.1  mrg       check_input ();
    186          1.1  mrg       check_output ();
    187          1.1  mrg     }
    188          1.1  mrg   else
    189          1.1  mrg     {
    190          1.1  mrg       cout << "Replacing decimal point didn't work, tests skipped\n";
    191          1.1  mrg     }
    192          1.1  mrg 
    193          1.1  mrg   tests_end ();
    194          1.1  mrg   return 0;
    195          1.1  mrg }
    196