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