forked from Alepha/Alepha
List delimiting primitive for output streams.
This commit is contained in:
@ -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
79
delimited_list.cc
Normal 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 &¶ms )
|
||||||
|
{
|
||||||
|
new impl_cc::DelimitedListStreambuf( os, params.delimiter );
|
||||||
|
}
|
||||||
|
}
|
42
delimited_list.h
Normal file
42
delimited_list.h
Normal 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
35
delimited_list.test/0.cc
Normal 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" },
|
||||||
|
};
|
||||||
|
};
|
1
delimited_list.test/CMakeLists.txt
Normal file
1
delimited_list.test/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
unit_test( 0 )
|
Reference in New Issue
Block a user