===================================================================
@@ -51,8 +51,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const char* money_base::_S_atoms = "-0123456789";
- const char* __num_base::_S_atoms_in = "-+xX0123456789abcdefABCDEF";
- const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF";
+ const char* __num_base::_S_atoms_in = "-+xXpP0123456789abcdefABCDEF";
+ const char* __num_base::_S_atoms_out ="-+xXpP0123456789abcdef0123456789ABCDEF";
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// According to the resolution of DR 231, about 22.2.2.2.2, p11,
@@ -77,11 +77,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
if (__mod)
*__fptr++ = __mod;
ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
- // [22.2.2.2.2] Table 58
+ // n3225 [22.4.2.2.2] Table 88
if (__fltfield == ios_base::fixed)
*__fptr++ = 'f';
else if (__fltfield == ios_base::scientific)
*__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
+ else if (__fltfield == (ios_base::scientific | ios_base::fixed))
+ *__fptr++ = (__flags & ios_base::uppercase) ? 'A' : 'a';
else
*__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
*__fptr = '\0';
===================================================================
@@ -175,6 +175,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
// Next, look for leading zeros.
bool __found_mantissa = false;
+ bool __found_hex = false;
int __sep_pos = 0;
while (!__testeof)
{
@@ -195,6 +196,20 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
else
__testeof = true;
}
+ // If a float starts 0x then it is a hexadecimal floating const
+ // But we only do this if both fixed and scientific are set
+ else if (
+ (__c == __lit[__num_base::_S_ix] || __c == __lit[__num_base::_S_iX])
+ && (__sep_pos == 1))
+ {
+ __found_hex = true;
+ __xtrc += 'x';
+ if (++__beg != __end)
+ __c = *__beg;
+ else
+ __testeof = true;
+ break;
+ }
else
break;
}
@@ -206,13 +221,35 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
if (__lc->_M_use_grouping)
__found_grouping.reserve(32);
const char_type* __lit_zero = __lit + __num_base::_S_izero;
+ // So use the C local to decide them.
+ // Use __len rather than literal 10 in decoding the digits to account
+ // for hexadecimal digits. The exponent prefix is changed from e -> p
+ const char_type __expPrefixLower
+ = __lit[__found_hex
+ ? __num_base::_S_ip
+ : __num_base::_S_ie];
+ const char_type __expPrefixUpper
+ = __lit[__found_hex
+ ? __num_base::_S_iP
+ : __num_base::_S_iE];
+ size_t __len = (__found_hex
+ ? __num_base::_S_iend - __num_base::_S_izero
+ : 10);
- if (!__lc->_M_allocated)
+ // Hexadecimal floating point values are not subject to local
+ if ((__found_hex) || (!__lc->_M_allocated))
// "C" locale
while (!__testeof)
{
- const int __digit = _M_find(__lit_zero, 10, __c);
- if (__digit != -1)
+ const int __digit = _M_find(__lit_zero, __len, __c);
+ if (__digit >= 10)
+ {
+ // Decode Hex digits
+ int __offset = __digit >= 16 ? 16 : 10;
+ __xtrc += 'A' - __offset + __digit;
+ __found_mantissa = true;
+ }
+ else if (__digit != -1)
{
__xtrc += '0' + __digit;
__found_mantissa = true;
@@ -223,13 +260,15 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
__xtrc += '.';
__found_dec = true;
}
- else if ((__c == __lit[__num_base::_S_ie]
- || __c == __lit[__num_base::_S_iE])
+ else if ((__c == __expPrefixLower
+ || __c == __expPrefixUpper)
&& !__found_sci && __found_mantissa)
{
// Scientific notation.
- __xtrc += 'e';
+ __xtrc += __found_hex ? 'p' : 'e';
__found_sci = true;
+ // The digit sequence after the exponent symbols is always base 10
+ __len = 10;
// Remove optional plus or minus sign, if they exist.
if (++__beg != __end)
@@ -346,6 +385,12 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
__testeof = true;
}
+ // If this was a HEX coded float (see 6.4.4.2 of n1124)
+ // Then it is required to have the exponent part of the number
+ if ((__found_hex) && (!__found_sci))
+ {
+ __err = ios_base::failbit;
+ }
// Digit grouping is checked. If grouping and found_grouping don't
// match, then get very very upset, and set failbit.
if (__found_grouping.size())
===================================================================
@@ -1522,6 +1522,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_S_oplus,
_S_ox,
_S_oX,
+ _S_op,
+ _S_oP,
_S_odigits,
_S_odigits_end = _S_odigits + 16,
_S_oudigits = _S_odigits_end,
@@ -1548,10 +1550,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_S_iplus,
_S_ix,
_S_iX,
+ _S_ip,
+ _S_iP,
_S_izero,
_S_ie = _S_izero + 14,
_S_iE = _S_izero + 20,
- _S_iend = 26
+ _S_iend = 28
};
// num_put
===================================================================
@@ -21,6 +21,8 @@
#include <locale>
#include <sstream>
+#include <limits>
+#include <cfloat>
#include <testsuite_hooks.h>
// libstdc++/9548 and DR 231
@@ -29,11 +31,14 @@ void test01()
using namespace std;
bool test __attribute__((unused)) = true;
- wostringstream woss1, woss2;
+ wostringstream woss1, woss2, woss3;
+ wstringstream woss4;
const num_put<wchar_t>& np1 = use_facet<num_put<wchar_t> >(woss1.getloc());
const num_put<wchar_t>& np2 = use_facet<num_put<wchar_t> >(woss2.getloc());
+ const num_put<wchar_t>& np3 = use_facet<num_put<wchar_t> >(woss3.getloc());
+ const num_put<wchar_t>& np4 = use_facet<num_put<wchar_t> >(woss4.getloc());
- wstring result1, result2;
+ wstring result1, result2, result3;
woss1.precision(-1);
woss1.setf(ios_base::fixed, ios_base::floatfield);
@@ -46,6 +51,32 @@ void test01()
np2.put(woss2.rdbuf(), woss2, L'+', 1.0);
result2 = woss2.str();
VERIFY( result2 == L"1e+00" );
+
+ // If both ios_base::fixed | ios_base::scientific are set then
+ // The format specifier should be "%a" or "%A"
+ // See n3225 22.4.2.2.2 Table 88
+ woss3.precision(2);
+ woss3.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+ np3.put(woss3.rdbuf(), woss3, L'+', 0.001);
+ result3 = woss3.str();
+ VERIFY( result3 == L"0x1.06p-10" );
+
+ if ((FLT_RADIX == 2)||(FLT_RADIX == 4)||(FLT_RADIX == 8)||(FLT_RADIX == 16))
+ {
+ // if FLT_RADIX is a power of 2
+ // If the format specifier is "%a" or "%A" and no precision is specified
+ // the precision is sufficient for an exact representation.
+ // see n1124 7.24.2.1p8
+ double input = 0.0123456789 * 0.01;
+ double result;
+ woss4.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+ woss4.precision(std::numeric_limits<double>::digits/4 + 1);
+
+ np4.put(woss4.rdbuf(), woss4, L' ', input);
+
+ woss4 >> result;
+ VERIFY( input == result );
+ }
}
int main()
===================================================================
@@ -21,6 +21,8 @@
#include <locale>
#include <sstream>
+#include <limits>
+#include <cfloat>
#include <testsuite_hooks.h>
// libstdc++/9548 and DR 231
@@ -29,11 +31,14 @@ void test01()
using namespace std;
bool test __attribute__((unused)) = true;
- ostringstream oss1, oss2;
+ ostringstream oss1, oss2, oss3;
+ stringstream oss4;
const num_put<char>& np1 = use_facet<num_put<char> >(oss1.getloc());
const num_put<char>& np2 = use_facet<num_put<char> >(oss2.getloc());
+ const num_put<char>& np3 = use_facet<num_put<char> >(oss3.getloc());
+ const num_put<char>& np4 = use_facet<num_put<char> >(oss4.getloc());
- string result1, result2;
+ string result1, result2, result3;
oss1.precision(-1);
oss1.setf(ios_base::fixed, ios_base::floatfield);
@@ -46,6 +51,32 @@ void test01()
np2.put(oss2.rdbuf(), oss2, '+', 1.0);
result2 = oss2.str();
VERIFY( result2 == "1e+00" );
+
+ // If both ios_base::fixed | ios_base::scientific are set then
+ // The format specifier should be "%a" or "%A"
+ // See n3225 22.4.2.2.2 Table 88
+ oss3.precision(2);
+ oss3.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+ np3.put(oss3.rdbuf(), oss3, '+', 0.001);
+ result3 = oss3.str();
+ VERIFY( result3 == "0x1.06p-10" );
+
+ if ((FLT_RADIX == 2)||(FLT_RADIX == 4)||(FLT_RADIX == 8)||(FLT_RADIX == 16))
+ {
+ // if FLT_RADIX is a power of 2
+ // If the format specifier is "%a" or "%A" and no precision is specified
+ // the precision is sufficient for an exact representation.
+ // see n1124 7.24.2.1p8
+ double input = 0.0123456789 * 0.01;
+ double result;
+ oss4.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+ oss4.precision(std::numeric_limits<double>::digits/4 + 1);
+
+ np4.put(oss4.rdbuf(), oss4, ' ', input);
+
+ oss4 >> result;
+ VERIFY( input == result );
+ }
}
int main()
===================================================================
@@ -53,6 +53,7 @@ void test02()
const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(iss.getloc());
const ios_base::iostate goodbit = ios_base::goodbit;
const ios_base::iostate eofbit = ios_base::eofbit;
+ const ios_base::iostate failbit = ios_base::failbit;
ios_base::iostate err = ios_base::goodbit;
// C
@@ -108,6 +109,23 @@ void test02()
ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( d == d2 );
VERIFY( err == eofbit );
+
+ iss.str(L"0xAFp+123");
+ iss.clear();
+ iss.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( d == 0xAFp+123 );
+ VERIFY( err == eofbit );
+
+ iss.str(L"0xFF1p-23 ");
+ iss.clear();
+ iss.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( d == 0xFF1p-23 );
+ VERIFY( err == goodbit );
+
}
int main()
===================================================================
@@ -53,6 +53,7 @@ void test02()
const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
const ios_base::iostate goodbit = ios_base::goodbit;
const ios_base::iostate eofbit = ios_base::eofbit;
+ const ios_base::iostate failbit = ios_base::failbit;
ios_base::iostate err = ios_base::goodbit;
// C
@@ -108,6 +109,23 @@ void test02()
ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( d == d2 );
VERIFY( err == eofbit );
+
+ iss.str("0xAFp+123");
+ iss.clear();
+ iss.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( d == 0xAFp+123 );
+ VERIFY( err == eofbit );
+
+ iss.str("0xFF1p-23 ");
+ iss.clear();
+ iss.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( d == 0xFF1p-23 );
+ VERIFY( err == goodbit );
+
}
int main()