From 92d6b3840d7380bb8edec367eeb0d6dc6a68a54d Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Tue, 17 Oct 2023 17:27:57 -0400 Subject: [PATCH] Use the stacked streambuf to implement wrapping. --- word_wrap.cpp | 57 +++++++++------------------------------------------ word_wrap.h | 13 +++++++----- 2 files changed, 18 insertions(+), 52 deletions(-) diff --git a/word_wrap.cpp b/word_wrap.cpp index 161c446..7447426 100644 --- a/word_wrap.cpp +++ b/word_wrap.cpp @@ -10,8 +10,6 @@ static_assert( __cplusplus > 2020 ); #include #include -#include - #include "evaluation_helpers.h" namespace Alepha::Cavorite ::detail:: word_wrap @@ -41,38 +39,23 @@ namespace Alepha::Cavorite ::detail:: word_wrap } struct WordWrapStreambuf - : public std::streambuf + : public Utility::StackableStreambuf { public: - std::unique_ptr< std::streambuf > ownership; - std::streambuf *underlying= nullptr; - std::size_t maximumWidth= 0; std::size_t nextLineOffset= 0; std::size_t currentLineLength= 0; std::string currentWord; - void writeChar( const char ch ); + explicit + WordWrapStreambuf( std::ostream &os, const std::size_t width, const std::size_t offset ) + : StackableStreambuf( os ), maximumWidth( width ), nextLineOffset( offset ) + {} - void drain(); + void writeChar( const char ch ) override; - public: - int - overflow( const int ch ) override - { - if( ch == EOF ) throw std::logic_error( "EOF!" ); - writeChar( ch ); - - return 1; - } - - std::streamsize - xsputn( const char *const data, const std::streamsize amt ) override - { - for( std::streamsize i= 0; i< amt; ++i ) overflow( data[ i ] ); - return amt; - } + void drain() override; }; } @@ -160,29 +143,9 @@ namespace Alepha::Cavorite ::detail:: word_wrap } } - std::ostream & - impl::operator << ( std::ostream &os, EndWrap_t ) + void + impl::build_streambuf( std::ostream &os, StartWrap &&args ) { - releaseWrapper( os ); - return os; - } - - std::ostream & - impl::operator << ( std::ostream &os, StartWrap args ) - { - auto buf= std::make_unique< WordWrapStreambuf >(); - buf->maximumWidth= args.width; - buf->nextLineOffset= args.nextLineOffset; - buf->underlying= os.rdbuf( buf.get() ); - auto &state= os.iword( wrapperIndex ); - if( not state ) - { - state= 1; - os.register_callback( wordwrapCallback, wrapperIndex ); - } - assert( os.pword( wrapperIndex ) == nullptr ); - os.pword( wrapperIndex )= buf.release(); - - return os; + new WordWrapStreambuf( os, args.width, args.nextLineOffset ); } } diff --git a/word_wrap.h b/word_wrap.h index 80979e1..d1eb350 100644 --- a/word_wrap.h +++ b/word_wrap.h @@ -7,27 +7,30 @@ static_assert( __cplusplus > 2020'00 ); #include #include +#include + namespace Alepha::inline Cavorite ::detail:: word_wrap { inline namespace exports { std::string wordWrap( const std::string &text, std::size_t width, std::size_t nextLineOffset= 0 ); - struct StartWrap + struct StartWrap_params { std::size_t width; std::size_t nextLineOffset; - explicit StartWrap( const std::size_t width, const std::size_t nextLineOffset= 0 ) : width( width ), nextLineOffset( nextLineOffset ) {} + explicit StartWrap_params( const std::size_t width, const std::size_t nextLineOffset= 0 ) : width( width ), nextLineOffset( nextLineOffset ) {} }; - constexpr struct EndWrap_t {} EndWrap; + using StartWrap= Utility::PushStack< StartWrap_params >; + + constexpr Utility::PopStack< StartWrap_params > EndWrap; } inline namespace impl { - std::ostream &operator << ( std::ostream &, StartWrap ); - std::ostream &operator << ( std::ostream &, EndWrap_t ); + void build_streambuf( std::ostream &os, StartWrap &&args ); } }