1
0
forked from Alepha/Alepha

Use the stacked streambuf to implement wrapping.

This commit is contained in:
2023-10-17 17:27:57 -04:00
parent 87634c4549
commit 92d6b3840d
2 changed files with 18 additions and 52 deletions

View File

@ -10,8 +10,6 @@ static_assert( __cplusplus > 2020 );
#include <sstream> #include <sstream>
#include <memory> #include <memory>
#include <Alepha/Utility/StackableStreambuf.h>
#include "evaluation_helpers.h" #include "evaluation_helpers.h"
namespace Alepha::Cavorite ::detail:: word_wrap namespace Alepha::Cavorite ::detail:: word_wrap
@ -41,38 +39,23 @@ namespace Alepha::Cavorite ::detail:: word_wrap
} }
struct WordWrapStreambuf struct WordWrapStreambuf
: public std::streambuf : public Utility::StackableStreambuf
{ {
public: public:
std::unique_ptr< std::streambuf > ownership;
std::streambuf *underlying= nullptr;
std::size_t maximumWidth= 0; std::size_t maximumWidth= 0;
std::size_t nextLineOffset= 0; std::size_t nextLineOffset= 0;
std::size_t currentLineLength= 0; std::size_t currentLineLength= 0;
std::string currentWord; 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: void drain() override;
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;
}
}; };
} }
@ -160,29 +143,9 @@ namespace Alepha::Cavorite ::detail:: word_wrap
} }
} }
std::ostream & void
impl::operator << ( std::ostream &os, EndWrap_t ) impl::build_streambuf( std::ostream &os, StartWrap &&args )
{ {
releaseWrapper( os ); new WordWrapStreambuf( os, args.width, args.nextLineOffset );
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;
} }
} }

View File

@ -7,27 +7,30 @@ static_assert( __cplusplus > 2020'00 );
#include <string> #include <string>
#include <streambuf> #include <streambuf>
#include <Alepha/Utility/StackableStreambuf.h>
namespace Alepha::inline Cavorite ::detail:: word_wrap namespace Alepha::inline Cavorite ::detail:: word_wrap
{ {
inline namespace exports inline namespace exports
{ {
std::string wordWrap( const std::string &text, std::size_t width, std::size_t nextLineOffset= 0 ); 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 width;
std::size_t nextLineOffset; 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 inline namespace impl
{ {
std::ostream &operator << ( std::ostream &, StartWrap ); void build_streambuf( std::ostream &os, StartWrap &&args );
std::ostream &operator << ( std::ostream &, EndWrap_t );
} }
} }