Skip to content

Commit 0d63bb8

Browse files
committed
Changes for cases where wint_t and wchar_t have the same width. The changes are compatible with the current IBM provided libc++.
1 parent aecd376 commit 0d63bb8

File tree

2 files changed

+80
-6
lines changed

2 files changed

+80
-6
lines changed

libcxx/include/ios

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ storage-class-specifier const error_category& iostream_category() noexcept;
224224
#include <__system_error/error_code.h>
225225
#include <__system_error/error_condition.h>
226226
#include <__system_error/system_error.h>
227+
#include <__type_traits/conditional.h>
227228
#include <__utility/swap.h>
228229
#include <__verbose_abort>
229230
#include <version>
@@ -521,6 +522,31 @@ inline _LIBCPP_HIDE_FROM_ABI void ios_base::exceptions(iostate __iostate) {
521522
clear(__rdstate_);
522523
}
523524

525+
template <class _Traits>
526+
// Attribute 'packed' is used to keep the layout compatible with the previous
527+
// definition of '__set_' in basic_ios on AIX.
528+
struct _LIBCPP_PACKED _OptionalFill {
529+
_OptionalFill() : __set_(false) { }
530+
_OptionalFill& operator=(typename _Traits::int_type __x) { __set_ = true; __fill_val_ = __x; return *this; }
531+
bool __is_set() const { return __set_; }
532+
typename _Traits::int_type __fill() const { return __fill_val_; }
533+
534+
private:
535+
typename _Traits::int_type __fill_val_;
536+
bool __set_;
537+
};
538+
539+
template <class _Traits>
540+
struct _LIBCPP_PACKED _SentinelValueFill {
541+
_SentinelValueFill() : __fill_val_(_Traits::eof()) { }
542+
_SentinelValueFill& operator=(typename _Traits::int_type __x) { __fill_val_ = __x; return *this; }
543+
bool __is_set() const { return __fill_val_ != _Traits::eof(); }
544+
typename _Traits::int_type __fill() const { return __fill_val_; }
545+
546+
private:
547+
typename _Traits::int_type __fill_val_;
548+
};
549+
524550
template <class _CharT, class _Traits>
525551
class _LIBCPP_TEMPLATE_VIS basic_ios : public ios_base {
526552
public:
@@ -590,7 +616,24 @@ protected:
590616

591617
private:
592618
basic_ostream<char_type, traits_type>* __tie_;
593-
mutable int_type __fill_;
619+
620+
#if defined(_AIX) || (defined(__MVS__) && defined(__64BIT__))
621+
// AIX and 64-bit MVS must use _OptionalFill for ABI backward compatibility.
622+
using _FillType = _OptionalFill<_Traits>;
623+
#else
624+
#if defined(_WIN32)
625+
static const bool _OptOutForABICompat = true;
626+
#else
627+
static const bool _OptOutForABICompat = false;
628+
#endif
629+
630+
using _FillType = _If<
631+
sizeof(char_type) >= sizeof(int_type) && !_OptOutForABICompat,
632+
_OptionalFill<_Traits>,
633+
_SentinelValueFill<_Traits>
634+
>;
635+
#endif
636+
mutable _FillType __fill_;
594637
};
595638

596639
template <class _CharT, class _Traits>
@@ -605,7 +648,7 @@ template <class _CharT, class _Traits>
605648
inline _LIBCPP_HIDE_FROM_ABI void basic_ios<_CharT, _Traits>::init(basic_streambuf<char_type, traits_type>* __sb) {
606649
ios_base::init(__sb);
607650
__tie_ = nullptr;
608-
__fill_ = traits_type::eof();
651+
__fill_ = widen(' ');
609652
}
610653

611654
template <class _CharT, class _Traits>
@@ -655,16 +698,16 @@ inline _LIBCPP_HIDE_FROM_ABI _CharT basic_ios<_CharT, _Traits>::widen(char __c)
655698

656699
template <class _CharT, class _Traits>
657700
inline _LIBCPP_HIDE_FROM_ABI _CharT basic_ios<_CharT, _Traits>::fill() const {
658-
if (traits_type::eq_int_type(traits_type::eof(), __fill_))
701+
if (!__fill_.__is_set())
659702
__fill_ = widen(' ');
660-
return __fill_;
703+
return __fill_.__fill();
661704
}
662705

663706
template <class _CharT, class _Traits>
664707
inline _LIBCPP_HIDE_FROM_ABI _CharT basic_ios<_CharT, _Traits>::fill(char_type __ch) {
665-
if (traits_type::eq_int_type(traits_type::eof(), __fill_))
708+
if (!__fill_.__is_set())
666709
__fill_ = widen(' ');
667-
char_type __r = __fill_;
710+
char_type __r = __fill_.__fill();
668711
__fill_ = __ch;
669712
return __r;
670713
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// Test that weof as a wchar_t value can be set as the fill character.
10+
11+
// UNSUPPORTED: no-wide-characters
12+
// REQUIRES: target=powerpc{{(64)?}}-ibm-aix || target=s390x-ibm-zos
13+
14+
#include <iomanip>
15+
#include <ostream>
16+
#include <cassert>
17+
#include <string>
18+
19+
template <class CharT>
20+
struct testbuf : public std::basic_streambuf<CharT> {
21+
testbuf() {}
22+
};
23+
24+
int main(int, char**) {
25+
testbuf<wchar_t> sb;
26+
std::wostream os(&sb);
27+
os << std::setfill((wchar_t)std::char_traits<wchar_t>::eof());
28+
assert(os.fill() == (wchar_t)std::char_traits<wchar_t>::eof());
29+
30+
return 0;
31+
}

0 commit comments

Comments
 (0)