new feature

master
Marc Wäckerlin 20 years ago
parent bea4847b13
commit ef00668649
  1. 77
      mrw/deque.hpp
  2. 77
      mrw/list.hpp
  3. 86
      mrw/map.hpp
  4. 82
      mrw/multimap.hpp
  5. 77
      mrw/multiset.hpp
  6. 84
      mrw/set.hpp
  7. 257
      mrw/stdext_test.cpp
  8. 450
      mrw/string.hpp
  9. 77
      mrw/vector.hpp

@ -0,0 +1,77 @@
/** @file
$Id$
$Date$
$Author$
@copy © Marc Wäckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#ifndef __MRW__DEQUE__HPP__
#define __MRW__DEQUE__HPP__
#include <deque>
#include <mrw/exception.hpp>
#include <mrw/string.hpp>
/** @addtogroup StdExt
*/
//@{
/** @brief push a value to a deque
@code
std::deque<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
@endcode
@param l a deque of values
@param o a value to be inserted into deque @c l
@pre #include <mrw/deque.hpp>
*/
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;
}
/** @brief extract the first value of a deque
@code
std::deque<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
int i1(0), i2(0), i3(0), i4(0);
test>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 test=={5, 6, 7, 8}
@endcode
@param l a deque of values
@param o a value to be extracted from deque @c l
@throw mrw::length_error, if deque was empty on entry
@note when something is extracted from a deque, it is removed
from the deque, that means after every shift the deque is
shortened by the shifted element
@pre #include <mrw/string.hpp>
*/
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

@ -0,0 +1,77 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#ifndef __MRW__LIST__HPP__
#define __MRW__LIST__HPP__
#include <list>
#include <mrw/exception.hpp>
#include <mrw/string.hpp>
/** @addtogroup StdExt
*/
//@{
/** @brief push a value to a list
@code
std::list<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
@endcode
@param l a list of values
@param o a value to be inserted into list @c l
@pre #include <mrw/list.hpp>
*/
template <typename T, typename A>
std::list<T, A>& operator<<(std::list<T, A>& l, const T& o) throw(std::bad_exception) {
l.push_back(o);
return l;
}
/** @brief extract the first value of a list
@code
std::list<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
int i1(0), i2(0), i3(0), i4(0);
test>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 test=={5, 6, 7, 8}
@endcode
@param l a list of values
@param o a value to be extracted from list @c l
@throw mrw::length_error, if list was empty on entry
@note when something is extracted from a list, it is removed
from the list, that means after every shift the list is
shortened by the shifted element
@pre #include <mrw/string.hpp>
*/
template <typename T, typename A>
std::list<T, A>& operator>>(std::list<T, A>& l, T& o) throw(std::exception) {
typename std::list<T, A>::iterator it(l.begin());
if (it==l.end())
throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
": std::list<>& operator>>(std::list<>&, T&),"
" list is empty");
o = *it;
l.erase(it);
return l;
}
//@}
#endif

@ -0,0 +1,86 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#ifndef __MRW__MAP__HPP__
#define __MRW__MAP__HPP__
#include <map>
#include <mrw/exception.hpp>
#include <mrw/string.hpp>
/** @addtogroup StdExt
*/
//@{
/** @brief insert a value in a map
@code
std::map<int, std::string> test;
test<<std::make_pair(1, std::string("one"))
<<std::make_pair(2, std::string("two"));
@endcode
@throw mrw::invalid_argument, if element is already in map
@param l a map of values
@param o a value to be inserted into map @c l
@pre #include <mrw/map.hpp>
*/
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;
}
/** @brief extract the first value of a map
@code
std::map<int, std::string> test;
test<<std::make_pair(1, std::string("one"))
<<std::make_pair(2, std::string("two"));
std::pair<int, std::string> i1, i2;
test>>i1>>i2;
// now: i1==(1, "one") i2==(2, "two") test=={}
@endcode
@param l a map of values
@param o a value to be extracted from map @c l
@throw mrw::length_error, if map was empty on entry
@note when something is extracted from a map, it is removed
from the map, that means after every shift the map is
shortened by the shifted element
@pre #include <mrw/string.hpp>
*/
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

