From a6467772f4a8800c72ea1880b283c7b3555d28ef Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Thu, 4 Apr 2024 15:41:27 -0400 Subject: [PATCH] Make it possible to use arbitrary code in making delimited lists. --- delimited_list.cc | 14 +++++++------- delimited_list.h | 13 +++++++++++-- delimited_list.test/0.cc | 30 ++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/delimited_list.cc b/delimited_list.cc index a4ebf9b..14ded6e 100644 --- a/delimited_list.cc +++ b/delimited_list.cc @@ -28,23 +28,23 @@ namespace Alepha::Hydrogen ::detail:: delimited_list_m : virtual public IOStreams::StackableStreambuf, virtual public std::streambuf { private: - std::string delim; + DelimiterWriter writer; bool first= true; public: explicit - DelimitedListStreambuf( std::ios &is, const std::string delim ) - : StackableStreambuf( is ), delim( delim ) + DelimitedListStreambuf( std::ios &is, const DelimiterWriter writer ) + : StackableStreambuf( is ), writer( writer ) { tracker.get( is )= this; if( C::debug ) error() << "Streambuf adapted." << std::endl; } void - doNext() + doNext( std::ostream &out ) { if( C::debug ) error() << "Do Next called" << std::endl; - if( not first ) out() << delim; + if( not first ) writer( out ); first= false; } @@ -66,7 +66,7 @@ namespace Alepha::Hydrogen ::detail:: delimited_list_m { if( C::debug ) error() << "Marker called" << std::endl; auto thisTracker= tracker.get( os ); - if( thisTracker != nullptr ) thisTracker->doNext(); + if( thisTracker != nullptr ) thisTracker->doNext( os ); return os; } @@ -74,6 +74,6 @@ namespace Alepha::Hydrogen ::detail:: delimited_list_m void impl::build_streambuf( std::ostream &os, StartDelimitedList &¶ms ) { - new impl_cc::DelimitedListStreambuf( os, params.delimiter ); + new impl_cc::DelimitedListStreambuf( os, params.writer ); } } diff --git a/delimited_list.h b/delimited_list.h index 27239f9..a89fe80 100644 --- a/delimited_list.h +++ b/delimited_list.h @@ -12,11 +12,20 @@ namespace Alepha::Hydrogen ::detail:: delimited_list_m { inline namespace exports {} + using DelimiterWriter= std::function< void ( std::ostream & ) >; struct DelimitedList_params { - const std::string delimiter; + DelimiterWriter writer; - explicit DelimitedList_params( const std::string delimiter ) : delimiter( delimiter ) {} + explicit + DelimitedList_params( const std::string delimiter ) + : writer( [delimiter] ( std::ostream &os ) { os << delimiter; } ) + {} + + explicit + DelimitedList_params( DelimiterWriter writer ) + : writer( writer ) + {} }; struct MarkItem_t {}; diff --git a/delimited_list.test/0.cc b/delimited_list.test/0.cc index a671af8..5af3f47 100644 --- a/delimited_list.test/0.cc +++ b/delimited_list.test/0.cc @@ -7,6 +7,8 @@ static_assert( __cplusplus > 2020'99 ); #include +#include + static auto init= Alepha::Utility::enroll <=[] { using namespace Alepha::Testing::literals; @@ -32,4 +34,32 @@ static auto init= Alepha::Utility::enroll <=[] { { "Simple", { { "Alpha", "Bravo", "Charlie", "Delta", "Echo" } }, "Alpha, Bravo, Charlie, Delta, Echo" }, }; + + "Simple Comma Testing using delim function"_test <=TableTest + < + []( std::vector< std::string > names ) + { + std::ostringstream oss; + oss << setDelimiter( Alepha::IOStreams::fieldDelimiter, ", " ); + + oss << Alepha::StartDelimitedList + { + []( std::ostream &os ) + { + os << Alepha::IOStreams::fieldDelimiter; + } + }; + + for( const auto &name: names ) + { + oss << Alepha::NextItem << name; + } + + return oss.str(); + } + > + ::Cases + { + { "Simple", { { "Alpha", "Bravo", "Charlie", "Delta", "Echo" } }, "Alpha, Bravo, Charlie, Delta, Echo" }, + }; };