]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gmp/cxx/ismpf.cc
Imported gcc-4.4.3
[msp430-gcc.git] / gmp / cxx / ismpf.cc
diff --git a/gmp/cxx/ismpf.cc b/gmp/cxx/ismpf.cc
new file mode 100644 (file)
index 0000000..bfe4dc8
--- /dev/null
@@ -0,0 +1,134 @@
+/* operator>> -- C++-style input of mpf_t.
+
+Copyright 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MP 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 Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
+
+#include <cctype>
+#include <iostream>
+#include <string>
+#include <clocale>    // for localeconv
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+// For g++ libstdc++ parsing see num_get<chartype,initer>::_M_extract_float
+// in include/bits/locale_facets.tcc.
+//
+// There are no plans to accept hex or octal floats, not unless the standard
+// C++ library does so.  Although such formats might be of use, it's
+// considered more important to be compatible with what the normal
+// operator>> does on "double"s etc.
+
+istream &
+operator>> (istream &i, mpf_ptr f)
+{
+  int base;
+  char c = 0;
+  string s;
+  bool ok = false;
+
+  // C decimal point, as expected by mpf_set_str
+  const char *lconv_point = localeconv()->decimal_point;
+
+  // C++ decimal point
+#if HAVE_STD__LOCALE
+  const locale& loc = i.getloc();
+  char point_char = use_facet< numpunct<char> >(loc).decimal_point();
+#else
+  const char *point = lconv_point;
+  char point_char = *point;
+#endif
+
+  i.get(c); // start reading
+
+  if (i.flags() & ios::skipws) // skip initial whitespace
+    {
+      // C++ isspace
+#if HAVE_STD__LOCALE
+      const ctype<char>& ct = use_facet< ctype<char> >(loc);
+#define cxx_isspace(c)  (ct.is(ctype_base::space,(c)))
+#else
+#define cxx_isspace(c)  isspace(c)
+#endif
+
+      while (cxx_isspace(c) && i.get(c))
+        ;
+    }
+
+  if (c == '-' || c == '+') // sign
+    {
+      if (c == '-')
+       s = "-";
+      i.get(c);
+    }
+
+  base = 10;
+  __gmp_istream_set_digits(s, i, c, ok, base); // read the number
+
+  // look for the C++ radix point, but put the C one in for mpf_set_str
+  if (c == point_char)
+    {
+#if HAVE_STD__LOCALE
+      i.get(c);
+#else // lconv point can be multi-char
+      for (;;)
+        {
+          i.get(c);
+          point++;
+          if (*point == '\0')
+            break;
+          if (c != *point)
+            goto fail;
+        }
+#endif
+      s += lconv_point;
+      __gmp_istream_set_digits(s, i, c, ok, base); // read the mantissa
+    }
+
+  if (ok && (c == 'e' || c == 'E')) // exponent
+    {
+      s += c;
+      i.get(c);
+      ok = false; // exponent is mandatory
+
+      if (c == '-' || c == '+') // sign
+       {
+         s += c;
+         i.get(c);
+       }
+
+      __gmp_istream_set_digits(s, i, c, ok, base); // read the exponent
+    }
+
+  if (i.good()) // last character read was non-numeric
+    i.putback(c);
+  else if (i.eof() && ok) // stopped just before eof
+    i.clear();
+
+  if (ok)
+    ASSERT_NOCARRY (mpf_set_str(f, s.c_str(), base)); // extract the number
+  else
+    {
+    fail:
+      i.setstate(ios::failbit); // read failed
+    }
+
+  return i;
+}