forked from Alepha/Alepha
80 lines
1.6 KiB
C++
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 &¶ms )
|
|
{
|
|
new impl_cc::DelimitedListStreambuf( os, params.writer );
|
|
}
|
|
}
|