new library for arguments - namespace mrw added; refs #6
parent
a6b48ec7c4
commit
fbe6874579
3 changed files with 472 additions and 408 deletions
@ -0,0 +1,105 @@ |
||||
/*! @file |
||||
|
||||
@id $Id$ |
||||
*/ |
||||
// 1 2 3 4 5 6 7 8 |
||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890 |
||||
|
||||
#ifndef __MRW__IOMANIP__ |
||||
#define __MRW__IOMANIP__ |
||||
|
||||
#include <stdexcept> |
||||
#include <sstream> |
||||
#include <string> |
||||
#include <iomanip> |
||||
|
||||
// check if code is compiled with a new C++11 compiler |
||||
// otherwise there is a fallback wich makes everything much more compliacted |
||||
#ifndef ARGS__OLD_PRE11_COMPILER |
||||
#if __cplusplus < 201103L |
||||
/// Code is compiled with an old non C++11 standard compliant compiler |
||||
/** There are workarounds for old non C++11 compatible |
||||
compilers. These workarounds are deprecated, but will remain until |
||||
most compilers fully support C++11. So this workaround will be |
||||
removed in future releases, when support for C++11 is more |
||||
common. Only rely on this workaround, if you really have to. |
||||
@see oldcompiler for details on usage */ |
||||
#define ARGS__OLD_PRE11_COMPILER |
||||
#warning You need a C++11 compliant compiler, on gcc use option -std=c++11 |
||||
#warning emulating C++11 - this changes the way you use the library |
||||
#warning this is deprecated and will be removed in future releases |
||||
#warning refere to the library documentation for more details |
||||
#endif |
||||
#endif |
||||
|
||||
|
||||
namespace mrw { |
||||
//! IO-Manipulator to split long lines into several shorter lines. |
||||
template <class _CharT = char, class _Traits = std::char_traits<_CharT> > |
||||
class basic_split /*: public std::basic_ostream<_CharT, _Traits>*/ { |
||||
public: |
||||
basic_split(int width=80, int indent=0, char fill=' '): |
||||
_width(width), _indent(indent), _fill(fill), _os(0) { |
||||
if (_width<_indent) |
||||
#ifdef ARGS__OLD_PRE11_COMPILER |
||||
throw std::runtime_error(((std::stringstream&) |
||||
(std::stringstream() |
||||
<<"wrong use of split: width is "<<_width |
||||
<<" but should be larger than indent," |
||||
<<" which is "<<_indent)).str()); |
||||
#else |
||||
throw std::runtime_error("wrong use of split: width is "+ |
||||
std::to_string(_width)+ |
||||
" but should be larger than indent," |
||||
" which is "+std::to_string(_indent)); |
||||
#endif |
||||
} |
||||
virtual ~basic_split() { |
||||
flush(); |
||||
} |
||||
friend basic_split& operator<<(std::basic_ostream<_CharT, _Traits>& os, |
||||
const basic_split& s) { |
||||
if (s._os!=&os) { |
||||
const_cast<basic_split&>(s).flush(); |
||||
const_cast<basic_split&>(s)._os = &os; |
||||
} |
||||
return const_cast<basic_split&>(s); |
||||
} |
||||
template <typename T> basic_split& operator<<(T t) { |
||||
if (!_os) |
||||
throw std::runtime_error("wrong use of split, it is an io" |
||||
" manipulator and must be used within" |
||||
" a stream"); |
||||
_buffer<<t; |
||||
while (_buffer.str().size()>=_width-_indent) { |
||||
if (_indent) *_os<<std::setw(_indent)<<std::setfill(_fill)<<_fill; |
||||
std::string::size_type pos |
||||
(_buffer.str().find_last_of(' ', _width-_indent)); |
||||
std::string::size_type next(pos+1); |
||||
if (pos==std::string::npos) { |
||||
pos=_width-_indent; |
||||
next=pos; |
||||
} |
||||
*_os<<_buffer.str().substr(0, pos)<<std::endl; |
||||
_buffer.str(_buffer.str().substr(next)); |
||||
} |
||||
return *this; |
||||
} |
||||
private: |
||||
void flush() { |
||||
if (_os) { |
||||
if (_indent) *_os<<std::setw(_indent)<<std::setfill(_fill)<<_fill; |
||||
*_os<<_buffer.str(); |
||||
_buffer.clear(); |
||||
} |
||||
} |
||||
private: |
||||
int _width; |
||||
int _indent; |
||||
char _fill; |
||||
std::stringstream _buffer; |
||||
std::basic_ostream<_CharT, _Traits>* _os; |
||||
}; |
||||
typedef basic_split<char> split; |
||||
} |
||||
#endif |
Loading…
Reference in new issue