@@ -119,6 +119,7 @@ protected:
119119# include < __locale>
120120# include < __type_traits/is_same.h>
121121# include < __utility/is_valid_range.h>
122+ # include < __utility/scope_guard.h>
122123# include < climits>
123124# include < ios>
124125# include < iosfwd>
@@ -178,18 +179,27 @@ public:
178179 // Get and put areas:
179180 // 27.6.2.2.3 Get area:
180181 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize in_avail () {
182+ __check_invariants ();
183+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
184+
181185 if (gptr () < egptr ())
182186 return static_cast <streamsize>(egptr () - gptr ());
183187 return showmanyc ();
184188 }
185189
186190 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc () {
191+ __check_invariants ();
192+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
193+
187194 if (sbumpc () == traits_type::eof ())
188195 return traits_type::eof ();
189196 return sgetc ();
190197 }
191198
192199 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sbumpc () {
200+ __check_invariants ();
201+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
202+
193203 if (gptr () == egptr ())
194204 return uflow ();
195205 int_type __c = traits_type::to_int_type (*gptr ());
@@ -198,6 +208,9 @@ public:
198208 }
199209
200210 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc () {
211+ __check_invariants ();
212+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
213+
201214 if (gptr () == egptr ())
202215 return underflow ();
203216 return traits_type::to_int_type (*gptr ());
@@ -207,13 +220,19 @@ public:
207220
208221 // 27.6.2.2.4 Putback:
209222 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputbackc (char_type __c) {
223+ __check_invariants ();
224+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
225+
210226 if (eback () == gptr () || !traits_type::eq (__c, *(gptr () - 1 )))
211227 return pbackfail (traits_type::to_int_type (__c));
212228 this ->gbump (-1 );
213229 return traits_type::to_int_type (*gptr ());
214230 }
215231
216232 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sungetc () {
233+ __check_invariants ();
234+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
235+
217236 if (eback () == gptr ())
218237 return pbackfail ();
219238 this ->gbump (-1 );
@@ -222,6 +241,9 @@ public:
222241
223242 // 27.6.2.2.5 Put area:
224243 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputc (char_type __c) {
244+ __check_invariants ();
245+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
246+
225247 if (pptr () == epptr ())
226248 return overflow (traits_type::to_int_type (__c));
227249 *pptr () = __c;
@@ -317,6 +339,9 @@ protected:
317339 virtual streamsize showmanyc () { return 0 ; }
318340
319341 virtual streamsize xsgetn (char_type* __s, streamsize __n) {
342+ __check_invariants ();
343+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
344+
320345 int_type __c;
321346 streamsize __i = 0 ;
322347 while (__i < __n) {
@@ -338,6 +363,9 @@ protected:
338363
339364 virtual int_type underflow () { return traits_type::eof (); }
340365 virtual int_type uflow () {
366+ __check_invariants ();
367+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
368+
341369 if (underflow () == traits_type::eof ())
342370 return traits_type::eof ();
343371 int_type __c = traits_type::to_int_type (*gptr ());
@@ -350,6 +378,9 @@ protected:
350378
351379 // 27.6.2.4.5 Put area:
352380 virtual streamsize xsputn (const char_type* __s, streamsize __n) {
381+ __check_invariants ();
382+ auto __guard = std::__make_scope_guard ([this ] { this ->__check_invariants (); });
383+
353384 streamsize __i = 0 ;
354385 while (__i < __n) {
355386 if (pptr () >= epptr ()) {
@@ -370,6 +401,15 @@ protected:
370401
371402 virtual int_type overflow (int_type = traits_type::eof()) { return traits_type::eof (); }
372403
404+ // This function checks some invariants of the class (it isn't exhaustive).
405+ _LIBCPP_HIDE_FROM_ABI void __check_invariants () const {
406+ _LIBCPP_ASSERT_INTERNAL (pbase () <= pptr (), " this is an invariant of the class" );
407+ _LIBCPP_ASSERT_INTERNAL (pptr () <= epptr (), " this is an invariant of the class" );
408+
409+ _LIBCPP_ASSERT_INTERNAL (eback () <= gptr (), " this is an invariant of the class" );
410+ _LIBCPP_ASSERT_INTERNAL (gptr () <= egptr (), " this is an invariant of the class" );
411+ }
412+
373413private:
374414 locale __loc_;
375415 char_type* __binp_ = nullptr ;
0 commit comments