1
0
forked from Alepha/Alepha

List delimiting primitive for output streams.

This commit is contained in:
2024-04-03 15:53:43 -04:00
parent 8bd9852bd4
commit 66e8acfd5b
5 changed files with 159 additions and 0 deletions

View File

@ -14,6 +14,7 @@ add_library( alepha SHARED
string_algorithms.cc string_algorithms.cc
word_wrap.cc word_wrap.cc
Thread.cc Thread.cc
delimited_list.cc
) )
# Everything else depends upon it # Everything else depends upon it
link_libraries( alepha ) link_libraries( alepha )
@ -40,6 +41,7 @@ add_subdirectory( assertion.test )
add_subdirectory( Constness.test ) add_subdirectory( Constness.test )
add_subdirectory( Blob.test ) add_subdirectory( Blob.test )
add_subdirectory( Capabilities.test ) add_subdirectory( Capabilities.test )
add_subdirectory( delimited_list.test )
# Sample applications # Sample applications
add_executable( example example.cc ) add_executable( example example.cc )

79
delimited_list.cc Normal file
View File

@ -0,0 +1,79 @@
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:
std::string delim;
bool first= true;
public:
explicit
DelimitedListStreambuf( std::ios &is, const std::string delim )
: StackableStreambuf( is ), delim( delim )
{
tracker.get( is )= this;
if( C::debug ) error() << "Streambuf adapted." << std::endl;
}
void
doNext()
{
if( C::debug ) error() << "Do Next called" << std::endl;
if( not first ) out() << delim;
first= false;
}
private:
void writeChar( char ) override { throw "Unimpl"; }
void drain() override { throw "Unimpl"; }
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();
return os;
}
void
impl::build_streambuf( std::ostream &os, StartDelimitedList &&params )
{
new impl_cc::DelimitedListStreambuf( os, params.delimiter );
}
}

42
delimited_list.h Normal file
View File

@ -0,0 +1,42 @@
static_assert( __cplusplus > 2020'99 );
#pragma once
#include <Alepha/Alepha.h>
#include <ostream>
#include <Alepha/IOStreams/StackableStreambuf.h>
namespace Alepha::Hydrogen ::detail:: delimited_list_m
{
inline namespace exports {}
struct DelimitedList_params
{
const std::string delimiter;
explicit DelimitedList_params( const std::string delimiter ) : delimiter( delimiter ) {}
};
struct MarkItem_t {};
namespace exports
{
constexpr MarkItem_t NextItem;;
using StartDelimitedList= IOStreams::PushStack< DelimitedList_params >;
constexpr IOStreams::PopStack EndDelimitedList;
}
inline namespace impl
{
void build_streambuf( std::ostream &, StartDelimitedList && );
std::ostream &operator << ( std::ostream &os, MarkItem_t );
}
}
namespace Alepha::Hydrogen::inline exports::inline delimited_list_m
{
using namespace detail::delimited_list_m::exports;
}

35
delimited_list.test/0.cc Normal file
View File

@ -0,0 +1,35 @@
static_assert( __cplusplus > 2020'99 );
#include "../delimited_list.h"
#include <Alepha/Testing/test.h>
#include <Alepha/Testing/TableTest.h>
#include <Alepha/Utility/evaluation_helpers.h>
static auto init= Alepha::Utility::enroll <=[]
{
using namespace Alepha::Testing::literals;
using namespace std::literals::string_literals;
using namespace Alepha::Testing::exports;
"Simple Comma Testing"_test <=TableTest
<
[]( std::vector< std::string > names )
{
std::ostringstream oss;
oss << Alepha::StartDelimitedList{ ", "s };
for( const auto &name: names )
{
oss << Alepha::NextItem << name;
}
return oss.str();
}
>
::Cases
{
{ "Simple", { { "Alpha", "Bravo", "Charlie", "Delta", "Echo" } }, "Alpha, Bravo, Charlie, Delta, Echo" },
};
};

View File

@ -0,0 +1 @@
unit_test( 0 )