@ -0,0 +1,82 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#ifndef __MRW__MULTIMAP__HPP__
#define __MRW__MULTIMAP__HPP__
#include <map>
#include <mrw/exception.hpp>
#include <mrw/string.hpp>
/** @addtogroup StdExt
*/
//@{
/** @brief insert a value in a multimap
@code
std::multimap<int, std::string> test;
test<<std::make_pair(1, std::string("one"))
<<std::make_pair(2, std::string("two"));
@endcode
@throw mrw::invalid_argument, if element is already in multimap
@param l a multimap of values
@param o a value to be inserted into multimap @c l
@pre #include <mrw/multimap.hpp>
*/
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;
}
/** @brief extract the first value of a multimap
@code
std::multimap<int, std::string> test;
test<<std::make_pair(1, std::string("one"))
<<std::make_pair(2, std::string("two"));
std::pair<int, std::string> i1, i2;
test>>i1>>i2;
// now: i1==(1, "one") i2==(2, "two") test=={}
@endcode
@param l a multimap of values
@param o a value to be extracted from multimap @c l
@throw mrw::length_error, if multimap was empty on entry
@note when something is extracted from a multimap, it is removed
from the multimap, that means after every shift the multimap is
shortened by the shifted element
@pre #include <mrw/string.hpp>
*/
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>>(std::multimap<>&, T&),"
" multimap is empty");
o = *it;
l.erase(it);
return l;
}
//@}
#endif

@ -0,0 +1,77 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#ifndef __MRW__MULTISET__HPP__
#define __MRW__MULTISET__HPP__
#include <set>
#include <mrw/exception.hpp>
#include <mrw/string.hpp>
/** @addtogroup StdExt
*/
//@{
/** @brief insert a value in a multiset
@code
std::multiset<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
@endcode
@param l a multiset of values
@param o a value to be inserted into multiset @c l
@pre #include <mrw/multiset.hpp>
*/
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;
}
/** @brief extract the first value of a multiset
@code
std::multiset<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
int i1(0), i2(0), i3(0), i4(0);
test>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 test=={5, 6, 7, 8}
@endcode
@param l a multiset of values
@param o a value to be extracted from multiset @c l
@throw mrw::length_error, if set was empty on entry
@note when something is extracted from a multiset, it is removed
from the multiset, that means after every shift the multiset is
shortened by the shifted element
@pre #include <mrw/string.hpp>
*/
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>>(std::multiset<>&, T&),"
" multiset is empty");
o = *it;
l.erase(it);
return l;
}
//@}
#endif

@ -0,0 +1,84 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#ifndef __MRW__SET__HPP__
#define __MRW__SET__HPP__
#include <set>
#include <mrw/exception.hpp>
#include <mrw/string.hpp>
/** @addtogroup StdExt
*/
//@{
/** @brief insert a value in a set
@code
std::set<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
@endcode
@throw mrw::invalid_argument, if element is already in set
@param l a set of values
@param o a value to be inserted into set @c l
@pre #include <mrw/set.hpp>
*/
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<<(std::set<>&, const T&),"
"set element already exists");
return l;
}
/** @brief extract the first value of a set
@code
std::set<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
int i1(0), i2(0), i3(0), i4(0);
test>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 test=={5, 6, 7, 8}
@endcode
@param l a set of values
@param o a value to be extracted from set @c l
@throw mrw::length_error, if set was empty on entry
@note when something is extracted from a set, it is removed
from the set, that means after every shift the set is
shortened by the shifted element
@pre #include <mrw/string.hpp>
*/
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>>(std::set<>&, T&),"
" set is empty");
o = *it;
l.erase(it);
return l;
}
//@}
#endif

