diff --git a/libcxx/include/ios b/libcxx/include/ios --- a/libcxx/include/ios +++ b/libcxx/include/ios @@ -684,7 +684,28 @@ void set_rdbuf(basic_streambuf* __sb); private: basic_ostream* __tie_; + + template + struct _HasFillSet + { + static const bool value = false; + }; + + template <> + struct _HasFillSet + { +#if defined(_AIX) + static const bool value = true; +#elif defined(_WIN32) + static const bool value = false; +#else + static const bool value = + (WEOF >= (wint_t)WCHAR_MIN || WEOF <= (wint_t)WCHAR_MAX); +#endif + }; + static const bool __has_fill_set = _HasFillSet::value; mutable int_type __fill_; + mutable bool __fill_set_[__has_fill_set]; }; template @@ -706,7 +727,14 @@ { ios_base::init(__sb); __tie_ = nullptr; - __fill_ = traits_type::eof(); + if (__has_fill_set) + { + __fill_set_[0] = false; + } + else + { + __fill_ = traits_type::eof(); + } } template @@ -778,8 +806,18 @@ _CharT basic_ios<_CharT, _Traits>::fill() const { - if (traits_type::eq_int_type(traits_type::eof(), __fill_)) + if (__has_fill_set) + { + if (!__fill_set_[0]) + { + __fill_ = widen(' '); + __fill_set_[0] = true; + } + } + else if (traits_type::eq_int_type(traits_type::eof(), __fill_)) + { __fill_ = widen(' '); + } return __fill_; } @@ -788,9 +826,7 @@ _CharT basic_ios<_CharT, _Traits>::fill(char_type __ch) { - if (traits_type::eq_int_type(traits_type::eof(), __fill_)) - __fill_ = widen(' '); - char_type __r = __fill_; + char_type __r = fill(); __fill_ = __ch; return __r; } @@ -805,6 +841,10 @@ ios_base::copyfmt(__rhs); __tie_ = __rhs.__tie_; __fill_ = __rhs.__fill_; + if (__has_fill_set) + { + __fill_set_[0] = __rhs.__fill_set_[0]; + } __call_callbacks(copyfmt_event); exceptions(__rhs.exceptions()); } @@ -820,6 +860,10 @@ __tie_ = __rhs.__tie_; __rhs.__tie_ = nullptr; __fill_ = __rhs.__fill_; + if (__has_fill_set) + { + __fill_set_[0] = __rhs.__fill_set_[0]; + } } template @@ -830,6 +874,10 @@ ios_base::swap(__rhs); _VSTD::swap(__tie_, __rhs.__tie_); _VSTD::swap(__fill_, __rhs.__fill_); + if (__has_fill_set) + { + _VSTD::swap(__fill_set_[0], __rhs.__fill_set_[0]); + } } template diff --git a/libcxx/test/std/input.output/iostream.format/std.manip/setfill_wcharmax.pass.cpp b/libcxx/test/std/input.output/iostream.format/std.manip/setfill_wcharmax.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/iostream.format/std.manip/setfill_wcharmax.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: no-wide-characters + +// XFAIL: stdlib=libc++ && target=aarch64-linux-gnu +// XFAIL: stdlib=libc++ && target=armv7l-linux-gnueabihf +// XFAIL: stdlib=libc++ && target=armv8l-linux-gnueabihf +// XFAIL: stdlib=libc++ && target=x86_64-pc-windows-msvc +// XFAIL: stdlib=libc++ && target=x86_64-w64-windows-gnu + +// + +// template unspecified setfill(charT c); + +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct testbuf + : public std::basic_streambuf +{ + testbuf() {} +}; + +int main(int, char**) +{ + testbuf sb; + std::wostream os(&sb); + os << std::setfill(std::numeric_limits::max()); + assert(os.fill() == std::numeric_limits::max()); + + return 0; +}