Index: include/locale =================================================================== --- include/locale +++ include/locale @@ -505,9 +505,17 @@ return -1; } if (__x == 'x' || __x == 'X') - __exp = 'P'; + { + unsigned __sign = (*__a == '-') + (*__a == '+'); + if (__a_end == __a + __sign + 1 && __a[__sign] == '0') + __exp = 'P'; + else + return -1; + } else if ((__x & 0x5F) == __exp) { + if (__exp & 0x80) + return -1; __exp |= 0x80; if (__in_units) { @@ -516,6 +524,48 @@ *__g_end++ = __dc; } } + else if (__f > 9) + { + if (__x == 'P' || __x == 'p') + return -1; + unsigned __sign = (*__a == '-') + (*__a == '+'); + if (__x == 'I' || __x == 'i') + { + if (__a_end != __a + __sign) // start of Inf + return -1; + } + else if (__x == 'N' || __x == 'n') + { + bool __ok = + __a_end == __a // start of NaN + || + (__a_end == __a + 2 && // end of NaN + (__a[0] & 0x5F) == 'N' && + (__a[1] & 0x5F) == 'A') + || + (__a_end == __a + __sign + 1 && // middle of Inf + (__a[__sign] & 0x5F) == 'I'); + if (!__ok) + return -1; + } + else + { + // Only hex remains. + bool __ok = + __exp == 'P' // in a hex mantissa + || + ((__x == 'A' || __x == 'a') && // middle of NaN + __a_end == __a + 1 && + (__a[0] & 0x5F) == 'N') + || + ((__x == 'F' || __x == 'f') && // end of Inf + __a_end == __a + __sign + 2 && + (__a[__sign ] & 0x5F) == 'I' && + (__a[__sign+1] & 0x5F) == 'N'); + if (!__ok) + return -1; + } + } *__a_end++ = __x; if (__f >= 22) return 0; Index: test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp =================================================================== --- test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp +++ test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp @@ -208,6 +208,19 @@ assert(v == 2); } { + // http://cplusplus.github.io/LWG/lwg-active.html#2381 + v = -1; + const char str[] = "0x1a.bp+07p"; + std::ios_base::iostate err = ios.goodbit; + input_iterator iter = + f.get(input_iterator(str), + input_iterator(str+sizeof(str)), + ios, err, v); + assert(err == ios.goodbit); + assert(iter.base() == str+sizeof(str)-2); + assert(v == 0x1a.bp+07); + } + { v = -1; const char str[] = "1.79779e+309"; // unrepresentable std::ios_base::iostate err = ios.goodbit;