1
0
forked from Alepha/Alepha
Files
Alepha/delimited_list.cc

80 lines
1.6 KiB
C++

static_assert( __cplusplus > 2020'99 );
#include "delimited_list.h"
#include <Alepha/error.h>
#include <Alepha/IOStreams/StreamState.h>
namespace Alepha::Hydrogen ::detail:: delimited_list_m
{
namespace
{
namespace C
{
const bool debug= false;
}
namespace impl_cc
{
struct DelimitedListStreambuf;
}
IOStreams::StreamState< impl_cc::DelimitedListStreambuf * > tracker{ [] { return nullptr; } };
}
struct impl_cc::DelimitedListStreambuf
: virtual public IOStreams::StackableStreambuf, virtual public std::streambuf
{
private:
DelimiterWriter writer;
bool first= true;
public:
explicit
DelimitedListStreambuf( std::ios &ios, const DelimiterWriter writer )
: StackableStreambuf( ios ), writer( writer )
{
tracker.get( ios )= this;
if( C::debug ) error() << "Streambuf adapted." << std::endl;
}
void
doNext( std::ostream &out )
{
if( C::debug ) error() << "Do Next called" << std::endl;
if( not first ) writer( out );
first= false;
}
private:
void writeChar( char ) override { throw "Unimpl"; }
void drain() override {} // Do nothing...
int
overflow( const int ch ) override
{
if( C::debug ) error() << "Overflow called" << std::endl;
return forwardOverflow( ch );
}
};
std::ostream &
impl::operator << ( std::ostream &os, MarkItem_t )
{
if( C::debug ) error() << "Marker called" << std::endl;
auto thisTracker= tracker.get( os );
if( thisTracker != nullptr ) thisTracker->doNext( os );
return os;
}
void
impl::build_streambuf( std::ostream &os, StartDelimitedList &&params )
{
new impl_cc::DelimitedListStreambuf( os, params.writer );
}
}