diff --git a/libcxx/include/__locale_dir/num.h b/libcxx/include/__locale_dir/num.h index 98b8eb0c600f5..b7ea02e7cb7f7 100644 --- a/libcxx/include/__locale_dir/num.h +++ b/libcxx/include/__locale_dir/num.h @@ -436,6 +436,7 @@ class num_get : public locale::facet, private __num_get<_CharT> { ++__first; if (__first == __last) { __err |= ios_base::eofbit; + __v = 0; return __first; } // __c2 == 'x' || __c2 == 'X' @@ -444,6 +445,7 @@ class num_get : public locale::facet, private __num_get<_CharT> { ++__first; } else { __base = 8; + __parsed_num = true; // We only swallowed '0', so we've started to parse a number } } else { __base = 10; diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp index a110aae2db11b..45b034833fecc 100644 --- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp @@ -670,5 +670,101 @@ int main(int, char**) assert(v == std::numeric_limits::min()); } + { // Check that auto-detection of the base works properly + ios.flags(ios.flags() & ~std::ios::basefield); + { // zeroes + { + v = -1; + const char str[] = "0"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator iter = + f.get(cpp17_input_iterator(str), cpp17_input_iterator(str + 1), ios, err, v); + assert(base(iter) == str + 1); + assert(err == ios.eofbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "00"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator iter = + f.get(cpp17_input_iterator(str), cpp17_input_iterator(str + 2), ios, err, v); + assert(base(iter) == str + 2); + assert(err == ios.eofbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "0x0"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator iter = + f.get(cpp17_input_iterator(str), cpp17_input_iterator(str + 3), ios, err, v); + assert(base(iter) == str + 3); + assert(err == ios.eofbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "0X0"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator iter = + f.get(cpp17_input_iterator(str), cpp17_input_iterator(str + 3), ios, err, v); + assert(base(iter) == str + 3); + assert(err == ios.eofbit); + assert(v == 0); + } + } + { // first character after base is out of range + { + v = -1; + const char str[] = "08"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator iter = + f.get(cpp17_input_iterator(str), cpp17_input_iterator(str + 2), ios, err, v); + assert(base(iter) == str + 1); + assert(err == ios.goodbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "1a"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator iter = + f.get(cpp17_input_iterator(str), cpp17_input_iterator(str + 2), ios, err, v); + assert(base(iter) == str + 1); + assert(err == ios.goodbit); + assert(v == 1); + } + { + v = -1; + const char str[] = "0xg"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator iter = + f.get(cpp17_input_iterator(str), cpp17_input_iterator(str + 3), ios, err, v); + assert(base(iter) == str + 2); + assert(err == ios.failbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "0Xg"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator iter = + f.get(cpp17_input_iterator(str), cpp17_input_iterator(str + 3), ios, err, v); + assert(base(iter) == str + 2); + assert(err == ios.failbit); + assert(v == 0); + } + } + } + return 0; }