github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/cxx/ismpf.cc (about) 1 /* operator>> -- C++-style input of mpf_t. 2 3 Copyright 2001, 2003 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library. 6 7 The GNU MP Library is free software; you can redistribute it and/or modify 8 it under the terms of either: 9 10 * the GNU Lesser General Public License as published by the Free 11 Software Foundation; either version 3 of the License, or (at your 12 option) any later version. 13 14 or 15 16 * the GNU General Public License as published by the Free Software 17 Foundation; either version 2 of the License, or (at your option) any 18 later version. 19 20 or both in parallel, as here. 21 22 The GNU MP Library is distributed in the hope that it will be useful, but 23 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 24 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25 for more details. 26 27 You should have received copies of the GNU General Public License and the 28 GNU Lesser General Public License along with the GNU MP Library. If not, 29 see https://www.gnu.org/licenses/. */ 30 31 #include <cctype> 32 #include <iostream> 33 #include <string> 34 #include <clocale> // for localeconv 35 36 #include "gmp.h" 37 #include "gmp-impl.h" 38 39 using namespace std; 40 41 42 // For g++ libstdc++ parsing see num_get<chartype,initer>::_M_extract_float 43 // in include/bits/locale_facets.tcc. 44 // 45 // There are no plans to accept hex or octal floats, not unless the standard 46 // C++ library does so. Although such formats might be of use, it's 47 // considered more important to be compatible with what the normal 48 // operator>> does on "double"s etc. 49 50 istream & 51 operator>> (istream &i, mpf_ptr f) 52 { 53 int base; 54 char c = 0; 55 string s; 56 bool ok = false; 57 58 // C decimal point, as expected by mpf_set_str 59 const char *lconv_point = GMP_DECIMAL_POINT; 60 61 // C++ decimal point 62 #if HAVE_STD__LOCALE 63 const locale& loc = i.getloc(); 64 char point_char = use_facet< numpunct<char> >(loc).decimal_point(); 65 #else 66 const char *point = lconv_point; 67 char point_char = *point; 68 #endif 69 70 i.get(c); // start reading 71 72 if (i.flags() & ios::skipws) // skip initial whitespace 73 { 74 // C++ isspace 75 #if HAVE_STD__LOCALE 76 const ctype<char>& ct = use_facet< ctype<char> >(loc); 77 #define cxx_isspace(c) (ct.is(ctype_base::space,(c))) 78 #else 79 #define cxx_isspace(c) isspace(c) 80 #endif 81 82 while (cxx_isspace(c) && i.get(c)) 83 ; 84 } 85 86 if (c == '-' || c == '+') // sign 87 { 88 if (c == '-') 89 s = "-"; 90 i.get(c); 91 } 92 93 base = 10; 94 __gmp_istream_set_digits(s, i, c, ok, base); // read the number 95 96 // look for the C++ radix point, but put the C one in for mpf_set_str 97 if (c == point_char) 98 { 99 #if HAVE_STD__LOCALE 100 i.get(c); 101 #else // lconv point can be multi-char 102 for (;;) 103 { 104 i.get(c); 105 point++; 106 if (*point == '\0') 107 break; 108 if (c != *point) 109 goto fail; 110 } 111 #endif 112 s += lconv_point; 113 __gmp_istream_set_digits(s, i, c, ok, base); // read the mantissa 114 } 115 116 if (ok && (c == 'e' || c == 'E')) // exponent 117 { 118 s += c; 119 i.get(c); 120 ok = false; // exponent is mandatory 121 122 if (c == '-' || c == '+') // sign 123 { 124 s += c; 125 i.get(c); 126 } 127 128 __gmp_istream_set_digits(s, i, c, ok, base); // read the exponent 129 } 130 131 if (i.good()) // last character read was non-numeric 132 i.putback(c); 133 else if (i.eof() && ok) // stopped just before eof 134 i.clear(ios::eofbit); 135 136 if (ok) 137 ASSERT_NOCARRY (mpf_set_str(f, s.c_str(), base)); // extract the number 138 else 139 { 140 fail: 141 i.setstate(ios::failbit); // read failed 142 } 143 144 return i; 145 }