solve lvalue problem in container shift; refs #7
This commit is contained in:
133
ax_cxx_compile_stdcxx_11.m4
Normal file
133
ax_cxx_compile_stdcxx_11.m4
Normal file
@@ -0,0 +1,133 @@
|
||||
# ============================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
|
||||
# ============================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the C++11
|
||||
# standard; if necessary, add switches to CXXFLAGS to enable support.
|
||||
#
|
||||
# The first argument, if specified, indicates whether you insist on an
|
||||
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||
# -std=c++11). If neither is specified, you get whatever works, with
|
||||
# preference for an extended mode.
|
||||
#
|
||||
# The second argument, if specified 'mandatory' or if left unspecified,
|
||||
# indicates that baseline C++11 support is required and that the macro
|
||||
# should error out if no mode with that support is found. If specified
|
||||
# 'optional', then configuration proceeds regardless, after defining
|
||||
# HAVE_CXX11 if and only if a supporting mode is found.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 3
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
|
||||
template <typename T>
|
||||
struct check
|
||||
{
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};
|
||||
|
||||
typedef check<check<bool>> right_angle_brackets;
|
||||
|
||||
int a;
|
||||
decltype(a) b;
|
||||
|
||||
typedef check<int> check_type;
|
||||
check_type c;
|
||||
check_type&& cr = static_cast<check_type&&>(c);
|
||||
|
||||
auto d = a;
|
||||
])
|
||||
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
|
||||
m4_if([$1], [], [],
|
||||
[$1], [ext], [],
|
||||
[$1], [noext], [],
|
||||
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
|
||||
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
|
||||
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
|
||||
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
|
||||
ax_cv_cxx_compile_cxx11,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[ax_cv_cxx_compile_cxx11=yes],
|
||||
[ax_cv_cxx_compile_cxx11=no])])
|
||||
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
|
||||
ac_success=yes
|
||||
fi
|
||||
|
||||
m4_if([$1], [noext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for switch in -std=gnu++11 -std=gnu++0x; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
|
||||
m4_if([$1], [ext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for switch in -std=c++11 -std=c++0x; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
AC_LANG_POP([C++])
|
||||
if test x$ax_cxx_compile_cxx11_required = xtrue; then
|
||||
if test x$ac_success = xno; then
|
||||
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
|
||||
fi
|
||||
else
|
||||
if test x$ac_success = xno; then
|
||||
HAVE_CXX11=0
|
||||
AC_MSG_NOTICE([No compiler with C++11 support was found])
|
||||
else
|
||||
HAVE_CXX11=1
|
||||
AC_DEFINE(HAVE_CXX11,1,
|
||||
[define if the compiler supports basic C++11 syntax])
|
||||
fi
|
||||
|
||||
AC_SUBST(HAVE_CXX11)
|
||||
fi
|
||||
])
|
@@ -1,4 +1,5 @@
|
||||
# $Id$
|
||||
m4_include(ax_cxx_compile_stdcxx_11.m4)
|
||||
AC_ALIAS([AC_DEFINE_DIR], [AX_DEFINE_DIR])
|
||||
AC_DEFUN([AX_DEFINE_DIR], [
|
||||
prefix_NONE=
|
||||
@@ -83,6 +84,7 @@ CXXFLAGS="${CXXFLAGS:-}"
|
||||
|
||||
# languages
|
||||
AC_LANG(C++)
|
||||
AX_CXX_COMPILE_STDCXX_11(noext, optional)
|
||||
|
||||
# programs
|
||||
AC_PROG_CXX
|
||||
|
@@ -6,6 +6,9 @@
|
||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
||||
#include <mrw/args.hxx>
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
#include <mrw/vector.hxx>
|
||||
#endif
|
||||
|
||||
void test_func() {
|
||||
std::cout<<"test parameter was given on command line"<<std::endl;
|
||||
@@ -19,48 +22,46 @@ int main(int argc, char** argv) try {
|
||||
std::string txt("Hello World");
|
||||
int x(0), y(0);
|
||||
|
||||
std::string description("This is an example for argument processing. If the "
|
||||
"description is very long, it is automatically "
|
||||
"splitted over several lines and indented on each "
|
||||
"new line. Arguments may have several parameters. "
|
||||
"Help is generated automatically from the argument "
|
||||
"declaration. The argument declaration contains long "
|
||||
"and short options and a list of parameters.");
|
||||
std::string returns("Returns a status of 0 on success and 1 on any error.");
|
||||
|
||||
// bind and evaluate options
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
mrw::args::list options;
|
||||
std::vector<std::shared_ptr<mrw::args::abstract_parameter> > params;
|
||||
params.push_back(mrw::args::help());
|
||||
params.push_back(mrw::args::exit());
|
||||
options.push_back(mrw::args::declaration("h", "help", "show this help",
|
||||
params));
|
||||
params.clear();
|
||||
params.push_back(mrw::args::param(r, "number"));
|
||||
options.push_back(mrw::args::declaration("r", "repeat",
|
||||
"number of repetitions",
|
||||
params));
|
||||
params.clear();
|
||||
params.push_back(mrw::args::param(flag));
|
||||
options.push_back(mrw::args::declaration("f", "flag", "check a flag",
|
||||
params));
|
||||
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);
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
mrw::args::list l;
|
||||
mrw::args::decl::param_list pl = mrw::args::decl::param_list();
|
||||
(mrw::args::decl::param_list())<<mrw::args::param(flag);
|
||||
l<<mrw::args::decl("f", "flag", "check a flag", pl);
|
||||
mrw::args::parse(argc, argv, description, mrw::args::list()
|
||||
<<mrw::args::decl("h", "help", "show this help",
|
||||
mrw::args::decl::param_list()
|
||||
<<mrw::args::help()
|
||||
<<mrw::args::exit())
|
||||
<<mrw::args::decl("r", "repeat", "number of repetitions",
|
||||
mrw::args::decl::param_list()
|
||||
<<mrw::args::param(r, "number"))
|
||||
<<mrw::args::decl("f", "flag", "check a flag",
|
||||
mrw::args::decl::param_list()
|
||||
<<mrw::args::param(flag))
|
||||
<<mrw::args::decl("t", "text", "pass a text",
|
||||
mrw::args::decl::param_list()
|
||||
<<mrw::args::param(txt, "text"))
|
||||
<<mrw::args::decl("c", "coord", "add some 2D coordinates",
|
||||
mrw::args::decl::param_list()
|
||||
<<mrw::args::param(x, "x")
|
||||
<<mrw::args::param(y, "y"))
|
||||
<<mrw::args::decl("", "test", "call test_func, no shortcut",
|
||||
mrw::args::decl::param_list()
|
||||
<<mrw::args::func(test_func)),
|
||||
returns);
|
||||
#else
|
||||
mrw::args::parse(argc, argv,
|
||||
"This is an example for argument processing. If the"
|
||||
" description is very long, it is automatically splitted"
|
||||
" over several lines and indented on each new line."
|
||||
" Arguments may have several parameters. Help is"
|
||||
" generated automatically from the argument declaration."
|
||||
" The argument declaration contains long and short options"
|
||||
" and a list of parameters.",
|
||||
description,
|
||||
{
|
||||
{"h", "help", "show this help",
|
||||
{mrw::args::help(), mrw::args::exit()}},
|
||||
@@ -80,7 +81,7 @@ int main(int argc, char** argv) try {
|
||||
{"", "test", "call test_func, no shortcut",
|
||||
{mrw::args::func(test_func)}},
|
||||
},
|
||||
"Returns a status of 0 on success and 1 on any error.");
|
||||
returns);
|
||||
#endif
|
||||
|
||||
// show the result
|
||||
|
@@ -57,7 +57,7 @@ distclean-local:
|
||||
- rm -r ${top_builddir}/@DOC_DIR@/html/* ${top_builddir}/@DOC_DIR@/latex/*
|
||||
- rm makefile makefile.in doxygen.err libmrw.doxytag
|
||||
- find . -name '*~' | xargs rm
|
||||
- rm -r autom4te.cache
|
||||
- rm -r autom4te.cache SPECS RPMS BUILD BUILDROOT SRPMS
|
||||
- rm aclocal.m4 config.guess config.sub configure \
|
||||
depcomp install-sh ltmain.sh makefile makefile.in \
|
||||
missing mkinstalldirs SPECS RPMS BUILD BUILDROOT SRPMS
|
||||
missing mkinstalldirs
|
||||
|
@@ -14,7 +14,8 @@ nobase_include_HEADERS = mrw/arg.hxx mrw/auto.hxx mrw/configfile.hxx \
|
||||
mrw/smartpointer.hxx mrw/stacktrace.hxx \
|
||||
mrw/stdext.hxx mrw/string.hxx \
|
||||
mrw/tokenizer.hxx mrw/unistd.hxx \
|
||||
mrw/vector.hxx mrw/args.hxx mrw/iomanip.hxx
|
||||
mrw/vector.hxx mrw/args.hxx mrw/iomanip.hxx \
|
||||
mrw/checkcxx11.hxx
|
||||
|
||||
if HAVE_STACKTRACE
|
||||
AM_CPPFLAGS += -DHAVE_STACKTRACE
|
||||
|
104
src/mrw/args.hxx
104
src/mrw/args.hxx
@@ -4,9 +4,10 @@
|
||||
*/
|
||||
// 1 2 3 4 5 6 7 8
|
||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
#ifndef __ARGS__
|
||||
#define __ARGS__
|
||||
#ifndef __MRW__
|
||||
#define __MRW__
|
||||
|
||||
#include <mrw/checkcxx11.hxx>
|
||||
#include <mrw/iomanip.hxx>
|
||||
|
||||
#include <vector>
|
||||
@@ -19,43 +20,12 @@
|
||||
#include <numeric>
|
||||
#include <cstdlib> // exit()
|
||||
|
||||
// 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
|
||||
|
||||
/** @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.
|
||||
@refs MRW__OLD_PRE11_COMPILER is set.
|
||||
*/
|
||||
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
#include <boost/shared_ptr.hpp>
|
||||
namespace std {
|
||||
// there is no std::shared_ptr in pre C++11 compilers, so we use the
|
||||
// one from the boost library as a 1:1 replacement
|
||||
template <typename T> class shared_ptr: public boost::shared_ptr<T> {
|
||||
public:
|
||||
explicit shared_ptr(T* p): boost::shared_ptr<T>(p) {}
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace mrw {
|
||||
/// Cool and easy evaluation of commandline arguments in C++11.
|
||||
/** Evaluating command line arguments is extremely easy with this library:
|
||||
@@ -198,46 +168,44 @@ namespace mrw {
|
||||
private:
|
||||
void(*_ref)();
|
||||
};
|
||||
typedef std::shared_ptr<abstract_parameter> param_ptr;
|
||||
template<typename T>
|
||||
std::shared_ptr<abstract_parameter> param
|
||||
(T& t, const std::string& s = std::string()) {
|
||||
return std::shared_ptr<abstract_parameter>(new args::parameter<T>(t, s));
|
||||
param_ptr param(T& t, const std::string& s = std::string()) {
|
||||
return param_ptr(new args::parameter<T>(t, s));
|
||||
}
|
||||
struct declaration {
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
declaration(std::string p1, std::string p2, std::string p3,
|
||||
std::vector<std::shared_ptr<abstract_parameter> > p4):
|
||||
struct decl {
|
||||
typedef std::vector<param_ptr> param_list;
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
decl(std::string p1, std::string p2, std::string p3, param_list p4):
|
||||
short_arg(p1), long_arg(p2), desc(p3), params(p4) {
|
||||
}
|
||||
#endif
|
||||
std::string short_arg;
|
||||
std::string long_arg;
|
||||
std::string desc;
|
||||
std::vector<std::shared_ptr<abstract_parameter> > params;
|
||||
param_list params;
|
||||
};
|
||||
typedef std::map<std::string,
|
||||
std::vector<std::shared_ptr<abstract_parameter> > >
|
||||
arg_map;
|
||||
typedef std::map<std::string, decl::param_list> arg_map;
|
||||
static arg_map& args() {
|
||||
static arg_map a;
|
||||
return a;
|
||||
}
|
||||
typedef std::vector<declaration> list;
|
||||
typedef std::vector<decl> list;
|
||||
static list& arg_list() {
|
||||
static list a;
|
||||
return a;
|
||||
}
|
||||
void match(const std::string& arg, char**& a, char** max) {
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
arg_map::iterator it(args().find(arg));
|
||||
#else
|
||||
auto it(args().find(arg));
|
||||
#endif
|
||||
if (it==args().end())
|
||||
throw std::runtime_error("unknown argument: "+std::string(*a));
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
for (std::vector<std::shared_ptr<abstract_parameter> >::iterator
|
||||
it2(it->second.begin()); it2!=it->second.end(); ++it2)
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
for (decl::param_list::iterator it2(it->second.begin());
|
||||
it2!=it->second.end(); ++it2)
|
||||
#else
|
||||
for (auto it2(it->second.begin()); it2!=it->second.end(); ++it2)
|
||||
#endif
|
||||
@@ -282,7 +250,7 @@ namespace mrw {
|
||||
returns(ret); // store return documentation for later use in help
|
||||
arg_list() = l; // store options and parameters for later use in help
|
||||
// setup the argument mapping table
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
for (list::iterator it(l.begin()); it!=l.end(); ++it)
|
||||
#else
|
||||
for (auto it(l.begin()); it!=l.end(); ++it)
|
||||
@@ -292,7 +260,7 @@ namespace mrw {
|
||||
if (it->long_arg.size()) args()["--"+it->long_arg] = it->params;
|
||||
}
|
||||
// parse commandline and evaluate the arguments
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
for (char** a(argv+1); a<argv+argc; ++a)
|
||||
#else
|
||||
for (auto a(argv+1); a<argv+argc; ++a)
|
||||
@@ -300,7 +268,7 @@ namespace mrw {
|
||||
{
|
||||
std::string arg(*a);
|
||||
if (arg.size()>1&&arg[0]=='-'&&arg[1]!='-') { // short argument
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
for (std::string::iterator it(arg.begin()+1); it!=arg.end(); ++it)
|
||||
#else
|
||||
for (auto it(arg.begin()+1); it!=arg.end(); ++it)
|
||||
@@ -320,10 +288,10 @@ namespace mrw {
|
||||
std::cout<<synopsis_txt<<std::endl<<std::endl
|
||||
<<" "<<filename()<<" ["<<options_txt<<"]"<<std::endl<<std::endl
|
||||
<<description_txt<<std::endl<<std::endl
|
||||
<<split(max_line, indent)<<description(); //! @bug
|
||||
<<ssplit(max_line, indent)<<description(); //! @bug
|
||||
std::cout<<std::endl<<std::endl
|
||||
<<options_txt<<std::endl;
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
for (list::iterator arg(arg_list().begin()); arg!=arg_list().end(); ++arg)
|
||||
#else
|
||||
for (auto arg(arg_list().begin()); arg!=arg_list().end(); ++arg)
|
||||
@@ -332,10 +300,9 @@ namespace mrw {
|
||||
std::string o((arg->short_arg.size()?"-"+arg->short_arg:"")+
|
||||
(arg->short_arg.size()&&arg->long_arg.size()?", ":"")+
|
||||
(arg->long_arg.size()?"--"+arg->long_arg:""));
|
||||
#ifdef ARGS__OLD_PRE11_COMPILER
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
std::string a;
|
||||
for (std::vector<std::shared_ptr<abstract_parameter> >::iterator
|
||||
p(arg->params.begin());
|
||||
for (decl::param_list::iterator p(arg->params.begin());
|
||||
p!=arg->params.end(); ++p) {
|
||||
std::string def(**p);
|
||||
a+=(*p)->type()+(def.size()?"="+def:"");
|
||||
@@ -344,17 +311,18 @@ namespace mrw {
|
||||
std::string a(std::accumulate(arg->params.begin(), arg->params.end(),
|
||||
std::string(),
|
||||
[](const std::string& s,
|
||||
std::shared_ptr<abstract_parameter> p)
|
||||
param_ptr p)
|
||||
-> std::string {
|
||||
std::string def(**p);
|
||||
return s+p->type()+(def.size()?"="+def:"");
|
||||
std::string def(*p);
|
||||
return
|
||||
s+p->type()+(def.size()?"="+def:"");
|
||||
}));
|
||||
#endif
|
||||
std::cout<<std::endl<<" "
|
||||
<<o<<std::setw(option_len-o.size())<<' '
|
||||
<<a;
|
||||
if (arg->desc.size()>max_line-indent-option_len-param_len)
|
||||
std::cout<<std::endl<<std::endl<<split(max_line, long_indent)
|
||||
std::cout<<std::endl<<std::endl<<ssplit(max_line, long_indent)
|
||||
<<arg->desc;
|
||||
else
|
||||
std::cout<<std::setw(param_len-a.size())<<' '<<arg->desc;
|
||||
@@ -362,7 +330,7 @@ namespace mrw {
|
||||
}
|
||||
if (returns().size()) {
|
||||
std::cout<<std::endl<<returns_txt<<std::endl<<std::endl
|
||||
<<split(max_line, indent)<<returns();
|
||||
<<ssplit(max_line, indent)<<returns();
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
}
|
||||
@@ -372,15 +340,13 @@ namespace mrw {
|
||||
void do_exit() {
|
||||
exit(1);
|
||||
}
|
||||
std::shared_ptr<args::abstract_parameter> func(void(*fn)()) {
|
||||
return
|
||||
std::shared_ptr<args::abstract_parameter>
|
||||
(new args::parameter<void(*)()>(fn));
|
||||
param_ptr func(void(*fn)()) {
|
||||
return param_ptr(new args::parameter<void(*)()>(fn));
|
||||
}
|
||||
std::shared_ptr<args::abstract_parameter> help() {
|
||||
param_ptr help() {
|
||||
return func(args::help_no_arg);
|
||||
}
|
||||
std::shared_ptr<args::abstract_parameter> exit() {
|
||||
param_ptr exit() {
|
||||
return func(args::do_exit);
|
||||
}
|
||||
}
|
||||
|
42
src/mrw/checkcxx11.hxx
Normal file
42
src/mrw/checkcxx11.hxx
Normal file
@@ -0,0 +1,42 @@
|
||||
/*! @file
|
||||
|
||||
@id $Id$
|
||||
*/
|
||||
// 1 2 3 4 5 6 7 8
|
||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
||||
#ifndef __MRW__CHECKCXX11__
|
||||
#define __MRW__CHECKCXX11__
|
||||
|
||||
// check if code is compiled with a new C++11 compiler
|
||||
// otherwise there is a fallback wich makes everything much more compliacted
|
||||
# ifndef MRW__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. */
|
||||
# define MRW__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
|
||||
|
||||
|
||||
# ifdef MRW__OLD_PRE11_COMPILER
|
||||
# include <boost/shared_ptr.hpp>
|
||||
namespace std {
|
||||
// there is no std::shared_ptr in pre C++11 compilers, so we use the
|
||||
// one from the boost library as a 1:1 replacement
|
||||
template <typename T> class shared_ptr: public boost::shared_ptr<T> {
|
||||
public:
|
||||
explicit shared_ptr(T* p): boost::shared_ptr<T>(p) {}
|
||||
};
|
||||
};
|
||||
# endif
|
||||
|
||||
#endif
|
@@ -27,6 +27,7 @@
|
||||
#define __MRW__DEQUE__HPP__
|
||||
|
||||
#include <deque>
|
||||
#include <mrw/checkcxx11.hxx>
|
||||
#include <mrw/exception.hxx>
|
||||
#include <mrw/string.hxx>
|
||||
|
||||
@@ -48,11 +49,21 @@
|
||||
@param o a value to be inserted into deque @c l
|
||||
@pre \#include <mrw/deque.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename T, typename A>
|
||||
std::deque<T, A>& operator<<(std::deque<T, A>& l, const T& o) throw(std::bad_exception) {
|
||||
std::deque<T, A> operator<<(std::deque<T, A> l, const T& o)
|
||||
throw(std::bad_exception) {
|
||||
l.push_back(o);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename T, typename A>
|
||||
std::deque<T, A>&& operator<<(std::deque<T, A>&& l, const T& o)
|
||||
throw(std::bad_exception) {
|
||||
l.push_back(o);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief extract the first value of a deque
|
||||
|
||||
@@ -72,8 +83,10 @@ std::deque<T, A>& operator<<(std::deque<T, A>& l, const T& o) throw(std::bad_exc
|
||||
shortened by the shifted element
|
||||
@pre \#include <mrw/deque.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename T, typename A>
|
||||
std::deque<T, A>& operator>>(std::deque<T, A>& l, T& o) throw(std::exception) {
|
||||
std::deque<T, A> operator>>(std::deque<T, A> l, T& o)
|
||||
throw(std::exception) {
|
||||
typename std::deque<T, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
@@ -83,6 +96,20 @@ std::deque<T, A>& operator>>(std::deque<T, A>& l, T& o) throw(std::exception) {
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename T, typename A>
|
||||
std::deque<T, A>&& operator>>(std::deque<T, A>&& l, T& o)
|
||||
throw(std::exception) {
|
||||
typename std::deque<T, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::deque<>& operator>>(std::deque<>&, T&),"
|
||||
" deque is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
//@}
|
||||
//@}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
|
||||
// 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
|
||||
#ifndef MRW__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
|
||||
@@ -24,7 +24,7 @@
|
||||
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
|
||||
#define MRW__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
|
||||
@@ -41,7 +41,7 @@ namespace mrw {
|
||||
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
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
throw std::runtime_error(((std::stringstream&)
|
||||
(std::stringstream()
|
||||
<<"wrong use of split: width is "<<_width
|
||||
@@ -100,6 +100,6 @@ namespace mrw {
|
||||
std::stringstream _buffer;
|
||||
std::basic_ostream<_CharT, _Traits>* _os;
|
||||
};
|
||||
typedef basic_split<char> split;
|
||||
typedef basic_split<char> ssplit;
|
||||
}
|
||||
#endif
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#define __MRW__MAP__HPP__
|
||||
|
||||
#include <map>
|
||||
#include <mrw/checkcxx11.hxx>
|
||||
#include <mrw/exception.hxx>
|
||||
#include <mrw/string.hxx>
|
||||
|
||||
@@ -50,8 +51,10 @@
|
||||
@param o a value to be inserted into map @c l
|
||||
@pre \#include <mrw/map.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename K, typename T, class C, typename A>
|
||||
std::map<K, T, C, A>& operator<<(std::map<K, T, C, A>& l, const std::pair<K, T>& o)
|
||||
std::map<K, T, C, A> operator<<(std::map<K, T, C, A> l,
|
||||
const std::pair<K, T>& o)
|
||||
throw(std::exception) {
|
||||
if (!l.insert(o).second)
|
||||
throw mrw::invalid_argument(std::string(__FILE__ ":")+__LINE__+
|
||||
@@ -60,6 +63,19 @@ std::map<K, T, C, A>& operator<<(std::map<K, T, C, A>& l, const std::pair<K, T>&
|
||||
"map element already exists");
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename K, typename T, class C, typename A>
|
||||
std::map<K, T, C, A>&& operator<<(std::map<K, T, C, A>&& l,
|
||||
const std::pair<K, T>& o)
|
||||
throw(std::exception) {
|
||||
if (!l.insert(o).second)
|
||||
throw mrw::invalid_argument(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::map<>&"
|
||||
" operator<<(std::map<>&, const T&),"
|
||||
"map element already exists");
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief extract the first value of a map
|
||||
|
||||
@@ -80,8 +96,9 @@ std::map<K, T, C, A>& operator<<(std::map<K, T, C, A>& l, const std::pair<K, T>&
|
||||
shortened by the shifted element
|
||||
@pre \#include <mrw/map.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename K, typename T, class C, typename A>
|
||||
std::map<K, T, C, A>& operator>>(std::map<K, T, C, A>& l, std::pair<K, T>& o)
|
||||
std::map<K, T, C, A> operator>>(std::map<K, T, C, A> l, std::pair<K, T>& o)
|
||||
throw(std::exception) {
|
||||
typename std::map<K, T, C, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
@@ -92,6 +109,21 @@ std::map<K, T, C, A>& operator>>(std::map<K, T, C, A>& l, std::pair<K, T>& o)
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename K, typename T, class C, typename A>
|
||||
std::map<K, T, C, A>&& operator>>(std::map<K, T, C, A>&& l,
|
||||
std::pair<K, T>& o)
|
||||
throw(std::exception) {
|
||||
typename std::map<K, T, C, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::map<>& operator>>(std::map<>&, T&),"
|
||||
" map is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
//@}
|
||||
//@}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#define __MRW__MULTIMAP__HPP__
|
||||
|
||||
#include <map>
|
||||
#include <mrw/checkcxx11.hxx>
|
||||
#include <mrw/exception.hxx>
|
||||
#include <mrw/string.hxx>
|
||||
|
||||
@@ -50,12 +51,23 @@
|
||||
@param o a value to be inserted into multimap @c l
|
||||
@pre \#include <mrw/multimap.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename K, typename T, class C, typename A>
|
||||
std::multimap<K, T, C, A>& operator<<(std::multimap<K, T, C, A>& l, const std::pair<K, T>& o)
|
||||
std::multimap<K, T, C, A> operator<<(std::multimap<K, T, C, A> l,
|
||||
const std::pair<K, T>& o)
|
||||
throw(std::bad_exception) {
|
||||
l.insert(o);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename K, typename T, class C, typename A>&&
|
||||
std::multimap<K, T, C, A> operator<<(std::multimap<K, T, C, A>&& l,
|
||||
const std::pair<K, T>& o)
|
||||
throw(std::bad_exception) {
|
||||
l.insert(o);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief extract the first value of a multimap
|
||||
|
||||
@@ -76,18 +88,35 @@ std::multimap<K, T, C, A>& operator<<(std::multimap<K, T, C, A>& l, const std::p
|
||||
shortened by the shifted element
|
||||
@pre \#include <mrw/multimap.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename K, typename T, class C, typename A>
|
||||
std::multimap<K, T, C, A>& operator>>(std::multimap<K, T, C, A>& l, std::pair<K, T>& o)
|
||||
std::multimap<K, T, C, A> operator>>(std::multimap<K, T, C, A> l,
|
||||
std::pair<K, T>& o)
|
||||
throw(std::exception) {
|
||||
typename std::multimap<K, T, C, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::multimap<>& operator>>(std::multimap<>&, T&),"
|
||||
": std::multimap<>::operator>>,"
|
||||
" multimap is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename K, typename T, class C, typename A>
|
||||
std::multimap<K, T, C, A>&& operator>>(std::multimap<K, T, C, A>&& l,
|
||||
std::pair<K, T>& o)
|
||||
throw(std::exception) {
|
||||
typename std::multimap<K, T, C, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::multimap<>::operator>>,"
|
||||
" multimap is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
//@}
|
||||
//@}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#define __MRW__MULTISET__HPP__
|
||||
|
||||
#include <set>
|
||||
#include <mrw/checkcxx11.hxx>
|
||||
#include <mrw/exception.hxx>
|
||||
#include <mrw/string.hxx>
|
||||
|
||||
@@ -48,11 +49,21 @@
|
||||
@param o a value to be inserted into multiset @c l
|
||||
@pre \#include <mrw/multiset.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename T, class C, typename A>
|
||||
std::multiset<T, C, A>& operator<<(std::multiset<T, C, A>& l, const T& o) throw(std::bad_exception) {
|
||||
std::multiset<T, C, A> operator<<(std::multiset<T, C, A> l, const T& o)
|
||||
throw(std::bad_exception) {
|
||||
l.insert(o);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename T, class C, typename A>
|
||||
std::multiset<T, C, A>&& operator<<(std::multiset<T, C, A>&& l, const T& o)
|
||||
throw(std::bad_exception) {
|
||||
l.insert(o);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief extract the first value of a multiset
|
||||
|
||||
@@ -72,17 +83,33 @@ std::multiset<T, C, A>& operator<<(std::multiset<T, C, A>& l, const T& o) throw(
|
||||
shortened by the shifted element
|
||||
@pre \#include <mrw/multiset.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename T, class C, typename A>
|
||||
std::multiset<T, C, A>& operator>>(std::multiset<T, C, A>& l, T& o) throw(std::exception) {
|
||||
std::multiset<T, C, A> operator>>(std::multiset<T, C, A> l, T& o)
|
||||
throw(std::exception) {
|
||||
typename std::multiset<T, C, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::multiset<>& operator>>(std::multiset<>&, T&),"
|
||||
": std::multiset<> operator>>,"
|
||||
" multiset is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename T, class C, typename A>
|
||||
std::multiset<T, C, A>&& operator>>(std::multiset<T, C, A>&& l, T& o)
|
||||
throw(std::exception) {
|
||||
typename std::multiset<T, C, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::multiset<> operator>>,"
|
||||
" multiset is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
//@}
|
||||
//@}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#define __MRW__SET__HPP__
|
||||
|
||||
#include <set>
|
||||
#include <mrw/checkcxx11.hxx>
|
||||
#include <mrw/exception.hxx>
|
||||
#include <mrw/string.hxx>
|
||||
|
||||
@@ -49,16 +50,27 @@
|
||||
@param o a value to be inserted into set @c l
|
||||
@pre \#include <mrw/set.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename T, class C, typename A>
|
||||
std::set<T, C, A>& operator<<(std::set<T, C, A>& l, const T& o)
|
||||
std::set<T, C, A> operator<<(std::set<T, C, A> l, const T& o)
|
||||
throw(std::exception) {
|
||||
if (!l.insert(o).second)
|
||||
throw mrw::invalid_argument(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::set<>&"
|
||||
" operator<<(std::set<>&, const T&),"
|
||||
": std::set<>::operator<<, "
|
||||
"set element already exists");
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename T, class C, typename A>
|
||||
std::set<T, C, A>&& operator<<(std::set<T, C, A>&& l, const T& o)
|
||||
throw(std::exception) {
|
||||
if (!l.insert(o).second)
|
||||
throw mrw::invalid_argument(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::set<> operator<<, "
|
||||
"set element already exists");
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief extract the first value of a set
|
||||
|
||||
@@ -78,18 +90,33 @@ std::set<T, C, A>& operator<<(std::set<T, C, A>& l, const T& o)
|
||||
shortened by the shifted element
|
||||
@pre \#include <mrw/set.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename T, class C, typename A>
|
||||
std::set<T, C, A>& operator>>(std::set<T, C, A>& l, T& o)
|
||||
std::set<T, C, A> operator>>(std::set<T, C, A> l, T& o)
|
||||
throw(std::exception) {
|
||||
typename std::set<T, C, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::set<>& operator>>(std::set<>&, T&),"
|
||||
": std::set<> operator>>,"
|
||||
" set is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename T, class C, typename A>
|
||||
std::set<T, C, A> operator>>(std::set<T, C, A> l, T& o)
|
||||
throw(std::exception) {
|
||||
typename std::set<T, C, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::set<> operator>>,"
|
||||
" set is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
//@}
|
||||
//@}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#define __MRW__VECTOR__HPP__
|
||||
|
||||
#include <vector>
|
||||
#include <mrw/checkcxx11.hxx>
|
||||
#include <mrw/exception.hxx>
|
||||
#include <mrw/string.hxx>
|
||||
|
||||
@@ -48,11 +49,21 @@
|
||||
@param o a value to be inserted into vector @c l
|
||||
@pre \#include <mrw/vector.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename T, typename A>
|
||||
std::vector<T, A>& operator<<(std::vector<T, A>& l, const T& o) throw(std::bad_exception) {
|
||||
std::vector<T, A> operator<<(std::vector<T, A> l, const T& o)
|
||||
throw(std::bad_exception) {
|
||||
l.push_back(o);
|
||||
return l;
|
||||
}
|
||||
#else
|
||||
template <typename T, typename A>
|
||||
std::vector<T, A>&& operator<<(std::vector<T, A>&& l, const T& o)
|
||||
throw(std::bad_exception) {
|
||||
l.push_back(o);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief extract the first value of a vector
|
||||
|
||||
@@ -72,8 +83,10 @@ std::vector<T, A>& operator<<(std::vector<T, A>& l, const T& o) throw(std::bad_e
|
||||
shortened by the shifted element
|
||||
@pre \#include <mrw/vector.hxx>
|
||||
*/
|
||||
#ifdef MRW__OLD_PRE11_COMPILER
|
||||
template <typename T, typename A>
|
||||
std::vector<T, A>& operator>>(std::vector<T, A>& l, T& o) throw(std::exception) {
|
||||
std::vector<T, A> operator>>(std::vector<T, A> l, T& o)
|
||||
throw(std::exception) {
|
||||
typename std::vector<T, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
@@ -83,7 +96,20 @@ std::vector<T, A>& operator>>(std::vector<T, A>& l, T& o) throw(std::exception)
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
|
||||
#else
|
||||
template <typename T, typename A>
|
||||
std::vector<T, A>&& operator>>(std::vector<T, A>&& l, T& o)
|
||||
throw(std::exception) {
|
||||
typename std::vector<T, A>::iterator it(l.begin());
|
||||
if (it==l.end())
|
||||
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
|
||||
": std::vector<>& operator>>(std::vector<>&, T&),"
|
||||
" vector is empty");
|
||||
o = *it;
|
||||
l.erase(it);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
//@}
|
||||
//@}
|
||||
|
||||
|
Reference in New Issue
Block a user