1
0
forked from Alepha/Alepha

Fix problems in the stackable streambuf cleanup.

This commit is contained in:
2023-11-09 14:29:40 -05:00
parent 6a77318df8
commit 352bf22a68

View File

@ -2,16 +2,24 @@ static_assert( __cplusplus > 2020'99 );
#include "StackableStreambuf.h" #include "StackableStreambuf.h"
#include <cassert>
namespace Alepha::Hydrogen::Utility::detail::stackable_streambuf namespace Alepha::Hydrogen::Utility::detail::stackable_streambuf
{ {
namespace namespace
{ {
const auto index= std::ios::xalloc(); 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 ) 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 ) >{}; if( not ownership ) ownership= new std::decay_t< decltype( *ownership ) >{};
return *ownership; return *ownership;
@ -24,6 +32,7 @@ namespace Alepha::Hydrogen::Utility::detail::stackable_streambuf
{ {
auto &ownership= getStack( ios ); auto &ownership= getStack( ios );
assert( not ownership.empty() );
// Since it's owned, delete happens at scope exit. // Since it's owned, delete happens at scope exit.
const std::unique_ptr top= std::move( ownership.top() ); const std::unique_ptr top= std::move( ownership.top() );
ownership.pop(); ownership.pop();
@ -48,9 +57,8 @@ namespace Alepha::Hydrogen::Utility::detail::stackable_streambuf
inline void inline void
releaseStack( std::ios_base &ios ) releaseStack( std::ios_base &ios )
{ {
auto &os= dynamic_cast< std::ostream & >( ios ); delete getStackPtr( ios );
getStackPtr( ios )= nullptr;
while( releaseTop( os ) );
} }
void void