Main MRPT website > C++ reference
MRPT logo
stl_extensions.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file |
7  | Copyright (c) 2005-2013, MAPIR group, University of Malaga |
8  | Copyright (c) 2012-2013, University of Almeria |
9  | All rights reserved. |
10  | |
11  | Redistribution and use in source and binary forms, with or without |
12  | modification, are permitted provided that the following conditions are |
13  | met: |
14  | * Redistributions of source code must retain the above copyright |
15  | notice, this list of conditions and the following disclaimer. |
16  | * Redistributions in binary form must reproduce the above copyright |
17  | notice, this list of conditions and the following disclaimer in the |
18  | documentation and/or other materials provided with the distribution. |
19  | * Neither the name of the copyright holders nor the |
20  | names of its contributors may be used to endorse or promote products |
21  | derived from this software without specific prior written permission.|
22  | |
23  | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
24  | 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
25  | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR|
26  | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
27  | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL|
28  | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR|
29  | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
30  | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
31  | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
32  | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
33  | POSSIBILITY OF SUCH DAMAGE. |
34  +---------------------------------------------------------------------------+ */
35 #ifndef stl_extensions_H
36 #define stl_extensions_H
37 
39 #include <mrpt/utils/CStream.h>
41 
42 #include <set>
43 #include <map>
44 #include <list>
45 #include <cctype> // tolower
46 
47 // These are "STL extensions" but have their own files for clarity
50 #include <mrpt/utils/bimap.h>
52 #include <mrpt/utils/traits_map.h>
53 
54 
55 namespace mrpt
56 {
57  namespace utils
58  {
59  /** \addtogroup stlext_grp STL extensions and metaprogramming
60  * \ingroup mrpt_base_grp
61  * @{ */
62 
63  using namespace mrpt::utils::metaprogramming;
64  using std::for_each;
65  using std::string;
66 
67 
68  #define MRPTSTL_SERIALIZABLE_SEQ_CONTAINER( CONTAINER ) \
69  /** Template method to serialize a sequential STL container */ \
70  template <class T,class _Ax> \
71  CStream& operator << (CStream& out, const CONTAINER<T,_Ax> &obj) \
72  { \
73  out << string(#CONTAINER) << TTypeName<T>::get(); \
74  out << static_cast<uint32_t>(obj.size()); \
75  for_each( obj.begin(), obj.end(), ObjectWriteToStream(&out) ); \
76  return out; \
77  } \
78  /** Template method to deserialize a sequential STL container */ \
79  template <class T,class _Ax> \
80  CStream& operator >> (CStream& in, CONTAINER<T,_Ax> &obj) \
81  { \
82  obj.clear(); \
83  string pref,stored_T; \
84  in >> pref; \
85  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() )) \
86  in >> stored_T; \
87  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() )) \
88  uint32_t n; \
89  in >> n; \
90  obj.resize(n); \
91  for_each( obj.begin(), obj.end(), ObjectReadFromStream(&in) ); \
92  return in; \
93  }
94 
95 
96  #define MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER( CONTAINER ) \
97  /** Template method to serialize an associative STL container */ \
98  template <class K,class V, class _Pr, class _Alloc> \
99  CStream& operator << (CStream& out, const CONTAINER<K,V,_Pr,_Alloc> &obj) \
100  { \
101  out << string(#CONTAINER) << TTypeName<K>::get() << TTypeName<V>::get(); \
102  out << static_cast<uint32_t>(obj.size()); \
103  for (typename CONTAINER<K,V,_Pr,_Alloc>::const_iterator it=obj.begin();it!=obj.end();++it) \
104  out << it->first << it->second; \
105  return out; \
106  } \
107  /** Template method to deserialize an associative STL container */ \
108  template <class K,class V, class _Pr, class _Alloc> \
109  CStream& operator >> (CStream& in, CONTAINER<K,V,_Pr,_Alloc> &obj) \
110  { \
111  obj.clear(); \
112  string pref,stored_K,stored_V; \
113  in >> pref; \
114  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())) \
115  in >> stored_K; \
116  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())) \
117  in >> stored_V; \
118  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())) \
119  uint32_t n; \
120  in >> n; \
121  for (uint32_t i=0;i<n;i++) \
122  { \
123  K key_obj; \
124  in >> key_obj; \
125  /* Create an pair (Key, empty), then read directly into the ".second": */ \
126  typename CONTAINER<K,V,_Pr,_Alloc>::iterator it_new = obj.insert(obj.begin(), std::make_pair(key_obj, V()) ); \
127  in >> it_new->second; \
128  } \
129  return in; \
130  }
131 
132  MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::vector) // Serialization for std::vector
133  MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::deque) // Serialization for std::deque
134  MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::list) // Serialization for std::list
135 
136  MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER(std::map) // Serialization for std::map
137  MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER(std::multimap) // Serialization for std::multimap
138 
139 
140  #define MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER( CONTAINER ) \
141  /** Template method to serialize an associative STL container */ \
142  template <class K,class _Pr,class _Alloc> \
143  CStream& operator << (CStream& out, const CONTAINER<K,_Pr,_Alloc> &obj) \
144  { \
145  out << string(#CONTAINER) << TTypeName<K>::get(); \
146  out << static_cast<uint32_t>(obj.size()); \
147  for (typename CONTAINER<K,_Pr,_Alloc>::const_iterator it=obj.begin();it!=obj.end();++it) \
148  out << *it; \
149  return out; \
150  } \
151  /** Template method to deserialize an associative STL container */ \
152  template <class K,class _Pr,class _Alloc> \
153  CStream& operator >> (CStream& in, CONTAINER<K,_Pr,_Alloc> &obj) \
154  { \
155  obj.clear(); \
156  string pref,stored_K; \
157  in >> pref; \
158  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())) \
159  in >> stored_K; \
160  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())) \
161  uint32_t n; \
162  in >> n; \
163  for (uint32_t i=0;i<n;i++) \
164  { \
165  K key_obj; \
166  in >> key_obj; \
167  obj.insert(key_obj); \
168  } \
169  return in; \
170  }
171 
172  MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(std::set) // Serialization for std::set
173  MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(std::multiset) // Serialization for std::multiset
174 
175 
176  /** Template method to serialize a STL pair */
177  template <class T1,class T2>
178  CStream& operator << (CStream& out, const std::pair<T1,T2> &obj)
179  {
180  out << string("std::pair") << TTypeName<T1>::get() << TTypeName<T2>::get();
181  out << obj.first << obj.second;
182  return out;
183  }
184  /** Template method to deserialize a STL pair */
185  template <class T1,class T2>
186  CStream& operator >> (CStream& in, std::pair<T1,T2> &obj)
187  {
188  string pref,stored_K,stored_V;
189  in >> pref;
190  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()))
191  in >> stored_K;
192  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()))
193  in >> stored_V;
194  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()))
195  in >> obj.first >> obj.second;
196  return in;
197  }
198 
199 
200  /** Returns the index of the value "T" in the container "vect" (std::vector,std::deque,etc), or string::npos if not found.
201  */
202  template <class T,class CONTAINER>
203  size_t find_in_vector(const T &value, const CONTAINER &vect)
204  {
205  typename CONTAINER::const_iterator last = vect.end();
206  for (typename CONTAINER::const_iterator i=vect.begin();i!=last;++i)
207  if (*i==value) return std::distance(vect.begin(),i);
208  return std::string::npos;
209  }
210 
211  /** Calls the standard "erase" method of a STL container, but also returns an iterator to the next element in the container (or ::end if none) */
212  template <class T> inline typename std::list<T>::iterator erase_return_next(std::list<T> &cont, typename std::list<T>::iterator &it)
213  {
214  return cont.erase(it);
215  }
216  //! \overload
217  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)
218  {
219  typename std::map<K,V>::iterator itRet = it; ++itRet;
220  cont.erase(it);
221  return itRet;
222  }
223  //! \overload
224  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)
225  {
226  typename std::multimap<K,V>::iterator itRet = it; ++itRet;
227  cont.erase(it);
228  return itRet;
229  }
230  //! \overload
231  template <class T> inline typename std::set<T>::iterator erase_return_next(std::set<T> &cont, typename std::set<T>::iterator &it)
232  {
233  typename std::set<T>::iterator itRet = it; ++itRet;
234  cont.erase(it);
235  return itRet;
236  }
237 
238  /** Generates a string for a vector in the format [A,B,C,...] to std::cout, and the fmt string for <b>each</b> vector element. */
239  template <typename T>
240  std::string sprintf_vector(const char *fmt, const std::vector<T> &V )
241  {
242  std::string ret = "[";
243  const size_t N = V.size();
244  for (size_t i=0;i<N;i++)
245  {
246  ret+= format(fmt,V[i]);
247  if (i!=(N-1)) ret+= ",";
248  }
249  ret+="]";
250  return ret;
251  }
252  /// @overload
253  template <typename Derived>
254  std::string sprintf_vector(const char *fmt, const Eigen::MatrixBase<Derived> &V )
255  {
256  std::string ret = "[";
257  const size_t N = V.size();
258  for (size_t i=0;i<N;i++)
259  {
260  ret+= format(fmt,V[i]);
261  if (i!=(N-1)) ret+= ",";
262  }
263  ret+="]";
264  return ret;
265  }
266 
267  /** Prints a vector in the format [A,B,C,...] to std::cout, and the fmt string for <b>each</b> vector element. */
268  template <typename T>
269  void printf_vector(const char *fmt, const std::vector<T> &V ) {
270  std::cout << sprintf_vector(fmt, V);
271  }
272 
273  /** A case-insensitive comparator struct for usage within STL containers, eg: map<string,string,ci_less>
274  */
275  struct ci_less : std::binary_function<std::string,std::string,bool>
276  {
277  // case-independent (ci) compare_less binary function
278  struct nocase_compare : public std::binary_function<char,char,bool> {
279  bool operator()(const char c1, const char c2) const { return tolower(c1)<tolower(c2); }
280  };
281  bool operator() (const std::string & s1, const std::string & s2) const {
282  return std::lexicographical_compare(s1.begin(),s1.end(), s2.begin(),s2.end(), nocase_compare());
283  }
284  }; // end of ci_less
285 
286  /** @} */ // end of grouping
287 
288  } // End of namespace
289 } // End of namespace
290 #endif
bool operator()(const char c1, const char c2) const
std::string sprintf_vector(const char *fmt, const std::vector< T > &V)
Generates a string for a vector in the format [A,B,C,...] to std::cout, and the fmt string for each v...
A case-insensitive comparator struct for usage within STL containers, eg: map<string,string,ci_less>
A template to obtain the type of its argument as a string at compile time.
Definition: TTypeName.h:72
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
#define THROW_EXCEPTION(msg)
Scalar * iterator
Definition: eigen_plugins.h:49
const Scalar * const_iterator
Definition: eigen_plugins.h:50
#define MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(CONTAINER)
std::list< T >::iterator erase_return_next(std::list< T > &cont, typename std::list< T >::iterator &it)
Calls the standard "erase" method of a STL container, but also returns an iterator to the next elemen...
::mrpt::utils::CStream & operator>>(mrpt::utils::CStream &in, CImagePtr &pObj)
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:62
A set of utility objects for metaprogramming with STL algorithms.
static std::string get()
Definition: TTypeName.h:74
void printf_vector(const char *fmt, const std::vector< T > &V)
Prints a vector in the format [A,B,C,...] to std::cout, and the fmt string for each vector element...
MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std::vector) MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(std
Template method to serialize a STL pair.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define MRPTSTL_SERIALIZABLE_ASSOC_CONTAINER(CONTAINER)
size_t find_in_vector(const T &value, const CONTAINER &vect)
Returns the index of the value "T" in the container "vect" (std::vector,std::deque,etc), or string::npos if not found.
double BASE_IMPEXP distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.



Page generated by Doxygen 1.8.14 for MRPT 1.0.2 SVN: at lun oct 28 00:52:41 CET 2019 Hosted on:
SourceForge.net Logo