@ -0,0 +1,257 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#include <mrw/string.hpp>
#include <mrw/list.hpp>
#include <mrw/vector.hpp>
#include <mrw/deque.hpp>
#include <mrw/set.hpp>
#include <mrw/map.hpp>
#include <mrw/multiset.hpp>
#include <mrw/multimap.hpp>
#include <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <iostream>
class StdExtTest: public CppUnit::TestFixture {
public:
void StringConv() {
std::string s("Integer=");
int i(4);
CPPUNIT_ASSERT(s+mrw::string(i) == "Integer=4");
}
void StringShift() {
std::string s("Integer=");
int i(4);
CPPUNIT_ASSERT((s<<i<<" test "<<4<<(long)5<<" xx") == "Integer=4 test 45 xx");
int i2 = 0;
std::string s2, s3;
s>>s2>>s3>>i2;
CPPUNIT_ASSERT(s2=="Integer=4");
CPPUNIT_ASSERT(s3=="test");
CPPUNIT_ASSERT(i2==45);
CPPUNIT_ASSERT(s==" xx");
s2=""; s3="";
s>>s2>>s3;
CPPUNIT_ASSERT(s2=="xx");
CPPUNIT_ASSERT(s3=="");
CPPUNIT_ASSERT(s=="");
}
void StringAdd() {
std::string s;
s=s+(signed short)1+(signed int)2+(signed long)3+(signed char)'A'+
(unsigned short)1+(unsigned int)2+(unsigned long)3+(unsigned char)'A'+'c';
CPPUNIT_ASSERT(s=="1236512365c");
s=(signed short)-4+s;
s=(signed int)5+s;
s=(signed long)6+s;
s=(signed char)8+s;
s=(unsigned short)4+s;
s=(unsigned int)5+s;
s=(unsigned long)6+s;
s=(unsigned char)8+s;
s='a'+s;
CPPUNIT_ASSERT(s=="a8654865-41236512365c");
s+=(signed short)-4;
s+=(signed int)5 ;
s+=(signed long)6;
s+=(signed char)8 ;
s+=(unsigned short)4;
s+=(unsigned int)5 ;
s+=(unsigned long)6;
s+=(unsigned char)8 ;
s+='a';
CPPUNIT_ASSERT(s=="a8654865-41236512365c-45684568a");
}
void ListShift() {
std::list<int> l;
l<<1<<2<<3<<4<<5<<6<<7<<8;
int i1(0), i2(0), i3(0), i4(0);
l>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 l=={5, 6, 7, 8}
CPPUNIT_ASSERT(i1==1 && i2==2 && i3==3 && i4==4);
CPPUNIT_ASSERT(l.size()==4);
for (int i=0; i<4; (l.pop_front(), ++i)) {
CPPUNIT_ASSERT(l.front()==i+5);
}
bool exc(false);
try {
l>>i1;
} catch (mrw::length_error&) {
exc=true;
}
CPPUNIT_ASSERT(exc);
}
void VectorShift() {
std::vector<int> l;
l<<1<<2<<3<<4<<5<<6<<7<<8;
int i1(0), i2(0), i3(0), i4(0);
l>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 l=={5, 6, 7, 8}
CPPUNIT_ASSERT(i1==1 && i2==2 && i3==3 && i4==4);
CPPUNIT_ASSERT(l.size()==4);
for (int i=0; i<4; (l.erase(l.begin()), ++i)) {
CPPUNIT_ASSERT(l.front()==i+5);
}
bool exc(false);
try {
l>>i1;
} catch (mrw::length_error&) {
exc=true;
}
CPPUNIT_ASSERT(exc);
}
void DequeShift() {
std::deque<int> l;
l<<1<<2<<3<<4<<5<<6<<7<<8;
int i1(0), i2(0), i3(0), i4(0);
l>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 l=={5, 6, 7, 8}
CPPUNIT_ASSERT(i1==1 && i2==2 && i3==3 && i4==4);
CPPUNIT_ASSERT(l.size()==4);
for (int i=0; i<4; (l.erase(l.begin()), ++i)) {
CPPUNIT_ASSERT(l.front()==i+5);
}
bool exc(false);
try {
l>>i1;
} catch (mrw::length_error&) {
exc=true;
}
CPPUNIT_ASSERT(exc);
}
void SetShift() {
std::set<int> s;
bool exc(false);
try {
s<<1<<2<<3<<4<<5<<6<<7<<8<<8;
} catch (mrw::invalid_argument& e) {
std::cout<<"******** EXCEPTION"<<std::endl
<<e.what()<<std::endl
<<e.stacktrace();
exc=true;
}
CPPUNIT_ASSERT(exc);
int i1(0), i2(0), i3(0), i4(0);
s>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 s=={5, 6, 7, 8}
CPPUNIT_ASSERT(i1==1 && i2==2 && i3==3 && i4==4);
CPPUNIT_ASSERT(s.size()==4);
for (int i=0; i<4; ++i) {
CPPUNIT_ASSERT(s.find(i+5)!=s.end());
}
s.erase(s.begin(), s.end());
exc=false;
try {
s>>i1;
} catch (mrw::length_error&) {
exc=true;
}
CPPUNIT_ASSERT(exc);
}
void MapShift() {
std::map<int, std::string> s;
bool exc(false);
try {
s<<std::make_pair(1, std::string("one"))
<<std::make_pair(2, std::string("two"))
<<std::make_pair(2, std::string("two"));
} catch (mrw::invalid_argument& e) {
std::cout<<"******** EXCEPTION"<<std::endl
<<e.what()<<std::endl
<<e.stacktrace();
exc=true;
}
CPPUNIT_ASSERT(exc);
std::pair<int, std::string> i1, i2;
s>>i1>>i2;
// now: i1==1 i2==2 i3==3 i4==4 s=={5, 6, 7, 8}
CPPUNIT_ASSERT(i1==std::make_pair(1, std::string("one")) &&
i2==std::make_pair(2, std::string("two")));
CPPUNIT_ASSERT(s.size()==0);
exc=false;
try {
s>>i1;
} catch (mrw::length_error&) {
exc=true;
}
CPPUNIT_ASSERT(exc);
}
void MultisetShift() {
std::multiset<int> s;
s<<1<<2<<3<<4<<5<<6<<7<<8<<9;
int i1(0), i2(0), i3(0), i4(0);
s>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 s=={5, 6, 7, 8}
CPPUNIT_ASSERT(i1==1 && i2==2 && i3==3 && i4==4);
CPPUNIT_ASSERT(s.size()==5);
for (int i=0; i<5; ++i) {
CPPUNIT_ASSERT(s.find(i+5)!=s.end());
}
s.erase(s.begin(), s.end());
bool exc(false);
try {
s>>i1;
} catch (mrw::length_error&) {
exc=true;
}
CPPUNIT_ASSERT(exc);
}
void MultimapShift() {
std::multimap<int, std::string> s;
s<<std::make_pair(1, std::string("one"))
<<std::make_pair(2, std::string("two"))
<<std::make_pair(2, std::string("two"));
std::pair<int, std::string> i1, i2;
s>>i1>>i2;
// now: i1==1 i2==2 i3==3 i4==4 s=={5, 6, 7, 8}
CPPUNIT_ASSERT(i1==std::make_pair(1, std::string("one")) &&
i2==std::make_pair(2, std::string("two")));
CPPUNIT_ASSERT(s.size()==1);
s>>i1;
CPPUNIT_ASSERT(i1==std::make_pair(2, std::string("two")));
bool exc(false);
try {
s>>i1;
} catch (mrw::length_error&) {
exc=true;
}
CPPUNIT_ASSERT(exc);
}
CPPUNIT_TEST_SUITE(StdExtTest);
CPPUNIT_TEST(StringConv);
CPPUNIT_TEST(StringShift);
CPPUNIT_TEST(StringAdd);
CPPUNIT_TEST(ListShift);
CPPUNIT_TEST(VectorShift);
CPPUNIT_TEST(DequeShift);
CPPUNIT_TEST(SetShift);
CPPUNIT_TEST(MapShift);
CPPUNIT_TEST(MultisetShift);
CPPUNIT_TEST(MultimapShift);
CPPUNIT_TEST_SUITE_END();
};
CPPUNIT_TEST_SUITE_REGISTRATION(StdExtTest);
int main() {
CppUnit::TextUi::TestRunner runner;
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
return runner.run() ? 0 : 1;
}

