locale_facets.tcc (num_get::_M_extract_int, [...]): According to 22.2.2.1.2, p8-9...
authorPaolo Carlini <pcarlini@suse.de>
Fri, 19 Dec 2003 18:14:22 +0000 (18:14 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Fri, 19 Dec 2003 18:14:22 +0000 (18:14 +0000)
2003-12-19  Paolo Carlini  <pcarlini@suse.de>

* include/bits/locale_facets.tcc (num_get::_M_extract_int,
num_get::_M_extract_float): According to 22.2.2.1.2, p8-9,
first look for decimal_point and thousands_sep.
* testsuite/22_locale/num_get/get/char/11.cc: New.
* testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.

From-SVN: r74841

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc [new file with mode: 0644]

index 441ed54aa88d8c3a38f70110f67e5d44158b6e05..34bf9d61a739e7fc4d62b75e9d4bdcd2c068d37f 100644 (file)
@@ -1,3 +1,11 @@
+2003-12-19  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/locale_facets.tcc (num_get::_M_extract_int,
+       num_get::_M_extract_float): According to 22.2.2.1.2, p8-9,
+       first look for decimal_point and thousands_sep.
+       * testsuite/22_locale/num_get/get/char/11.cc: New.
+       * testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.
+
 2003-12-19  Paolo Carlini  <pcarlini@suse.de>
 
        * include/bits/locale_facets.tcc (num_get::_M_extract_float):
index 8f79d9e6959927e0c999a52c74bb8d542e139111..4dd3be11a3e43eed6193254c7e060ce4818859dc 100644 (file)
@@ -169,18 +169,22 @@ namespace std
       string __found_grouping;
       int __sep_pos = 0;
       bool __e;
+      const char_type* __p;
       while (__beg != __end)
         {
-         // Only look in digits.
+         // According to 22.2.2.1.2, p8-9, first look for decimal_point
+         // and thousands_sep.
          const char_type __c = *__beg;
-          const char_type* __p = __traits_type::find(__lit + _S_izero, 10, 
-                                                    __c);
-          if (__p)
+         if (__traits_type::eq(__c, __lc->_M_decimal_point) 
+             && !__found_dec && !__found_sci)
            {
-             // Try first for acceptable digit; record it if found.
-             __xtrc += _S_atoms_in[__p - __lit];
-             __found_mantissa = true;
-             ++__sep_pos;
+             // According to the standard, if no grouping chars are seen,
+             // no grouping check is applied. Therefore __found_grouping
+             // must be adjusted only if __dec comes after some __sep.
+             if (__found_grouping.size())
+               __found_grouping += static_cast<char>(__sep_pos);
+             __xtrc += '.';
+             __found_dec = true;
              ++__beg;
            }
           else if (__lc->_M_use_grouping
@@ -201,16 +205,11 @@ namespace std
                  break;
                }
             }
-         else if (__traits_type::eq(__c, __lc->_M_decimal_point) 
-                  && !__found_dec && !__found_sci)
+          else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
            {
-             // According to the standard, if no grouping chars are seen,
-             // no grouping check is applied. Therefore __found_grouping
-             // must be adjusted only if __dec comes after some __sep.
-             if (__found_grouping.size())
-               __found_grouping += static_cast<char>(__sep_pos);
-             __xtrc += '.';
-             __found_dec = true;
+             __xtrc += _S_atoms_in[__p - __lit];
+             __found_mantissa = true;
+             ++__sep_pos;
              ++__beg;
            }
          else if ((__e = __traits_type::eq(__c, __lit[_S_ie]) 
@@ -337,14 +336,34 @@ namespace std
        bool __overflow = false;
        _ValueT __result = 0;
        const char_type* __lit_zero = __lit + _S_izero;
+       const char_type* __p;
        if (__negative)
          {
            const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
            for (; __beg != __end; ++__beg)
              {
-               const char_type* __p = __traits_type::find(__lit_zero,
-                                                          __len, *__beg);
-               if (__p)
+               // According to 22.2.2.1.2, p8-9, first look for decimal_point
+               // and thousands_sep.
+               const char_type __c = *__beg;           
+               if (__traits_type::eq(__c, __lc->_M_decimal_point))
+                 break;
+               else if (__lc->_M_use_grouping
+                        && __traits_type::eq(__c, __lc->_M_thousands_sep))
+                 {
+                   // NB: Thousands separator at the beginning of a string
+                   // is a no-no, as is two consecutive thousands separators.
+                   if (__sep_pos)
+                     {
+                       __found_grouping += static_cast<char>(__sep_pos);
+                       __sep_pos = 0;
+                     }
+                   else
+                     {
+                       __err |= ios_base::failbit;
+                       break;
+                     }
+                 }
+               else if (__p = __traits_type::find(__lit_zero, __len, __c))
                  {
                    int __digit = __p - __lit_zero;
                    if (__digit > 15)
@@ -360,11 +379,22 @@ namespace std
                        __found_num = true;
                      }
                  }
+               else
+                 // Not a valid input item.
+                 break;
+             }
+         }
+       else
+         {
+           const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
+           for (; __beg != __end; ++__beg)
+             {
+               const char_type __c = *__beg;           
+               if (__traits_type::eq(__c, __lc->_M_decimal_point))
+                 break;
                else if (__lc->_M_use_grouping
-                        && __traits_type::eq(*__beg, __lc->_M_thousands_sep))
+                        && __traits_type::eq(__c, __lc->_M_thousands_sep))
                  {
-                   // NB: Thousands separator at the beginning of a string
-                   // is a no-no, as is two consecutive thousands separators.
                    if (__sep_pos)
                      {
                        __found_grouping += static_cast<char>(__sep_pos);
@@ -376,19 +406,7 @@ namespace std
                        break;
                      }
                  }
-               else
-                 // Not a valid input item.
-                 break;
-             }
-         }
-       else
-         {
-           const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
-           for (; __beg != __end; ++__beg)
-             {
-               const char_type* __p = __traits_type::find(__lit_zero,
-                                                          __len, *__beg);
-               if (__p)
+               else if (__p = __traits_type::find(__lit_zero, __len, __c))
                  {
                    int __digit = __p - __lit_zero;
                    if (__digit > 15)
@@ -404,20 +422,6 @@ namespace std
                        __found_num = true;
                      }
                  }
-               else if (__lc->_M_use_grouping
-                        && __traits_type::eq(*__beg, __lc->_M_thousands_sep))
-                 {
-                   if (__sep_pos)
-                     {
-                       __found_grouping += static_cast<char>(__sep_pos);
-                       __sep_pos = 0;
-                     }
-                   else
-                     {
-                       __err |= ios_base::failbit;
-                       break;
-                     }
-                 }
                else
                  break;
              }
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc
new file mode 100644 (file)
index 0000000..fde63c4
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2003 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.1.1  num_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct Punct: std::numpunct<char>
+{
+  std::string do_grouping() const { return "\1"; }
+  char do_thousands_sep() const { return '2'; }
+  char do_decimal_point() const { return '4'; }
+};
+
+void test01()
+{
+  using namespace std;
+  typedef istreambuf_iterator<char> iterator_type;
+  
+  bool test __attribute__((unused)) = true;
+
+  istringstream iss;
+  iss.imbue(locale(iss.getloc(), static_cast<numpunct<char>*>(new Punct)));
+  const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc()); 
+  ios_base::iostate err = ios_base::goodbit;
+  iterator_type end;
+  double d = 0.0;
+  double d1 = 13.0;
+  long l = 0l;
+  long l1 = 13l;
+  
+  iss.str("1234");
+  err = ios_base::goodbit;
+  end = ng.get(iss.rdbuf(), 0, iss, err, d);
+  VERIFY( err == ios_base::eofbit );
+  VERIFY( d == d1 );
+
+  iss.str("1234");
+  iss.clear();
+  err = ios_base::goodbit;
+  end = ng.get(iss.rdbuf(), 0, iss, err, l);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( l == l1 );
+}
+
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc
new file mode 100644 (file)
index 0000000..e438fbe
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2003 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.1.1  num_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct Punct: std::numpunct<wchar_t>
+{
+  std::string do_grouping() const { return "\1"; }
+  wchar_t do_thousands_sep() const { return L'2'; }
+  wchar_t do_decimal_point() const { return L'4'; }
+};
+
+void test01()
+{
+  using namespace std;
+  typedef istreambuf_iterator<wchar_t> iterator_type;
+  
+  bool test __attribute__((unused)) = true;
+
+  wistringstream iss;
+  iss.imbue(locale(iss.getloc(), static_cast<numpunct<wchar_t>*>(new Punct)));
+  const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(iss.getloc()); 
+  ios_base::iostate err = ios_base::goodbit;
+  iterator_type end;
+  double d = 0.0;
+  double d1 = 13.0;
+  long l = 0l;
+  long l1 = 13l;
+  
+  iss.str(L"1234");
+  err = ios_base::goodbit;
+  end = ng.get(iss.rdbuf(), 0, iss, err, d);
+  VERIFY( err == ios_base::eofbit );
+  VERIFY( d == d1 );
+
+  iss.str(L"1234");
+  iss.clear();
+  err = ios_base::goodbit;
+  end = ng.get(iss.rdbuf(), 0, iss, err, l);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( l == l1 );
+}
+
+
+int main()
+{
+  test01();
+  return 0;
+}