@@ -224,6 +224,7 @@ storage-class-specifier const error_category& iostream_category() noexcept;
224
224
#include < __system_error/error_code.h>
225
225
#include < __system_error/error_condition.h>
226
226
#include < __system_error/system_error.h>
227
+ #include < __type_traits/conditional.h>
227
228
#include < __utility/swap.h>
228
229
#include < __verbose_abort>
229
230
#include < version>
@@ -521,6 +522,31 @@ inline _LIBCPP_HIDE_FROM_ABI void ios_base::exceptions(iostate __iostate) {
521
522
clear (__rdstate_);
522
523
}
523
524
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
+
524
550
template <class _CharT , class _Traits >
525
551
class _LIBCPP_TEMPLATE_VIS basic_ios : public ios_base {
526
552
public:
@@ -590,7 +616,24 @@ protected:
590
616
591
617
private:
592
618
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_;
594
637
};
595
638
596
639
template <class _CharT , class _Traits >
@@ -605,7 +648,7 @@ template <class _CharT, class _Traits>
605
648
inline _LIBCPP_HIDE_FROM_ABI void basic_ios<_CharT, _Traits>::init(basic_streambuf<char_type, traits_type>* __sb) {
606
649
ios_base::init (__sb);
607
650
__tie_ = nullptr ;
608
- __fill_ = traits_type::eof ( );
651
+ __fill_ = widen ( ' ' );
609
652
}
610
653
611
654
template <class _CharT , class _Traits >
@@ -655,16 +698,16 @@ inline _LIBCPP_HIDE_FROM_ABI _CharT basic_ios<_CharT, _Traits>::widen(char __c)
655
698
656
699
template <class _CharT , class _Traits >
657
700
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 ( ))
659
702
__fill_ = widen (' ' );
660
- return __fill_;
703
+ return __fill_. __fill () ;
661
704
}
662
705
663
706
template <class _CharT , class _Traits >
664
707
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 ( ))
666
709
__fill_ = widen (' ' );
667
- char_type __r = __fill_;
710
+ char_type __r = __fill_. __fill () ;
668
711
__fill_ = __ch;
669
712
return __r;
670
713
}
0 commit comments