forked from Alepha/Alepha
Fix problems in the stackable streambuf cleanup.
This commit is contained in:
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user