00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef stl_extensions_H
00029 #define stl_extensions_H
00030
00031 #include <mrpt/utils/CSerializable.h>
00032 #include <mrpt/utils/CStream.h>
00033 #include <mrpt/utils/metaprogramming.h>
00034
00035 #include <set>
00036 #include <map>
00037 #include <list>
00038
00039 namespace mrpt
00040 {
00041 namespace utils
00042 {
00043 using namespace mrpt::utils::metaprogramming;
00044 using std::for_each;
00045 using std::string;
00046
00047
00048 #define MRPTSTL_SERIALIZABLE_SEQ_CONTAINER( CONTAINER ) \
00049 \
00050 template <class T> \
00051 CStream& operator << (CStream& out, const CONTAINER<T> &obj) \
00052 { \
00053 out << string(#CONTAINER) << TTypeName<T>::get(); \
00054 out << static_cast<uint32_t>(obj.size()); \
00055 for_each( obj.begin(), obj.end(), ObjectWriteToStream(&out) ); \
00056 return out; \
00057 } \
00058 \
00059 template <class T> \
00060 CStream& operator >> (CStream& in, CONTAINER<T> &obj) \
00061 { \
00062 obj.clear(); \
00063 string pref,stored_T; \
00064 in >> pref; \
00065 if (pref!=#CONTAINER) THROW_EXCEPTION(format("Error: serialized container %s<%s>'s preambles is wrong: '%s'",#CONTAINER,TTypeName<T>::get().c_str(),pref.c_str() )) \
00066 in >> stored_T; \
00067 if (stored_T != TTypeName<T>::get() ) THROW_EXCEPTION(format("Error: serialized container %s< %s != %s >",#CONTAINER,stored_T.c_str(),TTypeName<T>::get().c_str() )) \
00068 uint32_t n; \
00069 in >> n; \
00070 obj.resize(n); \
00071 for_each( obj.begin(), obj.end(), ObjectReadFromStream(&in) ); \
00072 return in; \
00073 }
00074
00075
00076 #define MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER( CONTAINER ) \
00077 \
00078 template <class K,class V> \
00079 CStream& operator << (CStream& out, const CONTAINER<K,V> &obj) \
00080 { \
00081 out << string(#CONTAINER) << TTypeName<K>::get() << TTypeName<V>::get(); \
00082 out << static_cast<uint32_t>(obj.size()); \
00083 for (typename CONTAINER<K,V>::const_iterator it=obj.begin();it!=obj.end();++it) \
00084 out << it->first << it->second; \
00085 return out; \
00086 } \
00087 \
00088 template <class K,class V> \
00089 CStream& operator >> (CStream& in, CONTAINER<K,V> &obj) \
00090 { \
00091 obj.clear(); \
00092 string pref,stored_K,stored_V; \
00093 in >> pref; \
00094 if (pref!=#CONTAINER) THROW_EXCEPTION(format("Error: serialized container %s<%s,%s>'s preamble is wrong: '%s'",#CONTAINER, TTypeName<K>::get().c_str(), TTypeName<V>::get().c_str() ,pref.c_str())) \
00095 in >> stored_K; \
00096 if (stored_K != TTypeName<K>::get()) THROW_EXCEPTION(format("Error: serialized container %s key type %s != %s",#CONTAINER,stored_K.c_str(), TTypeName<K>::get().c_str())) \
00097 in >> stored_V; \
00098 if (stored_V != TTypeName<V>::get()) THROW_EXCEPTION(format("Error: serialized container %s value type %s != %s",#CONTAINER,stored_V.c_str(), TTypeName<V>::get().c_str())) \
00099 uint32_t n; \
00100 in >> n; \
00101 for (uint32_t i=0;i<n;i++) \
00102 { \
00103 K key_obj; \
00104 in >> key_obj; \
00105 \
00106 typename CONTAINER<K,V>::iterator it_new = obj.insert(obj.begin(), std::make_pair(key_obj, V()) ); \
00107 in >> it_new->second; \
00108 } \
00109 return in; \
00110 }
00111
00112 MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::vector)
00113 MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::deque)
00114 MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::list)
00115
00116 MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER(std::map)
00117 MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER(std::multimap)
00118
00119
00120 #define MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER( CONTAINER ) \
00121 \
00122 template <class K> \
00123 CStream& operator << (CStream& out, const CONTAINER<K> &obj) \
00124 { \
00125 out << string(#CONTAINER) << TTypeName<K>::get(); \
00126 out << static_cast<uint32_t>(obj.size()); \
00127 for (typename CONTAINER<K>::const_iterator it=obj.begin();it!=obj.end();++it) \
00128 out << *it; \
00129 return out; \
00130 } \
00131 \
00132 template <class K> \
00133 CStream& operator >> (CStream& in, CONTAINER<K> &obj) \
00134 { \
00135 obj.clear(); \
00136 string pref,stored_K; \
00137 in >> pref; \
00138 if (pref!=#CONTAINER) THROW_EXCEPTION(format("Error: serialized container %s<%s>'s preamble is wrong: '%s'",#CONTAINER, TTypeName<K>::get().c_str(),pref.c_str())) \
00139 in >> stored_K; \
00140 if (stored_K != TTypeName<K>::get()) THROW_EXCEPTION(format("Error: serialized container %s key type %s != %s",#CONTAINER,stored_K.c_str(), TTypeName<K>::get().c_str())) \
00141 uint32_t n; \
00142 in >> n; \
00143 for (uint32_t i=0;i<n;i++) \
00144 { \
00145 K key_obj; \
00146 in >> key_obj; \
00147 obj.insert(key_obj); \
00148 } \
00149 return in; \
00150 }
00151
00152 MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(std::set)
00153 MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(std::multiset)
00154
00155
00156
00157 template <class T1,class T2>
00158 CStream& operator << (CStream& out, const std::pair<T1,T2> &obj)
00159 {
00160 out << string("std::pair") << TTypeName<T1>::get() << TTypeName<T2>::get();
00161 out << obj.first << obj.second;
00162 return out;
00163 }
00164
00165 template <class T1,class T2>
00166 CStream& operator >> (CStream& in, std::pair<T1,T2> &obj)
00167 {
00168 string pref,stored_K,stored_V;
00169 in >> pref;
00170 if (pref!="std::pair") THROW_EXCEPTION(format("Error: serialized std::pair<%s,%s>'s preamble is wrong: '%s'", TTypeName<T1>::get().c_str(), TTypeName<T2>::get().c_str() ,pref.c_str()))
00171 in >> stored_K;
00172 if (stored_K != TTypeName<T1>::get()) THROW_EXCEPTION(format("Error: serialized std::pair first type %s != %s",stored_K.c_str(), TTypeName<T1>::get().c_str()))
00173 in >> stored_V;
00174 if (stored_V != TTypeName<T2>::get()) THROW_EXCEPTION(format("Error: serialized std::pair second type %s != %s",stored_V.c_str(), TTypeName<T2>::get().c_str()))
00175 in >> obj.first >> obj.second;
00176 return in;
00177 }
00178
00179
00180
00181
00182
00183 template <class T>
00184 class list_searchable : public std::list<T>
00185 {
00186 public:
00187 virtual ~list_searchable() { std::list<T>::clear(); }
00188
00189 void insert( const T &o ) { std::list<T>::push_back(o); }
00190
00191 typename std::list<T>::iterator find( const T& i ) {
00192 return std::find(std::list<T>::begin(),std::list<T>::end(),i);
00193 }
00194
00195 typename std::list<T>::const_iterator find( const T& i ) const {
00196 return std::find(std::list<T>::begin(),std::list<T>::end(),i);
00197 }
00198
00199 };
00200
00201
00202
00203
00204 template <class T>
00205 size_t find_in_vector(const T &value, const std::vector<T> &vect)
00206 {
00207 for (size_t i=0;i<vect.size();i++)
00208 if (vect[i]==value) return i;
00209 return std::string::npos;
00210 }
00211
00212
00213
00214 template <class CONTAINER>
00215 typename CONTAINER::iterator erase_return_next(CONTAINER &cont, typename CONTAINER::iterator &it)
00216 {
00217 typename CONTAINER::iterator itRet = it;
00218 ++itRet;
00219 cont.erase(it);
00220 return itRet;
00221 }
00222
00223
00224 }
00225 }
00226 #endif