From 352bf22a687a8322759855463bbc839f8d172fd7 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Thu, 9 Nov 2023 14:29:40 -0500 Subject: [PATCH] Fix problems in the stackable streambuf cleanup. --- Utility/StackableStreambuf.cc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Utility/StackableStreambuf.cc b/Utility/StackableStreambuf.cc index 8ff763b..fc9fba2 100644 --- a/Utility/StackableStreambuf.cc +++ b/Utility/StackableStreambuf.cc @@ -2,16 +2,24 @@ static_assert( __cplusplus > 2020'99 ); #include "StackableStreambuf.h" +#include + namespace Alepha::Hydrogen::Utility::detail::stackable_streambuf { namespace { const auto index= std::ios::xalloc(); - inline auto & + auto *& + getStackPtr( std::ios_base &ios ) + { + return reinterpret_cast< std::stack< std::unique_ptr< StackableStreambuf > > *& >( ios.pword( index ) ); + } + + auto & getStack( std::ios_base &ios ) { - auto &ownership= reinterpret_cast< std::stack< std::unique_ptr< StackableStreambuf > > *& >( ios.pword( index ) ); + auto &ownership= getStackPtr( ios ); if( not ownership ) ownership= new std::decay_t< decltype( *ownership ) >{}; return *ownership; @@ -24,6 +32,7 @@ namespace Alepha::Hydrogen::Utility::detail::stackable_streambuf { auto &ownership= getStack( ios ); + assert( not ownership.empty() ); // Since it's owned, delete happens at scope exit. const std::unique_ptr top= std::move( ownership.top() ); ownership.pop(); @@ -48,9 +57,8 @@ namespace Alepha::Hydrogen::Utility::detail::stackable_streambuf inline void releaseStack( std::ios_base &ios ) { - auto &os= dynamic_cast< std::ostream & >( ios ); - - while( releaseTop( os ) ); + delete getStackPtr( ios ); + getStackPtr( ios )= nullptr; } void