@ -0,0 +1,450 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#ifndef __MRW__STRING__HPP__
#define __MRW__STRING__HPP__
#include <string>
#include <sstream>
namespace mrw {
/** @defgroup StdExt Extensions for C++ Standard Libraries
There are some feature I am often missing in standard C++. They
are relatively easy to obtain, but they could be even simpler. I
am mainly a convinced C++ programmer, because I love
simplicity. This means, to convert an integer to a string,
something like this is not simple enough:
@code
int i;
std::string s;
[...]
std::stringstream ss;
ss<<"length is: "<<i<<"mm";
ss>>s;
@endcode
Why can't it simply be:
@code
int i;
std::string s;
[...]
s<<"length is: "<<i<<"mm";
@endcode
Or:
@code
int i;
std::string s;
[...]
s += i; // convert i to string and append it
@endcode
Because we are using the great and powerful C++ language, it can
be! That's why you need this module.
In addition to the shift in and shift out operator for strings,
you also get a shhift in and shift out operator for all STL
container classes:
@code
std::list<int> l;
l<<1<<2<<<3<<4;
int i1, i2, i3, i4;
l>>i1>>i2>>i3>>i4;
@endcode
And the possibility to add strings to integers and vice versa:
@code
std::string s("x");
s = 1+s+2; // s=="1x2"
@endcode
@warning Please note that global namespace is polluted with some
operators. If you don't want this, just don't include any of
these include files files. There's no impact from this module,
if you don't include a header, since all code is inline.
@warning This code is still experimental and subject to frequent
changes! Do not rely your projects on it yet!
@since 1.0.0
*/
//@{
/** @brief convert any value to a std::string
@code
std::string s = mrw::string(15);
@endcode
@param o a value to be converted to std::string
@pre #include <mrw/string.hpp>
@pre T must support operator<< to a stream
*/
template <typename T> std::string string(const T& o) throw(std::bad_exception) {
std::stringstream ss;
ss<<o;
return ss.str();
}
/** @brief convert std::string to any value
@code
int i = mrw::to<int>("15");
@endcode
@param s the string where a value of type @c T is extracted from
@pre #include <mrw/string.hpp>
@pre T must support operator>> from a stream
*/
template <typename T> T to(const std::string& s) throw(std::bad_exception) {
T o;
std::stringstream ss(s);
ss>>o;
return o;
}
//@}
}
/** @addtogroup StdExt
*/
//@{
/** @brief append any value to a string
@code
std::string s;
s<<"length is: "<<i<<"mm";
@endcode
@param s the string, where o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
@pre T must support operator<< to a stream
*/
template <typename T> std::string& operator<<(std::string& s, const T& o) throw(std::bad_exception) {
return s+=mrw::string(o);
}
/** @brief extract any value from a string
@code
std::string s1("length: 15 mm");
string s2, s3;
int i(0);
s1>>s2>>is3;
// now: s1=="" s2=="length:" i==15 s3=="mm"
@endcode
@param s the string, from which o is extracted
@param o the value to extract from s
@note when something is extracted from a string, it is removed
from the string, that means after every shift the string is
shortened by the shifted element
@pre #include <mrw/string.hpp>
@pre T must support operator>> from a stream
*/
template <typename T> std::string& operator>>(std::string& s, T& o) throw(std::bad_exception) {
std::stringstream ss(s);
ss>>o;
return (s=ss.tellg()>0?s.substr(ss.tellg()):"");
}
/** @brief add a @c unsigned short value to a string
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(const std::string& s, unsigned short o) throw(std::bad_exception) {
return s+mrw::string(o);
}
/** @brief append a string to a @c unsigned short value
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is prepended
@param o the value to prepend in front of @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(unsigned short o, const std::string& s) throw(std::bad_exception) {
return mrw::string(o)+s;
}
/** @brief add an @c unsigned int value to a string
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(const std::string& s, unsigned int o) throw(std::bad_exception) {
return s+mrw::string(o);
}
/** @brief append a string to an @c unsigned int value
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is prepended
@param o the value to prepend in front of @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(unsigned int o, const std::string& s) throw(std::bad_exception) {
return mrw::string(o)+s;
}
/** @brief add a @c unsigned long value to a string
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(const std::string& s, unsigned long o) throw(std::bad_exception) {
return s+mrw::string(o);
}
/** @brief append a string to a @c unsigned long value
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is prepended
@param o the value to prepend in front of @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(unsigned long o, const std::string& s) throw(std::bad_exception) {
return mrw::string(o)+s;
}
/** @brief add a @c signed short value to a string
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(const std::string& s, signed short o) throw(std::bad_exception) {
return s+mrw::string(o);
}
/** @brief append a string to a @c signed short value
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is prepended
@param o the value to prepend in front of @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(signed short o, const std::string& s) throw(std::bad_exception) {
return mrw::string(o)+s;
}
/** @brief add an @c signed int value to a string
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(const std::string& s, signed int o) throw(std::bad_exception) {
return s+mrw::string(o);
}
/** @brief append a string to an @c signed int value
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is prepended
@param o the value to prepend in front of @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(signed int o, const std::string& s) throw(std::bad_exception) {
return mrw::string(o)+s;
}
/** @brief add a @c signed long value to a string
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(const std::string& s, signed long o) throw(std::bad_exception) {
return s+mrw::string(o);
}
/** @brief append a string to a @c signed long value
@code
std::string s;
s+"length is: "+i+"mm";
@endcode
@param s the string, where @c o is prepended
@param o the value to prepend in front of @c s
@pre #include <mrw/string.hpp>
*/
std::string operator+(signed long o, const std::string& s) throw(std::bad_exception) {
return mrw::string(o)+s;
}
/** @brief add a @c unsigned short value to a string
@code
std::string s;
s += o;
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string& operator+=(std::string& s, unsigned short o) throw(std::bad_exception) {
return s+=mrw::string(o);
}
/** @brief add an @c unsigned int value to a string
@code
std::string s;
s += o;
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string& operator+=(std::string& s, unsigned int o) throw(std::bad_exception) {
return s+=mrw::string(o);
}
/** @brief add a @c unsigned long value to a string
@code
std::string s;
s += o;
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string& operator+=(std::string& s, unsigned long o) throw(std::bad_exception) {
return s+=mrw::string(o);
}
/** @brief add a @c signed short value to a string
@code
std::string s;
s += o;
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string& operator+=(std::string& s, signed short o) throw(std::bad_exception) {
return s+=mrw::string(o);
}
/** @brief add an @c signed int value to a string
@code
std::string s;
s += o;
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string& operator+=(std::string& s, signed int o) throw(std::bad_exception) {
return s+=mrw::string(o);
}
/** @brief add a @c signed long value to a string
@code
std::string s;
s += o;
@endcode
@param s the string, where @c o is appended
@param o the value to append to @c s
@pre #include <mrw/string.hpp>
*/
std::string& operator+=(std::string& s, signed long o) throw(std::bad_exception) {
return s+=mrw::string(o);
}
//@}
#endif

