forked from Alepha/Alepha
Use the stacked streambuf to implement wrapping.
This commit is contained in:
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
word_wrap.h
13
word_wrap.h
@ -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 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user