solve lvalue problem in container shift; refs #7

This commit is contained in:
Marc Wäckerlin
2013-09-27 10:53:03 +00:00
parent 2763136313
commit 73ae395147
14 changed files with 452 additions and 139 deletions

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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
//@}
//@}

View File

@@ -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

View File

@@ -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,9 +96,10 @@ 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)
throw(std::exception) {
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__+
@@ -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
//@}
//@}

View File

@@ -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)
throw(std::bad_exception) {
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)
throw(std::exception) {
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
//@}
//@}

View File

@@ -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
//@}
//@}

View File

@@ -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)
throw(std::exception) {
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)
throw(std::exception) {
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
//@}
//@}

View File

@@ -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
//@}
//@}