@ -0,0 +1,77 @@
/** @file
$Id$
$Date$
$Author$
@copy &copy; Marc W&auml;ckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.1 2004/10/07 09:31:30 marc
new feature
*/
#ifndef __MRW__VECTOR__HPP__
#define __MRW__VECTOR__HPP__
#include <vector>
#include <mrw/exception.hpp>
#include <mrw/string.hpp>
/** @addtogroup StdExt
*/
//@{
/** @brief push a value to a vector
@code
std::vector<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
@endcode
@param l a vector of values
@param o a value to be inserted into vector @c l
@pre #include <mrw/vector.hpp>
*/
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;
}
/** @brief extract the first value of a vector
@code
std::vector<int> test;
test<<1<<2<<3<<4<<5<<6<<7<<8;
int i1(0), i2(0), i3(0), i4(0);
test>>i1>>i2>>i3>>i4;
// now: i1==1 i2==2 i3==3 i4==4 test=={5, 6, 7, 8}
@endcode
@param l a vector of values
@param o a value to be extracted from vector @c l
@throw mrw::length_error, if vector was empty on entry
@note when something is extracted from a vector, it is removed
from the vector, that means after every shift the vector is
shortened by the shifted element
@pre #include <mrw/string.hpp>
*/
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
Loading…
Cancel
Save