parent
bea4847b13
commit
ef00668649
9 changed files with 1267 additions and 0 deletions
@ -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 © 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__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 © 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__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 © 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__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 © 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__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 © 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__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 © 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 |
||||
|
||||
|
||||
*/ |
||||
#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 © 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__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 © 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__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…
Reference in new issue