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 <cassert>
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