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 #include <cctype>
00039
00040
00041 #include <mrpt/utils/circular_buffer.h>
00042 #include <mrpt/utils/list_searchable.h>
00043 #include <mrpt/utils/bimap.h>
00044 #include <mrpt/utils/map_as_vector.h>
00045 #include <mrpt/utils/traits_map.h>
00046
00047
00048 namespace mrpt
00049 {
00050 namespace utils
00051 {
00052 using namespace mrpt::utils::metaprogramming;
00053 using std::for_each;
00054 using std::string;
00055
00056
00057 #define MRPTSTL_SERIALIZABLE_SEQ_CONTAINER( CONTAINER ) \
00058 \
00059 template <class T,class _Ax> \
00060 CStream& operator << (CStream& out, const CONTAINER<T,_Ax> &obj) \
00061 { \
00062 out << string(#CONTAINER) << TTypeName<T>::get(); \
00063 out << static_cast<uint32_t>(obj.size()); \
00064 for_each( obj.begin(), obj.end(), ObjectWriteToStream(&out) ); \
00065 return out; \
00066 } \
00067 \
00068 template <class T,class _Ax> \
00069 CStream& operator >> (CStream& in, CONTAINER<T,_Ax> &obj) \
00070 { \
00071 obj.clear(); \
00072 string pref,stored_T; \
00073 in >> pref; \
00074 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() )) \
00075 in >> stored_T; \
00076 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() )) \
00077 uint32_t n; \
00078 in >> n; \
00079 obj.resize(n); \
00080 for_each( obj.begin(), obj.end(), ObjectReadFromStream(&in) ); \
00081 return in; \
00082 }
00083
00084
00085 #define MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER( CONTAINER ) \
00086 \
00087 template <class K,class V, class _Pr, class _Alloc> \
00088 CStream& operator << (CStream& out, const CONTAINER<K,V,_Pr,_Alloc> &obj) \
00089 { \
00090 out << string(#CONTAINER) << TTypeName<K>::get() << TTypeName<V>::get(); \
00091 out << static_cast<uint32_t>(obj.size()); \
00092 for (typename CONTAINER<K,V,_Pr,_Alloc>::const_iterator it=obj.begin();it!=obj.end();++it) \
00093 out << it->first << it->second; \
00094 return out; \
00095 } \
00096 \
00097 template <class K,class V, class _Pr, class _Alloc> \
00098 CStream& operator >> (CStream& in, CONTAINER<K,V,_Pr,_Alloc> &obj) \
00099 { \
00100 obj.clear(); \
00101 string pref,stored_K,stored_V; \
00102 in >> pref; \
00103 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())) \
00104 in >> stored_K; \
00105 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())) \
00106 in >> stored_V; \
00107 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())) \
00108 uint32_t n; \
00109 in >> n; \
00110 for (uint32_t i=0;i<n;i++) \
00111 { \
00112 K key_obj; \
00113 in >> key_obj; \
00114 \
00115 typename CONTAINER<K,V,_Pr,_Alloc>::iterator it_new = obj.insert(obj.begin(), std::make_pair(key_obj, V()) ); \
00116 in >> it_new->second; \
00117 } \
00118 return in; \
00119 }
00120
00121 MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::vector)
00122 MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::deque)
00123 MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::list)
00124
00125 MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER(std::map)
00126 MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER(std::multimap)
00127
00128
00129 #define MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER( CONTAINER ) \
00130 \
00131 template <class K,class _Pr,class _Alloc> \
00132 CStream& operator << (CStream& out, const CONTAINER<K,_Pr,_Alloc> &obj) \
00133 { \
00134 out << string(#CONTAINER) << TTypeName<K>::get(); \
00135 out << static_cast<uint32_t>(obj.size()); \
00136 for (typename CONTAINER<K,_Pr,_Alloc>::const_iterator it=obj.begin();it!=obj.end();++it) \
00137 out << *it; \
00138 return out; \
00139 } \
00140 \
00141 template <class K,class _Pr,class _Alloc> \
00142 CStream& operator >> (CStream& in, CONTAINER<K,_Pr,_Alloc> &obj) \
00143 { \
00144 obj.clear(); \
00145 string pref,stored_K; \
00146 in >> pref; \
00147 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())) \
00148 in >> stored_K; \
00149 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())) \
00150 uint32_t n; \
00151 in >> n; \
00152 for (uint32_t i=0;i<n;i++) \
00153 { \
00154 K key_obj; \
00155 in >> key_obj; \
00156 obj.insert(key_obj); \
00157 } \
00158 return in; \
00159 }
00160
00161 MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(std::set)
00162 MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(std::multiset)
00163
00164
00165
00166 template <class T1,class T2>
00167 CStream& operator << (CStream& out, const std::pair<T1,T2> &obj)
00168 {
00169 out << string("std::pair") << TTypeName<T1>::get() << TTypeName<T2>::get();
00170 out << obj.first << obj.second;
00171 return out;
00172 }
00173
00174 template <class T1,class T2>
00175 CStream& operator >> (CStream& in, std::pair<T1,T2> &obj)
00176 {
00177 string pref,stored_K,stored_V;
00178 in >> pref;
00179 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()))
00180 in >> stored_K;
00181 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()))
00182 in >> stored_V;
00183 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()))
00184 in >> obj.first >> obj.second;
00185 return in;
00186 }
00187
00188
00189
00190
00191 template <class T,class CONTAINER>
00192 size_t find_in_vector(const T &value, const CONTAINER &vect)
00193 {
00194 typename CONTAINER::const_iterator last = vect.end();
00195 for (typename CONTAINER::const_iterator i=vect.begin();i!=last;++i)
00196 if (*i==value) return std::distance(vect.begin(),i);
00197 return std::string::npos;
00198 }
00199
00200
00201 template <class T> inline typename std::list<T>::iterator erase_return_next(std::list<T> &cont, typename std::list<T>::iterator &it)
00202 {
00203 return cont.erase(it);
00204 }
00205
00206 template <class K,class V> inline typename std::map<K,V>::iterator erase_return_next(std::map<K,V> &cont, typename std::map<K,V>::iterator &it)
00207 {
00208 typename std::map<K,V>::iterator itRet = it; ++itRet;
00209 cont.erase(it);
00210 return itRet;
00211 }
00212
00213 template <class K,class V> inline typename std::multimap<K,V>::iterator erase_return_next(std::multimap<K,V> &cont, typename std::multimap<K,V>::iterator &it)
00214 {
00215 typename std::multimap<K,V>::iterator itRet = it; ++itRet;
00216 cont.erase(it);
00217 return itRet;
00218 }
00219
00220 template <class T> inline typename std::set<T>::iterator erase_return_next(std::set<T> &cont, typename std::set<T>::iterator &it)
00221 {
00222 typename std::set<T>::iterator itRet = it; ++itRet;
00223 cont.erase(it);
00224 return itRet;
00225 }
00226
00227 template <class T> inline typename std::vector<T>::iterator erase_return_next(std::vector<T> &cont, typename std::vector<T>::iterator &it)
00228 {
00229 typename std::vector<T>::iterator itRet = it;
00230 cont.erase(it);
00231 return ++itRet;
00232 }
00233
00234
00235 template <typename T>
00236 std::string sprintf_vector(const char *fmt, const std::vector<T> &V )
00237 {
00238 std::string ret = "[";
00239 const size_t N = V.size();
00240 for (size_t i=0;i<N;i++)
00241 {
00242 ret+= format(fmt,V[i]);
00243 if (i!=(N-1)) ret+= ",";
00244 }
00245 ret+="]";
00246 return ret;
00247 }
00248
00249 template <typename Derived>
00250 std::string sprintf_vector(const char *fmt, const Eigen::MatrixBase<Derived> &V )
00251 {
00252 std::string ret = "[";
00253 const size_t N = V.size();
00254 for (size_t i=0;i<N;i++)
00255 {
00256 ret+= format(fmt,V[i]);
00257 if (i!=(N-1)) ret+= ",";
00258 }
00259 ret+="]";
00260 return ret;
00261 }
00262
00263
00264 template <typename T>
00265 void printf_vector(const char *fmt, const std::vector<T> &V ) {
00266 std::cout << sprintf_vector(fmt, V);
00267 }
00268
00269
00270
00271 struct ci_less : std::binary_function<std::string,std::string,bool>
00272 {
00273
00274 struct nocase_compare : public std::binary_function<char,char,bool> {
00275 bool operator()(const char c1, const char c2) const { return tolower(c1)<tolower(c2); }
00276 };
00277 bool operator() (const std::string & s1, const std::string & s2) const {
00278 return std::lexicographical_compare(s1.begin(),s1.end(), s2.begin(),s2.end(), nocase_compare());
00279 }
00280 };
00281
00282 }
00283 }
00284 #endif