new library for arguments - namespace mrw added; refs #6
This commit is contained in:
@@ -21,55 +21,64 @@ int main(int argc, char** argv) try {
|
|||||||
|
|
||||||
// bind and evaluate options
|
// bind and evaluate options
|
||||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
args::list options;
|
mrw::args::list options;
|
||||||
std::vector<std::shared_ptr<args::abstract_parameter> > params;
|
std::vector<std::shared_ptr<mrw::args::abstract_parameter> > params;
|
||||||
params.push_back(args::help());
|
params.push_back(mrw::args::help());
|
||||||
params.push_back(args::exit());
|
params.push_back(mrw::args::exit());
|
||||||
options.push_back(args::declaration("h", "help", "show this help", params));
|
options.push_back(mrw::args::declaration("h", "help", "show this help",
|
||||||
params.clear();
|
|
||||||
params.push_back(args::param(r, "number"));
|
|
||||||
options.push_back(args::declaration("r", "repeat", "number of repetitions",
|
|
||||||
params));
|
params));
|
||||||
params.clear();
|
params.clear();
|
||||||
params.push_back(args::param(flag));
|
params.push_back(mrw::args::param(r, "number"));
|
||||||
options.push_back(args::declaration("f", "flag", "check a flag", params));
|
options.push_back(mrw::args::declaration("r", "repeat",
|
||||||
params.clear();
|
"number of repetitions",
|
||||||
params.push_back(args::param(txt, "text"));
|
|
||||||
options.push_back(args::declaration("t", "text", "pass a text", params));
|
|
||||||
params.clear();
|
|
||||||
params.push_back(args::param(x, "x"));
|
|
||||||
params.push_back(args::param(y, "y"));
|
|
||||||
options.push_back(args::declaration("c", "coord", "add some 2D coordinates",
|
|
||||||
params));
|
params));
|
||||||
params.clear();
|
params.clear();
|
||||||
params.push_back(args::func(test_func));
|
params.push_back(mrw::args::param(flag));
|
||||||
options.push_back(args::declaration("", "test",
|
options.push_back(mrw::args::declaration("f", "flag", "check a flag",
|
||||||
"call test_func, no shortcut", params));
|
params));
|
||||||
args::init(argc, argv, "This is an example for argument processing.",
|
params.clear();
|
||||||
|
params.push_back(mrw::args::param(txt, "text"));
|
||||||
|
options.push_back(mrw::args::declaration("t", "text", "pass a text", params));
|
||||||
|
params.clear();
|
||||||
|
params.push_back(mrw::args::param(x, "x"));
|
||||||
|
params.push_back(mrw::args::param(y, "y"));
|
||||||
|
options.push_back(mrw::args::declaration("c", "coord",
|
||||||
|
"add some 2D coordinates",
|
||||||
|
params));
|
||||||
|
params.clear();
|
||||||
|
params.push_back(mrw::args::func(test_func));
|
||||||
|
options.push_back(mrw::args::declaration("", "test",
|
||||||
|
"call test_func, no shortcut",
|
||||||
|
params));
|
||||||
|
mrw::args::parse(argc, argv, "This is an example for argument processing.",
|
||||||
options);
|
options);
|
||||||
#else
|
#else
|
||||||
args::init(argc, argv,
|
mrw::args::parse(argc, argv,
|
||||||
"This is an example for argument processing. If the description "
|
"This is an example for argument processing. If the"
|
||||||
"is very long, it is automatically splitted over several lines "
|
" description is very long, it is automatically splitted"
|
||||||
"and indented on each new line. Arguments may have several "
|
" over several lines and indented on each new line."
|
||||||
"parameters. Help is generated automatically from the argument "
|
" Arguments may have several parameters. Help is"
|
||||||
"declaration. The argument declaration contains long and short "
|
" generated automatically from the argument declaration."
|
||||||
"options and a list of parameters.",
|
" The argument declaration contains long and short options"
|
||||||
|
" and a list of parameters.",
|
||||||
{
|
{
|
||||||
{"h", "help", "show this help", {args::help(), args::exit()}},
|
{"h", "help", "show this help",
|
||||||
|
{mrw::args::help(), mrw::args::exit()}},
|
||||||
{"r", "repeat", "number of repetitions",
|
{"r", "repeat", "number of repetitions",
|
||||||
{args::param(r, "number")}},
|
{mrw::args::param(r, "number")}},
|
||||||
{"f", "flag",
|
{"f", "flag",
|
||||||
"check a flag; this is a boolean, so it is false by "
|
"check a flag; this is a boolean, so it is false by "
|
||||||
"default and true if the user specifies the flag on "
|
"default and true if the user specifies the flag on "
|
||||||
"the command line", {args::param(flag)}},
|
"the command line", {mrw::args::param(flag)}},
|
||||||
{"t", "text", "pass a text", {args::param(txt, "text")}},
|
{"t", "text", "pass a text",
|
||||||
|
{mrw::args::param(txt, "text")}},
|
||||||
{"c", "coord",
|
{"c", "coord",
|
||||||
"add some 2D coordinates; this is an example on how "
|
"add some 2D coordinates; this is an example on how "
|
||||||
"you can add more than one parameter",
|
"you can add more than one parameter",
|
||||||
{args::param(x, "x"), args::param(y, "y")}},
|
{mrw::args::param(x, "x"),
|
||||||
|
mrw::args::param(y, "y")}},
|
||||||
{"", "test", "call test_func, no shortcut",
|
{"", "test", "call test_func, no shortcut",
|
||||||
{args::func(test_func)}},
|
{mrw::args::func(test_func)}},
|
||||||
},
|
},
|
||||||
"Returns a status of 0 on success and 1 on any error.");
|
"Returns a status of 0 on success and 1 on any error.");
|
||||||
#endif
|
#endif
|
||||||
|
152
src/mrw/args
152
src/mrw/args
@@ -7,6 +7,8 @@
|
|||||||
#ifndef __ARGS__
|
#ifndef __ARGS__
|
||||||
#define __ARGS__
|
#define __ARGS__
|
||||||
|
|
||||||
|
#include <mrw/iomanip>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -15,10 +17,11 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <cstdlib>
|
#include <cstdlib> // exit()
|
||||||
|
|
||||||
// check if code is compiled with a new C++11 compiler
|
// check if code is compiled with a new C++11 compiler
|
||||||
// otherwise there is a fallback wich makes everything much more compliacted
|
// otherwise there is a fallback wich makes everything much more compliacted
|
||||||
|
#ifndef ARGS__OLD_PRE11_COMPILER
|
||||||
#if __cplusplus < 201103L
|
#if __cplusplus < 201103L
|
||||||
/// Code is compiled with an old non C++11 standard compliant compiler
|
/// Code is compiled with an old non C++11 standard compliant compiler
|
||||||
/** There are workarounds for old non C++11 compatible
|
/** There are workarounds for old non C++11 compatible
|
||||||
@@ -33,6 +36,13 @@
|
|||||||
#warning this is deprecated and will be removed in future releases
|
#warning this is deprecated and will be removed in future releases
|
||||||
#warning refere to the library documentation for more details
|
#warning refere to the library documentation for more details
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @page oldcompiler Workaround for old non C++11 compilers
|
||||||
|
... to be documented
|
||||||
|
@note Old compilers are automatically detected and the flag
|
||||||
|
@refs ARGS__OLD_PRE11_COMPILER is set.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
@@ -46,12 +56,7 @@ namespace std {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @page oldcompiler Workaround for old non C++11 compilers
|
namespace mrw {
|
||||||
... to be documented
|
|
||||||
@note Old compilers are automatically detected and the flag
|
|
||||||
@refs ARGS__OLD_PRE11_COMPILER is set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// Cool and easy evaluation of commandline arguments in C++11.
|
/// Cool and easy evaluation of commandline arguments in C++11.
|
||||||
/** Evaluating command line arguments is extremely easy with this library:
|
/** Evaluating command line arguments is extremely easy with this library:
|
||||||
@begincode
|
@begincode
|
||||||
@@ -66,14 +71,17 @@ namespace std {
|
|||||||
int x(0), y(0); // bound to option --coord
|
int x(0), y(0); // bound to option --coord
|
||||||
|
|
||||||
// bind and evaluate options
|
// bind and evaluate options
|
||||||
args::init(argc, argv, "This is an example for argument processing.", {
|
args::parse(argc, argv, "This is an example for argument processing.",
|
||||||
|
{
|
||||||
{"h", "help", "show this help", {args::help(), args::exit()}},
|
{"h", "help", "show this help", {args::help(), args::exit()}},
|
||||||
{"r", "repeat", "number of repetitions", {args::param(r, "number")}},
|
{"r", "repeat", "number of repetitions",
|
||||||
|
{args::param(r, "number")}},
|
||||||
{"f", "flag", "check a flag", {args::param(flag)}},
|
{"f", "flag", "check a flag", {args::param(flag)}},
|
||||||
{"t", "text", "pass a text", {args::param(txt, "text")}},
|
{"t", "text", "pass a text", {args::param(txt, "text")}},
|
||||||
{"c", "coord", "add some 2D coordinates", {args::param(x, "x"),
|
{"c", "coord", "add some 2D coordinates", {args::param(x, "x"),
|
||||||
args::param(y, "y")}},
|
args::param(y, "y")}},
|
||||||
{"", "test", "call test_func, no shortcut", {args::func(test_func)}},
|
{"", "test", "call test_func, no shortcut",
|
||||||
|
{args::func(test_func)}},
|
||||||
});
|
});
|
||||||
|
|
||||||
// [...] now the variables are setup according to the user's choice
|
// [...] now the variables are setup according to the user's choice
|
||||||
@@ -90,8 +98,7 @@ namespace std {
|
|||||||
non C++11 compliant compilers, so the use of a modern
|
non C++11 compliant compilers, so the use of a modern
|
||||||
compiler is strongly recommended. On GNU GCC, you may have
|
compiler is strongly recommended. On GNU GCC, you may have
|
||||||
to add the commandline option @c -std=c++11
|
to add the commandline option @c -std=c++11
|
||||||
@note I suggest to take this library into the next C++ standard.
|
@note I suggest to take this library into the next C++ standard. */
|
||||||
*/
|
|
||||||
namespace args {
|
namespace args {
|
||||||
/// Parent for holding a reference to a parameter variable.
|
/// Parent for holding a reference to a parameter variable.
|
||||||
/** This class ist used only as parent for instances of template
|
/** This class ist used only as parent for instances of template
|
||||||
@@ -143,7 +150,9 @@ namespace args {
|
|||||||
// special case: boolean has no parameter
|
// special case: boolean has no parameter
|
||||||
template<> class parameter<bool>: public abstract_parameter {
|
template<> class parameter<bool>: public abstract_parameter {
|
||||||
public:
|
public:
|
||||||
parameter(bool& ref, const std::string& = std::string()): _ref(ref=false) {}
|
parameter(bool& ref, const std::string& = std::string()):
|
||||||
|
_ref(ref=false) {
|
||||||
|
}
|
||||||
virtual void evaluate(char**&, char**) {
|
virtual void evaluate(char**&, char**) {
|
||||||
_ref = true;
|
_ref = true;
|
||||||
}
|
}
|
||||||
@@ -151,9 +160,11 @@ namespace args {
|
|||||||
bool& _ref;
|
bool& _ref;
|
||||||
};
|
};
|
||||||
// special case: string cannot easily be shifted
|
// special case: string cannot easily be shifted
|
||||||
template<typename T> class parameter<std::basic_string<T> >: public abstract_parameter {
|
template<typename T> class parameter<std::basic_string<T> >:
|
||||||
|
public abstract_parameter {
|
||||||
public:
|
public:
|
||||||
parameter(std::basic_string<T>& ref, const std::string& s = std::string()):
|
parameter(std::basic_string<T>& ref,
|
||||||
|
const std::string& s = std::string()):
|
||||||
_ref(ref), _type(s) {}
|
_ref(ref), _type(s) {}
|
||||||
virtual void evaluate(char**& a, char** max) {
|
virtual void evaluate(char**& a, char** max) {
|
||||||
if (max<a+1)
|
if (max<a+1)
|
||||||
@@ -178,7 +189,9 @@ namespace args {
|
|||||||
// special case: if a function is called
|
// special case: if a function is called
|
||||||
template<> class parameter<void(*)()>: public abstract_parameter {
|
template<> class parameter<void(*)()>: public abstract_parameter {
|
||||||
public:
|
public:
|
||||||
parameter(void(*ref)(), const std::string& = std::string()): _ref(ref) {}
|
parameter(void(*ref)(), const std::string& = std::string()):
|
||||||
|
_ref(ref) {
|
||||||
|
}
|
||||||
virtual void evaluate(char**&, char**) {
|
virtual void evaluate(char**&, char**) {
|
||||||
_ref();
|
_ref();
|
||||||
}
|
}
|
||||||
@@ -191,7 +204,7 @@ namespace args {
|
|||||||
return std::shared_ptr<abstract_parameter>(new args::parameter<T>(t, s));
|
return std::shared_ptr<abstract_parameter>(new args::parameter<T>(t, s));
|
||||||
}
|
}
|
||||||
struct declaration {
|
struct declaration {
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
declaration(std::string p1, std::string p2, std::string p3,
|
declaration(std::string p1, std::string p2, std::string p3,
|
||||||
std::vector<std::shared_ptr<abstract_parameter> > p4):
|
std::vector<std::shared_ptr<abstract_parameter> > p4):
|
||||||
short_arg(p1), long_arg(p2), desc(p3), params(p4) {
|
short_arg(p1), long_arg(p2), desc(p3), params(p4) {
|
||||||
@@ -215,22 +228,21 @@ namespace args {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
void match(const std::string& arg, char**& a, char** max) {
|
void match(const std::string& arg, char**& a, char** max) {
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
arg_map::iterator it(args().find(arg));
|
arg_map::iterator it(args().find(arg));
|
||||||
#else
|
#else
|
||||||
auto it(args().find(arg));
|
auto it(args().find(arg));
|
||||||
#endif
|
#endif
|
||||||
if (it==args().end())
|
if (it==args().end())
|
||||||
throw std::runtime_error("unknown argument: "+std::string(*a));
|
throw std::runtime_error("unknown argument: "+std::string(*a));
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
for (std::vector<std::shared_ptr<abstract_parameter> >::iterator
|
for (std::vector<std::shared_ptr<abstract_parameter> >::iterator
|
||||||
it2(it->second.begin()); it2!=it->second.end(); ++it2) {
|
it2(it->second.begin()); it2!=it->second.end(); ++it2)
|
||||||
#else
|
#else
|
||||||
for (auto it2(it->second.begin()); it2!=it->second.end(); ++it2) {
|
for (auto it2(it->second.begin()); it2!=it->second.end(); ++it2)
|
||||||
#endif
|
#endif
|
||||||
(*it2)->evaluate(a, max);
|
(*it2)->evaluate(a, max);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/// Filename as passed in argv[0].
|
/// Filename as passed in argv[0].
|
||||||
/** Used in the help display.
|
/** Used in the help display.
|
||||||
@note This function emulates a global variable using parts of a
|
@note This function emulates a global variable using parts of a
|
||||||
@@ -263,30 +275,32 @@ namespace args {
|
|||||||
used in @ref show_help
|
used in @ref show_help
|
||||||
@param l list of options and parameters to be parsed
|
@param l list of options and parameters to be parsed
|
||||||
@raram ret documentation of the return values of the program */
|
@raram ret documentation of the return values of the program */
|
||||||
static void init(int argc, char** argv, const std::string& desc, list l,
|
static void parse(int argc, char** argv, const std::string& desc, list l,
|
||||||
const std::string& ret = std::string()) {
|
const std::string& ret = std::string()) {
|
||||||
filename(argv[0]); // store filename for later use in help
|
filename(argv[0]); // store filename for later use in help
|
||||||
description(desc); // store program description for later use in help
|
description(desc); // store program description for later use in help
|
||||||
returns(ret); // store return values description for later use in help
|
returns(ret); // store return documentation for later use in help
|
||||||
arg_list() = l; // store options and parameters for later use in help
|
arg_list() = l; // store options and parameters for later use in help
|
||||||
// setup the argument mapping table
|
// setup the argument mapping table
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
for (list::iterator it(l.begin()); it!=l.end(); ++it) {
|
for (list::iterator it(l.begin()); it!=l.end(); ++it)
|
||||||
#else
|
#else
|
||||||
for (auto it(l.begin()); it!=l.end(); ++it) {
|
for (auto it(l.begin()); it!=l.end(); ++it)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
if (it->short_arg.size()==1) args()[it->short_arg] = it->params;
|
if (it->short_arg.size()==1) args()[it->short_arg] = it->params;
|
||||||
if (it->long_arg.size()) args()["--"+it->long_arg] = it->params;
|
if (it->long_arg.size()) args()["--"+it->long_arg] = it->params;
|
||||||
}
|
}
|
||||||
// parse commandline and evaluate the arguments
|
// parse commandline and evaluate the arguments
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
for (char** a(argv+1); a<argv+argc; ++a) {
|
for (char** a(argv+1); a<argv+argc; ++a)
|
||||||
#else
|
#else
|
||||||
for (auto a(argv+1); a<argv+argc; ++a) {
|
for (auto a(argv+1); a<argv+argc; ++a)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
std::string arg(*a);
|
std::string arg(*a);
|
||||||
if (arg.size()>1&&arg[0]=='-'&&arg[1]!='-') { // short argument
|
if (arg.size()>1&&arg[0]=='-'&&arg[1]!='-') { // short argument
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
for (std::string::iterator it(arg.begin()+1); it!=arg.end(); ++it)
|
for (std::string::iterator it(arg.begin()+1); it!=arg.end(); ++it)
|
||||||
#else
|
#else
|
||||||
for (auto it(arg.begin()+1); it!=arg.end(); ++it)
|
for (auto it(arg.begin()+1); it!=arg.end(); ++it)
|
||||||
@@ -297,72 +311,6 @@ namespace args {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//! 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)
|
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
|
||||||
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;
|
|
||||||
void show_help(const std::string& synopsis_txt="SYNOPSIS",
|
void show_help(const std::string& synopsis_txt="SYNOPSIS",
|
||||||
const std::string& description_txt="DESCRIPTION",
|
const std::string& description_txt="DESCRIPTION",
|
||||||
const std::string& options_txt="OPTIONS",
|
const std::string& options_txt="OPTIONS",
|
||||||
@@ -375,15 +323,16 @@ namespace args {
|
|||||||
<<split(max_line, indent)<<description(); //! @bug
|
<<split(max_line, indent)<<description(); //! @bug
|
||||||
std::cout<<std::endl<<std::endl
|
std::cout<<std::endl<<std::endl
|
||||||
<<options_txt<<std::endl;
|
<<options_txt<<std::endl;
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
for (list::iterator arg(arg_list().begin()); arg!=arg_list().end(); ++arg) {
|
for (list::iterator arg(arg_list().begin()); arg!=arg_list().end(); ++arg)
|
||||||
#else
|
#else
|
||||||
for (auto arg(arg_list().begin()); arg!=arg_list().end(); ++arg) {
|
for (auto arg(arg_list().begin()); arg!=arg_list().end(); ++arg)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
std::string o((arg->short_arg.size()?"-"+arg->short_arg:"")+
|
std::string o((arg->short_arg.size()?"-"+arg->short_arg:"")+
|
||||||
(arg->short_arg.size()&&arg->long_arg.size()?", ":"")+
|
(arg->short_arg.size()&&arg->long_arg.size()?", ":"")+
|
||||||
(arg->long_arg.size()?"--"+arg->long_arg:""));
|
(arg->long_arg.size()?"--"+arg->long_arg:""));
|
||||||
#ifndef ARGS__CPLUSPLUS11
|
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||||
std::string a;
|
std::string a;
|
||||||
for (std::vector<std::shared_ptr<abstract_parameter> >::iterator
|
for (std::vector<std::shared_ptr<abstract_parameter> >::iterator
|
||||||
p(arg->params.begin());
|
p(arg->params.begin());
|
||||||
@@ -435,4 +384,5 @@ namespace args {
|
|||||||
return func(args::do_exit);
|
return func(args::do_exit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
105
src/mrw/iomanip
Normal file
105
src/mrw/iomanip
Normal file
@@ -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
|
Reference in New Issue
Block a user