static_assert( __cplusplus > 2020'99 ); #include "delimited_list.h" #include #include 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 ); } }