Main MRPT website > C++ reference for MRPT 1.9.9
metaprogramming.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef metaprogramming_H
10 #define metaprogramming_H
11 
12 #include <mrpt/utils/CObject.h>
14 
15 namespace mrpt
16 {
17 namespace utils
18 {
19 class CStream;
20 
21 /** A set of utility objects for metaprogramming with STL algorithms.
22  * \ingroup stlext_grp
23  */
24 namespace metaprogramming
25 {
26 /** \addtogroup stlext_grp
27  * @{ */
28 
29 /** An object for deleting pointers (intended for STL algorithms) */
31 {
32  template <typename T>
33  inline void operator()(const T* ptr)
34  {
35  delete ptr;
36  }
37 };
38 
39 /** A function which deletes a container of pointers. */
40 template <typename T>
41 inline void DeleteContainer(T& container)
42 {
43  for_each(container.begin(), container.end(), ObjectDelete());
44 }
45 
46 // NOTE: when using this algorithm with for_each, replace the whole line with:
47 // for_each(bypassPointer(<beginning iterator>),bypassPointer(<ending
48 // iterator>),mem_fun_ref(&<NonPointerBaseClass>::clear)).
49 /** An object for clearing an object (invokes its method "->clear()") given a
50  * pointer or smart-pointer, intended for being used in STL algorithms. */
52 {
53  template <typename T>
54  inline void operator()(T& ptr)
55  {
56  if (ptr) ptr->clear();
57  }
58 };
59 
60 // NOTE: replace this with mem_fun_ref(&<BaseClass>::clear).
61 /** An object for clearing an object (invokes its method ".clear()") given a
62  * pointer or smart-pointer, intended for being used in STL algorithms. */
64 {
65  template <typename T>
66  inline void operator()(T& ptr)
67  {
68  ptr.reset();
69  }
70 };
71 
72 /** An object for clearing an object->second (invokes its method "clear()")
73  * given a pointer or smart-pointer, intended for being used in STL algorithms.
74  */
76 {
77  template <typename T>
78  inline void operator()(T obj)
79  {
80  obj.second.reset();
81  }
82 };
83 
84 /** An object for transforming between types/classes, intended for being used in
85  * STL algorithms.
86  * Example of usage:
87  * \code
88  * vector<int> v1(10); // Input
89  * vector<double> v2(10); // Output
90  * std::transform(v1.begin(),v1.end(), v2.begin(), ObjectConvert<double> );
91  * \endcode
92  */
93 template <typename TARGET_TYPE>
95 {
96  template <typename T>
97  inline TARGET_TYPE operator()(const T& val)
98  {
99  return TARGET_TYPE(val);
100  }
101 };
102 
103 // NOTE: replace with mem_fun_ref(&CSerializable::make_unique)
104 /** An object for making smart pointers unique (ie, making copies if necessary),
105  * intended for being used in STL algorithms. */
107 {
108  template <typename T>
109  inline void operator()(T& ptr)
110  {
111  ptr.reset(dynamic_cast<typename T::element_type*>(ptr->clone()));
112  }
113 };
114 
115 /** An object for making smart pointers unique (ie, making copies if necessary),
116  * intended for being used in STL algorithms. */
118 {
119  template <typename T>
120  inline void operator()(T& ptr)
121  {
122  ptr.first.reset(
123  dynamic_cast<typename T::first_type::element_type*>(
124  ptr.first->clone()));
125  ptr.second.reset(
126  dynamic_cast<typename T::second_type::element_type*>(
127  ptr.first->clone()));
128  }
129 };
130 
131 // NOTE: replace with mem_fun_ref(&CSerializable::reset)
132 /** An object for making smart pointers unique (ie, making copies if necessary),
133  * intended for being used in STL algorithms. */
134 template <typename T>
136 {
137  typedef T argument_type;
138  typedef void result_type;
139  inline void operator()(T& ptr) { ptr.reset(); }
140 };
141 
142 /** Behaves like std::copy but allows the source and target iterators to be of
143  * different types through static typecasting.
144  * \note As in std::copy, the target iterator must point to the first "slot"
145  * where to put the first transformed element, and sufficient space must be
146  * allocated in advance.
147  * \sa copy_container_typecasting
148  */
149 template <typename it_src, typename it_dst>
150 inline void copy_typecasting(it_src first, it_src last, it_dst target)
151 {
152  for (it_src i = first; i != last; ++i, ++target)
153  *target = static_cast<typename it_dst::value_type>(*i);
154 }
155 
156 /** Copy all the elements in a container (vector, deque, list) into a different
157  * one performing the appropriate typecasting.
158  * The target container is automatically resized to the appropriate size, and
159  * previous contents are lost.
160  * This can be used to assign std::vector's of different types:
161  * \code
162  * std::vector<int> vi(10);
163  * std::vector<float> vf;
164  * vf = vi; // Compiler error
165  * mrpt::utils::metaprogramming::copy_container_typecasting(v1,vf); // Ok
166  * \endcode
167  */
168 template <typename src_container, typename dst_container>
170  const src_container& src, dst_container& trg)
171 {
172  trg.resize(src.size());
173  typename src_container::const_iterator i = src.begin();
174  typename src_container::const_iterator last = src.end();
175  typename dst_container::iterator target = trg.begin();
176  for (; i != last; ++i, ++target)
177  *target = static_cast<typename dst_container::value_type>(*i);
178 }
179 
180 /** This class bypasses pointer access in iterators to pointers, thus allowing
181  * the use of algorithms that expect an object of class T with containers of
182  * T*.
183  * Although it may be used directly, use the bypassPointer function for better
184  * results and readability (since it most probably won't require template
185  * arguments).
186  */
187 template <typename T, typename U>
189 {
190  private:
192 
193  public:
194  typedef typename T::iterator_category iterator_category;
195  typedef U value_type;
196  typedef typename T::difference_type difference_type;
197  typedef U* pointer;
198  typedef U& reference;
199  inline MemoryBypasserIterator(const T& bi) : baseIterator(bi) {}
200  inline reference operator*() { return *(*baseIterator); }
202  {
203  ++baseIterator;
204  return *this;
205  }
207  {
208  MemoryBypasserIterator it = *this;
209  ++baseIterator;
210  return it;
211  }
213  {
214  --baseIterator;
215  return *this;
216  }
218  {
219  MemoryBypasserIterator it = *this;
220  --baseIterator;
221  return *this;
222  }
224  {
225  baseIterator += off;
226  return *this;
227  }
229  {
230  return (MemoryBypasserIterator<T, U>(*this)) += off;
231  }
233  {
234  baseIterator -= off;
235  return *this;
236  }
238  {
239  return (MemoryBypasserIterator<T, U>(*this)) -= off;
240  }
242  const MemoryBypasserIterator<T, U>& it) const
243  {
244  return baseIterator - it.baseIterator;
245  }
247  {
248  return *(this + off);
249  }
250  inline bool operator==(const MemoryBypasserIterator<T, U>& i) const
251  {
252  return baseIterator == i.baseIterator;
253  }
254  inline bool operator!=(const MemoryBypasserIterator<T, U>& i) const
255  {
256  return baseIterator != i.baseIterator;
257  }
258  inline bool operator<(const MemoryBypasserIterator<T, U>& i) const
259  {
260  return baseIterator < i.baseIterator;
261  }
262 };
263 
264 /** Sintactic sugar for MemoryBypasserIterator.
265  * For example, having the following declarations:
266  * vector<double *> vec;
267  * void modifyVal(double &v);
268  * The following sentence is not legal:
269  * for_each(vec.begin(),vec.end(),&modifyVal)
270  * But this one is:
271  * for_each(bypassPointer(vec.begin()),bypassPointer(vec.end()),&modifyVal)
272  */
273 template <typename U, typename T>
274 inline MemoryBypasserIterator<T, U> bypassPointer(const T& baseIterator)
275 {
276  return MemoryBypasserIterator<T, U>(baseIterator);
277 }
278 
279 /** This template encapsulates a binary member function and a single object into
280  * a
281  * function expecting the two parameters of the member function.
282  * Don't use directly. Use the wrapMember function instead to avoid explicit
283  * template instantiation.
284  */
285 template <typename T, typename U1, typename U2, typename V>
287 {
288  private:
289  typedef T (V::*MemberFunction)(U1, U2);
290  V& obj;
292 
293  public:
296  typedef T result_type;
298  {
299  }
300  inline T operator()(U1 p1, U2 p2) { return (obj.*func)(p1, p2); }
301 };
302 /** This template encapsulates an unary member function and a single object into
303  * a
304  * function expecting the parameter of the member function.
305  * Don't use directly. Use the wrapMember function instead.
306  */
307 template <typename T, typename U, typename V>
309 {
310  private:
311  typedef T (V::*MemberFunction)(U);
312  V& obj;
314 
315  public:
316  typedef U argument_type;
317  typedef T result_type;
319  {
320  }
321  inline T operator()(U p) { return (obj.*func)(p); }
322 };
323 /** This template encapsulates a member function without arguments and a single
324  * object into a function.
325  * Don't use directly. Use the wrapMember function instead.
326  */
327 template <typename T, typename V>
329 {
330  private:
331  typedef T (V::*MemberFunction)(void);
332  V& obj;
334 
335  public:
336  inline MemberFunctionWrapper(V& o, MemberFunction f) : obj(o), func(f) {}
337  inline T operator()() { return (obj.*func)(); }
338 };
339 /** This function creates a function from an object and a member function.
340  * It has three overloads, for zero, one and two parameters in the function.
341  */
342 template <typename T, typename U1, typename U2, typename V>
344  V& obj, T (V::*fun)(U1, U2))
345 {
347 }
348 template <typename T, typename U, typename V>
350 {
352 }
353 template <typename T, typename V>
354 inline MemberFunctionWrapper<T, V> wrapMember(V& obj, T (V::*fun)(void))
355 {
356  return MemberFunctionWrapper<T, V>(obj, fun);
357 }
358 
359 /** Equivalent of std::bind1st for functions with non-const arguments.
360  */
361 template <typename Op>
363 {
364  private:
365  Op& op;
366  typename Op::first_argument_type& val;
367 
368  public:
369  typedef typename Op::second_argument_type argument_type;
370  typedef typename Op::result_type result_type;
371  NonConstBind1st(Op& o, typename Op::first_argument_type& t) : op(o), val(t)
372  {
373  }
374  inline result_type operator()(argument_type& s) { return op(val, s); }
375 };
376 /** Use this function instead of directly calling NonConstBind1st.
377  */
378 template <typename Op>
380  Op& o, typename Op::first_argument_type& t)
381 {
382  return NonConstBind1st<Op>(o, t);
383 }
384 /** Equivalent of std::bind2nd for functions with non-const arguments.
385  */
386 template <typename Op>
388 {
389  private:
390  Op& op;
391  typename Op::second_argument_type& val;
392 
393  public:
394  typedef typename Op::first_argument_type argument_type;
395  typedef typename Op::result_type result_type;
396  NonConstBind2nd(Op& o, typename Op::second_argument_type& t) : op(o), val(t)
397  {
398  }
399  inline result_type operator()(argument_type& f) { return op(f, val); }
400 };
401 /** Do not directly use the NonConstBind2nd class directly. Use this function.
402  */
403 template <typename Op>
405  Op& o, typename Op::second_argument_type& t)
406 {
407  return NonConstBind2nd<Op>(o, t);
408 }
409 
410 /** @} */ // end of grouping
411 
412 } // end metaprogramming
413 } // End of namespace
414 } // end of namespace
415 #endif
NonConstBind2nd< Op > nonConstBind2nd(Op &o, typename Op::second_argument_type &t)
Do not directly use the NonConstBind2nd class directly.
MemoryBypasserIterator< T, U > & operator+=(difference_type off)
GLdouble GLdouble t
Definition: glext.h:3689
An object for making smart pointers unique (ie, making copies if necessary), intended for being used ...
An object for making smart pointers unique (ie, making copies if necessary), intended for being used ...
This class bypasses pointer access in iterators to pointers, thus allowing the use of algorithms that...
MemoryBypasserIterator< T, U > operator-(difference_type off) const
Equivalent of std::bind1st for functions with non-const arguments.
MemoryBypasserIterator< T, U > operator++(int)
GLint * first
Definition: glext.h:3827
MemoryBypasserIterator< T, U > & operator--()
Scalar * iterator
Definition: eigen_plugins.h:26
bool operator!=(const MemoryBypasserIterator< T, U > &i) const
const Scalar * const_iterator
Definition: eigen_plugins.h:27
result_type operator()(argument_type &f)
GLdouble s
Definition: glext.h:3676
GLuint src
Definition: glext.h:7278
NonConstBind1st< Op > nonConstBind1st(Op &o, typename Op::first_argument_type &t)
Use this function instead of directly calling NonConstBind1st.
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
void DeleteContainer(T &container)
A function which deletes a container of pointers.
MemoryBypasserIterator< T, U > & operator++()
An object for clearing an object (invokes its method ".clear()") given a pointer or smart-pointer...
bool operator==(const MemoryBypasserIterator< T, U > &i) const
This template encapsulates a member function without arguments and a single object into a function...
reference operator[](difference_type off) const
int val
Definition: mrpt_jpeglib.h:955
NonConstBind2nd(Op &o, typename Op::second_argument_type &t)
difference_type operator-(const MemoryBypasserIterator< T, U > &it) const
An object for clearing an object (invokes its method "->clear()") given a pointer or smart-pointer...
Equivalent of std::bind2nd for functions with non-const arguments.
MemoryBypasserIterator< T, U > operator+(difference_type off) const
An object for making smart pointers unique (ie, making copies if necessary), intended for being used ...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void copy_typecasting(it_src first, it_src last, it_dst target)
Behaves like std::copy but allows the source and target iterators to be of different types through st...
MemoryBypasserIterator< T, U > bypassPointer(const T &baseIterator)
Sintactic sugar for MemoryBypasserIterator.
An object for clearing an object->second (invokes its method "clear()") given a pointer or smart-poin...
An object for transforming between types/classes, intended for being used in STL algorithms.
BinaryMemberFunctionWrapper< T, U1, U2, V > wrapMember(V &obj, T(V::*fun)(U1, U2))
This function creates a function from an object and a member function.
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
NonConstBind1st(Op &o, typename Op::first_argument_type &t)
An object for deleting pointers (intended for STL algorithms)
This template encapsulates an unary member function and a single object into a function expecting the...
GLfloat GLfloat p
Definition: glext.h:6305
This template encapsulates a binary member function and a single object into a function expecting the...
void copy_container_typecasting(const src_container &src, dst_container &trg)
Copy all the elements in a container (vector, deque, list) into a different one performing the approp...
MemoryBypasserIterator< T, U > & operator-=(difference_type off)
result_type operator()(argument_type &s)
MemoryBypasserIterator< T, U > operator--(int)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019