@@ -66,24 +66,87 @@ public:
66
66
const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode = ios_base::in | ios_base::out)
67
67
: basic_stringbuf(_Str, _Mode, _Alloc{}) {}
68
68
69
- basic_stringbuf(basic_stringbuf&& _Right, const _Alloc& _Al_) : _Mystate(0), _Al(_Al_) {
70
- _Assign_rv(_STD move(_Right));
69
+ basic_stringbuf(basic_stringbuf&& _Right, const _Alloc& _Al_) : _Seekhigh(nullptr), _Mystate(0), _Al(_Al_) {
70
+ if constexpr (!allocator_traits<_Alloc>::is_always_equal::value) {
71
+ if (_Al != _Right._Al) {
72
+ _Copy_into_self_and_tidy(_STD move(_Right));
73
+ return;
74
+ }
75
+ }
76
+
77
+ _Take_contents(_STD move(_Right));
71
78
}
72
79
#endif // _HAS_CXX20
73
80
74
- basic_stringbuf(basic_stringbuf&& _Right) : _Mystate(0) {
75
- _Assign_rv(_STD move(_Right));
81
+ basic_stringbuf(basic_stringbuf&& _Right)
82
+ : _Seekhigh(_STD exchange(_Right._Seekhigh, nullptr)), _Mystate(_STD exchange(_Right._Mystate, 0)),
83
+ _Al(_Right._Al) {
84
+ _Mysb::swap(_Right);
76
85
}
77
86
78
- basic_stringbuf& operator=(basic_stringbuf&& _Right) noexcept /* strengthened */ {
79
- _Assign_rv(_STD move(_Right));
87
+ basic_stringbuf& operator=(basic_stringbuf&& _Right) noexcept(
88
+ _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) /* strengthened */ {
89
+ if (this != _STD addressof(_Right)) {
90
+ _Assign_rv_no_alias(_STD move(_Right));
91
+ }
80
92
return *this;
81
93
}
82
94
83
- void _Assign_rv(basic_stringbuf&& _Right) noexcept {
84
- if (this != _STD addressof(_Right)) {
85
- _Tidy();
86
- this->swap(_Right);
95
+ void _Take_contents(basic_stringbuf&& _Right) noexcept {
96
+ // pre: *this holds no dynamic buffer and _Al == _Right._Al
97
+ _Seekhigh = _STD exchange(_Right._Seekhigh, nullptr);
98
+ _Mystate = _STD exchange(_Right._Mystate, 0);
99
+ _Mysb::swap(_Right);
100
+ }
101
+
102
+ void _Copy_into_self_and_tidy(basic_stringbuf&& _Right) {
103
+ // pre: *this holds no dynamic buffer and _Al != _Right._Al
104
+ if ((_Right._Mystate & _Allocated) == 0) {
105
+ return;
106
+ }
107
+
108
+ const auto _Right_data = _Right._Mysb::eback();
109
+ const auto _Right_capacity = static_cast<typename allocator_traits<_Alloc>::size_type>(
110
+ (_Right._Mysb::pptr() ? _Right._Mysb::epptr() : _Right._Mysb::egptr()) - _Right_data);
111
+
112
+ auto _New_capacity = _Right_capacity;
113
+ const auto _New_data = _STD _Unfancy(_STD _Allocate_at_least_helper(_Al, _New_capacity));
114
+
115
+ _Mysb::setg(_New_data, _New_data + (_Right._Mysb::gptr() - _Right_data),
116
+ _New_data + (_Right._Mysb::egptr() - _Right_data));
117
+ if (_Right._Mysb::pbase() != nullptr) {
118
+ const auto _Pbase_diff = _Right._Mysb::pbase() - _Right_data;
119
+ const auto _Pptr_diff = _Right._Mysb::pptr() - _Right_data;
120
+ const auto _Epptr_diff = _Right._Mysb::epptr() - _Right_data;
121
+ _Mysb::setp(_New_data + _Pbase_diff, _New_data + _Pptr_diff, _New_data + _Epptr_diff);
122
+ } else {
123
+ _Mysb::setp(nullptr, nullptr, nullptr);
124
+ }
125
+
126
+ const auto _Right_view = _Right._Get_buffer_view();
127
+ if (_Right_view._Ptr != nullptr) {
128
+ _Traits::copy(_New_data + (_Right_view._Ptr - _Right_data), _Right_view._Ptr, _Right_view._Size);
129
+ }
130
+
131
+ _Seekhigh = _New_data + _New_capacity;
132
+ _Mystate = _Right._Mystate;
133
+
134
+ _Right._Tidy();
135
+ }
136
+
137
+ void _Assign_rv_no_alias(basic_stringbuf&& _Right) noexcept(
138
+ _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) {
139
+ // pre: this != std::addressof(_Right)
140
+ _Tidy();
141
+ if constexpr (_Choose_pocma_v<_Alloc> == _Pocma_values::_No_propagate_allocators) {
142
+ if (_Al == _Right._Al) {
143
+ _Take_contents(_STD move(_Right));
144
+ } else {
145
+ _Copy_into_self_and_tidy(_STD move(_Right));
146
+ }
147
+ } else {
148
+ _Pocma(_Al, _Right._Al);
149
+ _Take_contents(_STD move(_Right));
87
150
}
88
151
}
89
152
@@ -584,20 +647,17 @@ public:
584
647
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode | ios_base::in) {}
585
648
#endif // _HAS_CXX20
586
649
587
- basic_istringstream(basic_istringstream&& _Right) : _Mybase(_STD addressof(_Stringbuffer)) {
588
- _Assign_rv (_STD move(_Right));
589
- }
650
+ basic_istringstream(basic_istringstream&& _Right)
651
+ : _Mybase (_STD addressof(_Stringbuffer)),
652
+ _Stringbuffer((_Mybase::swap(_Right), _STD move(_Right._Stringbuffer))) { }
590
653
591
- basic_istringstream& operator=(basic_istringstream&& _Right) noexcept /* strengthened */ {
592
- _Assign_rv(_STD move(_Right));
593
- return *this;
594
- }
595
-
596
- void _Assign_rv(basic_istringstream&& _Right) noexcept {
654
+ basic_istringstream& operator=(basic_istringstream&& _Right) noexcept(
655
+ _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) /* strengthened */ {
597
656
if (this != _STD addressof(_Right)) {
598
657
_Mybase::swap(_Right);
599
- _Stringbuffer._Assign_rv (_STD move(_Right._Stringbuffer));
658
+ _Stringbuffer._Assign_rv_no_alias (_STD move(_Right._Stringbuffer));
600
659
}
660
+ return *this;
601
661
}
602
662
603
663
void swap(basic_istringstream& _Right) noexcept /* strengthened */ {
@@ -704,20 +764,17 @@ public:
704
764
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode | ios_base::out) {}
705
765
#endif // _HAS_CXX20
706
766
707
- basic_ostringstream(basic_ostringstream&& _Right) : _Mybase(_STD addressof(_Stringbuffer)) {
708
- _Assign_rv (_STD move(_Right));
709
- }
767
+ basic_ostringstream(basic_ostringstream&& _Right)
768
+ : _Mybase (_STD addressof(_Stringbuffer)),
769
+ _Stringbuffer((_Mybase::swap(_Right), _STD move(_Right._Stringbuffer))) { }
710
770
711
- basic_ostringstream& operator=(basic_ostringstream&& _Right) noexcept /* strengthened */ {
712
- _Assign_rv(_STD move(_Right));
713
- return *this;
714
- }
715
-
716
- void _Assign_rv(basic_ostringstream&& _Right) noexcept {
771
+ basic_ostringstream& operator=(basic_ostringstream&& _Right) noexcept(
772
+ _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) /* strengthened */ {
717
773
if (this != _STD addressof(_Right)) {
718
774
_Mybase::swap(_Right);
719
- _Stringbuffer._Assign_rv (_STD move(_Right._Stringbuffer));
775
+ _Stringbuffer._Assign_rv_no_alias (_STD move(_Right._Stringbuffer));
720
776
}
777
+ return *this;
721
778
}
722
779
723
780
void swap(basic_ostringstream& _Right) noexcept /* strengthened */ {
@@ -830,20 +887,17 @@ public:
830
887
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode) {}
831
888
#endif // _HAS_CXX20
832
889
833
- basic_stringstream(basic_stringstream&& _Right) : _Mybase(_STD addressof(_Stringbuffer)) {
834
- _Assign_rv (_STD move(_Right));
835
- }
890
+ basic_stringstream(basic_stringstream&& _Right)
891
+ : _Mybase (_STD addressof(_Stringbuffer)),
892
+ _Stringbuffer((_Mybase::swap(_Right), _STD move(_Right._Stringbuffer))) { }
836
893
837
- basic_stringstream& operator=(basic_stringstream&& _Right) noexcept /* strengthened */ {
838
- _Assign_rv(_STD move(_Right));
839
- return *this;
840
- }
841
-
842
- void _Assign_rv(basic_stringstream&& _Right) noexcept {
894
+ basic_stringstream& operator=(basic_stringstream&& _Right) noexcept(
895
+ _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) /* strengthened */ {
843
896
if (this != _STD addressof(_Right)) {
844
897
_Mybase::swap(_Right);
845
- _Stringbuffer._Assign_rv (_STD move(_Right._Stringbuffer));
898
+ _Stringbuffer._Assign_rv_no_alias (_STD move(_Right._Stringbuffer));
846
899
}
900
+ return *this;
847
901
}
848
902
849
903
void swap(basic_stringstream& _Right) noexcept /* strengthened */ {
0 commit comments