Index: include/istream =================================================================== --- include/istream +++ include/istream @@ -517,8 +517,9 @@ } template +_LIBCPP_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) +__input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n) { #ifndef _LIBCPP_NO_EXCEPTIONS try @@ -527,13 +528,10 @@ typename basic_istream<_CharT, _Traits>::sentry __sen(__is); if (__sen) { - streamsize __n = __is.width(); - if (__n <= 0) - __n = numeric_limits::max() / sizeof(_CharT) - 1; - streamsize __c = 0; + auto __s = __p; const ctype<_CharT>& __ct = use_facet >(__is.getloc()); ios_base::iostate __err = ios_base::goodbit; - while (__c < __n-1) + while (__s != __p + (__n-1)) { typename _Traits::int_type __i = __is.rdbuf()->sgetc(); if (_Traits::eq_int_type(__i, _Traits::eof())) @@ -545,12 +543,11 @@ if (__ct.is(__ct.space, __ch)) break; *__s++ = __ch; - ++__c; __is.rdbuf()->sbumpc(); } *__s = _CharT(); __is.width(0); - if (__c == 0) + if (__s == __p) __err |= ios_base::failbit; __is.setstate(__err); } @@ -564,6 +561,48 @@ return __is; } +#if _LIBCPP_STD_VER > 17 + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, _CharT (&__buf)[_Np]) +{ + auto __n = _Np; + if (__is.width() > 0) + __n = _VSTD::min(size_t(__is.width()), _Np); + return _VSTD::__input_c_string(__is, __buf, __n); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream& +operator>>(basic_istream& __is, unsigned char (&__buf)[_Np]) +{ + return __is >> (char(&)[_Np])__buf; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream& +operator>>(basic_istream& __is, signed char (&__buf)[_Np]) +{ + return __is >> (char(&)[_Np])__buf; +} + +#else + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) +{ + streamsize __n = __is.width(); + if (__n <= 0) + __n = numeric_limits::max() / sizeof(_CharT) - 1; + return _VSTD::__input_c_string(__is, __s, size_t(__n)); +} + template inline _LIBCPP_INLINE_VISIBILITY basic_istream& @@ -580,6 +619,8 @@ return __is >> (char*)__s; } +#endif // _LIBCPP_STD_VER > 17 + template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c) Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp =================================================================== --- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp +++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp @@ -61,6 +61,17 @@ assert(std::string((char*)s) == "abc"); assert(is.width() == 0); } +#if TEST_STD_VER > 17 + { + testbuf sb(" abcdefghijk "); + std::istream is(&sb); + signed char s[4]; + is >> s; + assert(!is.eof()); + assert(!is.fail()); + assert(std::string((char*)s) == "abc"); + } +#endif { testbuf sb(" abcdefghijk"); std::istream is(&sb); @@ -82,4 +93,15 @@ assert(std::string((char*)s) == ""); assert(is.width() == 0); } +#if TEST_STD_VER > 17 + { + testbuf sb(" abcdefghijk"); + std::istream is(&sb); + signed char s[1]; + is >> s; + assert(!is.eof()); + assert( is.fail()); + assert(std::string((char*)s) == ""); + } +#endif } Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp =================================================================== --- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp +++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp @@ -61,6 +61,17 @@ assert(std::string((char*)s) == "abc"); assert(is.width() == 0); } +#if TEST_STD_VER > 17 + { + testbuf sb(" abcdefghijk "); + std::istream is(&sb); + unsigned char s[4]; + is >> s; + assert(!is.eof()); + assert(!is.fail()); + assert(std::string((char*)s) == "abc"); + } +#endif { testbuf sb(" abcdefghijk"); std::istream is(&sb); @@ -82,4 +93,15 @@ assert(std::string((char*)s) == ""); assert(is.width() == 0); } +#if TEST_STD_VER > 17 + { + testbuf sb(" abcdefghijk"); + std::istream is(&sb); + unsigned char s[1]; + is >> s; + assert(!is.eof()); + assert( is.fail()); + assert(std::string((char*)s) == ""); + } +#endif } Index: test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp =================================================================== --- test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp +++ test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp @@ -50,6 +50,17 @@ assert(!is.fail()); assert(std::string(s) == "abcdefghijk"); } +#if TEST_STD_VER > 17 + { + testbuf sb(" abcdefghijk "); + std::istream is(&sb); + char s[4]; + is >> s; + assert(!is.eof()); + assert(!is.fail()); + assert(std::string(s) == "abc"); + } +#endif { testbuf sb(L" abcdefghijk "); std::wistream is(&sb); @@ -71,6 +82,17 @@ assert(std::wstring(s) == L"abcdefghijk"); assert(is.width() == 0); } +#if TEST_STD_VER > 17 + { + testbuf sb(L" abcdefghijk"); + std::wistream is(&sb); + wchar_t s[4]; + is >> s; + assert(!is.eof()); + assert(!is.fail()); + assert(std::wstring(s) == L"abc"); + } +#endif { testbuf sb(" abcdefghijk"); std::istream is(&sb); @@ -82,4 +104,15 @@ assert(std::string(s) == ""); assert(is.width() == 0); } +#if TEST_STD_VER > 17 + { + testbuf sb(" abcdefghijk"); + std::istream is(&sb); + char s[1]; + is >> s; + assert(!is.eof()); + assert( is.fail()); + assert(std::string(s) == ""); + } +#endif }