Main MRPT website > C++ reference for MRPT 1.4.0
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-2016, 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) */
30  struct ObjectDelete {
31  template<typename T>
32  inline void operator()(const T *ptr) {
33  delete ptr;
34  }
35  };
36 
37  /** A function which deletes a container of pointers. */
38  template<typename T> inline void DeleteContainer(T &container) {
39  for_each(container.begin(),container.end(),ObjectDelete());
40  }
41 
42  //NOTE: when using this algorithm with for_each, replace the whole line with:
43  // for_each(bypassPointer(<beginning iterator>),bypassPointer(<ending iterator>),mem_fun_ref(&<NonPointerBaseClass>::clear)).
44  /** An object for clearing an object (invokes its method "->clear()") given a pointer or smart-pointer, intended for being used in STL algorithms. */
45  struct ObjectClear {
46  template<typename T>
47  inline void operator()(T &ptr) {
48  if (ptr) ptr->clear();
49  }
50  };
51 
52  //NOTE: replace this with mem_fun_ref(&<BaseClass>::clear).
53  /** An object for clearing an object (invokes its method ".clear()") given a pointer or smart-pointer, intended for being used in STL algorithms. */
54  struct ObjectClear2 {
55  template<typename T>
56  inline void operator()(T &ptr){
57  ptr.clear();
58  }
59  };
60 
61  /** An object for clearing an object->second (invokes its method "clear()") given a pointer or smart-pointer, intended for being used in STL algorithms. */
63  template<typename T>
64  inline void operator()(T obj) {
65  obj.second.clear();
66  }
67  };
68 
69  /** An object for transforming between types/classes, intended for being used in STL algorithms.
70  * Example of usage:
71  * \code
72  * vector<int> v1(10); // Input
73  * vector<double> v2(10); // Output
74  * std::transform(v1.begin(),v1.end(), v2.begin(), ObjectConvert<double> );
75  * \endcode
76  */
77  template <typename TARGET_TYPE>
78  struct ObjectConvert {
79  template<typename T>
80  inline TARGET_TYPE operator()(const T &val) {
81  return TARGET_TYPE(val);
82  }
83  };
84 
85  //NOTE: replace with mem_fun_ref(&CSerializable::make_unique)
86  /** An object for making smart pointers unique (ie, making copies if necessary), intended for being used in STL algorithms. */
89  typedef void result_type;
90  inline void operator()(mrpt::utils::CObjectPtr &ptr) {
91  ptr.make_unique();
92  }
93  };
94 
95  /** An object for making smart pointers unique (ie, making copies if necessary), intended for being used in STL algorithms. */
97  template <typename T>
98  inline void operator()(T &ptr) {
99  ptr.first.make_unique();
100  ptr.second.make_unique();
101  }
102  };
103 
104  //NOTE: replace with mem_fun_ref(&CSerializable::clear_unique)
105  /** An object for making smart pointers unique (ie, making copies if necessary), intended for being used in STL algorithms. */
108  typedef void result_type;
110  {
111  ptr.clear_unique();
112  }
113  };
114 
115  /** Behaves like std::copy but allows the source and target iterators to be of different types through static typecasting.
116  * \note As in std::copy, the target iterator must point to the first "slot" where to put the first transformed element, and sufficient space must be allocated in advance.
117  * \sa copy_container_typecasting
118  */
119  template<typename it_src, typename it_dst>
120  inline void copy_typecasting(it_src first, it_src last,it_dst target)
121  {
122  for (it_src i=first; i!=last ; ++i,++target)
123  *target = static_cast<typename it_dst::value_type>(*i);
124  }
125 
126  /** Copy all the elements in a container (vector, deque, list) into a different one performing the appropriate typecasting.
127  * The target container is automatically resized to the appropriate size, and previous contents are lost.
128  * This can be used to assign std::vector's of different types:
129  * \code
130  * std::vector<int> vi(10);
131  * std::vector<float> vf;
132  * vf = vi; // Compiler error
133  * mrpt::utils::metaprogramming::copy_container_typecasting(v1,vf); // Ok
134  * \endcode
135  */
136  template<typename src_container, typename dst_container>
137  inline void copy_container_typecasting(const src_container &src, dst_container &trg)
138  {
139  trg.resize( src.size() );
140  typename src_container::const_iterator i = src.begin();
141  typename src_container::const_iterator last = src.end();
142  typename dst_container::iterator target = trg.begin();
143  for ( ; i!=last ; ++i,++target)
144  *target = static_cast<typename dst_container::value_type>(*i);
145  }
146 
147  /** This class bypasses pointer access in iterators to pointers, thus allowing
148  * the use of algorithms that expect an object of class T with containers of T*.
149  * Although it may be used directly, use the bypassPointer function for better
150  * results and readability (since it most probably won't require template
151  * arguments).
152  */
153  template<typename T,typename U> class MemoryBypasserIterator {
154  private:
156  public:
157  typedef typename T::iterator_category iterator_category;
158  typedef U value_type;
159  typedef typename T::difference_type difference_type;
160  typedef U *pointer;
161  typedef U &reference;
162  inline MemoryBypasserIterator(const T &bi):baseIterator(bi) {}
163  inline reference operator*() {
164  return *(*baseIterator);
165  }
167  ++baseIterator;
168  return *this;
169  }
171  MemoryBypasserIterator it=*this;
172  ++baseIterator;
173  return it;
174  }
176  --baseIterator;
177  return *this;
178  }
180  MemoryBypasserIterator it=*this;
181  --baseIterator;
182  return *this;
183  }
184  inline MemoryBypasserIterator<T,U> &operator+=(difference_type off) {
185  baseIterator+=off;
186  return *this;
187  }
188  inline MemoryBypasserIterator<T,U> operator+(difference_type off) const {
189  return (MemoryBypasserIterator<T,U>(*this))+=off;
190  }
191  inline MemoryBypasserIterator<T,U> &operator-=(difference_type off) {
192  baseIterator-=off;
193  return *this;
194  }
195  inline MemoryBypasserIterator<T,U> operator-(difference_type off) const {
196  return (MemoryBypasserIterator<T,U>(*this))-=off;
197  }
198  inline difference_type operator-(const MemoryBypasserIterator<T,U> &it) const {
199  return baseIterator-it.baseIterator;
200  }
201  inline reference operator[](difference_type off) const {
202  return *(this+off);
203  }
204  inline bool operator==(const MemoryBypasserIterator<T,U> &i) const {
205  return baseIterator==i.baseIterator;
206  }
207  inline bool operator!=(const MemoryBypasserIterator<T,U> &i) const {
208  return baseIterator!=i.baseIterator;
209  }
210  inline bool operator<(const MemoryBypasserIterator<T,U> &i) const {
211  return baseIterator<i.baseIterator;
212  }
213  };
214 
215  /** Sintactic sugar for MemoryBypasserIterator.
216  * For example, having the following declarations:
217  * vector<double *> vec;
218  * void modifyVal(double &v);
219  * The following sentence is not legal:
220  * for_each(vec.begin(),vec.end(),&modifyVal)
221  * But this one is:
222  * for_each(bypassPointer(vec.begin()),bypassPointer(vec.end()),&modifyVal)
223  */
224  template<typename U,typename T> inline MemoryBypasserIterator<T,U> bypassPointer(const T &baseIterator) {
225  return MemoryBypasserIterator<T,U>(baseIterator);
226  }
227 
228  /** This template encapsulates a binary member function and a single object into a
229  * function expecting the two parameters of the member function.
230  * Don't use directly. Use the wrapMember function instead to avoid explicit
231  * template instantiation.
232  */
233  template<typename T,typename U1,typename U2,typename V> class BinaryMemberFunctionWrapper {
234  private:
235  typedef T (V::*MemberFunction)(U1,U2);
236  V &obj;
237  MemberFunction func;
238  public:
241  typedef T result_type;
242  inline BinaryMemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
243  inline T operator()(U1 p1,U2 p2) {
244  return (obj.*func)(p1,p2);
245  }
246  };
247  /** This template encapsulates an unary member function and a single object into a
248  * function expecting the parameter of the member function.
249  * Don't use directly. Use the wrapMember function instead.
250  */
251  template<typename T,typename U,typename V> class UnaryMemberFunctionWrapper {
252  private:
253  typedef T (V::*MemberFunction)(U);
254  V &obj;
255  MemberFunction func;
256  public:
257  typedef U argument_type;
258  typedef T result_type;
259  inline UnaryMemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
260  inline T operator()(U p) {
261  return (obj.*func)(p);
262  }
263  };
264  /** This template encapsulates a member function without arguments and a single
265  * object into a function.
266  * Don't use directly. Use the wrapMember function instead.
267  */
268  template<typename T,typename V> class MemberFunctionWrapper {
269  private:
270  typedef T (V::*MemberFunction)(void);
271  V &obj;
272  MemberFunction func;
273  public:
274  inline MemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
275  inline T operator()() {
276  return (obj.*func)();
277  }
278  };
279  /** This function creates a function from an object and a member function.
280  * It has three overloads, for zero, one and two parameters in the function.
281  */
282  template<typename T,typename U1,typename U2,typename V> inline BinaryMemberFunctionWrapper<T,U1,U2,V> wrapMember(V &obj,T (V::*fun)(U1,U2)) {
284  }
285  template<typename T,typename U,typename V> inline UnaryMemberFunctionWrapper<T,U,V> wrapMember(V &obj,T (V::*fun)(U)) {
286  return UnaryMemberFunctionWrapper<T,U,V>(obj,fun);
287  }
288  template<typename T,typename V> inline MemberFunctionWrapper<T,V> wrapMember(V &obj,T (V::*fun)(void)) {
289  return MemberFunctionWrapper<T,V>(obj,fun);
290  }
291 
292  /** Equivalent of std::bind1st for functions with non-const arguments.
293  */
294  template<typename Op> class NonConstBind1st {
295  private:
296  Op &op;
297  typename Op::first_argument_type &val;
298  public:
299  typedef typename Op::second_argument_type argument_type;
300  typedef typename Op::result_type result_type;
301  NonConstBind1st(Op &o,typename Op::first_argument_type &t):op(o),val(t) {}
302  inline result_type operator()(argument_type &s) {
303  return op(val,s);
304  }
305  };
306  /** Use this function instead of directly calling NonConstBind1st.
307  */
308  template<typename Op> inline NonConstBind1st<Op> nonConstBind1st(Op &o,typename Op::first_argument_type &t) {
309  return NonConstBind1st<Op>(o,t);
310  }
311  /** Equivalent of std::bind2nd for functions with non-const arguments.
312  */
313  template<typename Op> class NonConstBind2nd {
314  private:
315  Op &op;
316  typename Op::second_argument_type &val;
317  public:
318  typedef typename Op::first_argument_type argument_type;
319  typedef typename Op::result_type result_type;
320  NonConstBind2nd(Op &o,typename Op::second_argument_type &t):op(o),val(t) {}
321  inline result_type operator()(argument_type &f) {
322  return op(f,val);
323  }
324  };
325  /** Do not directly use the NonConstBind2nd class directly. Use this function.
326  */
327  template<typename Op> inline NonConstBind2nd<Op> nonConstBind2nd(Op &o,typename Op::second_argument_type &t) {
328  return NonConstBind2nd<Op>(o,t);
329  }
330 
331  /** @} */ // end of grouping
332 
333  } // end metaprogramming
334  } // End of namespace
335 } // end of namespace
336 #endif
NonConstBind2nd< Op > nonConstBind2nd(Op &o, typename Op::second_argument_type &t)
Do not directly use the NonConstBind2nd class directly.
MemoryBypasserIterator< T, U > operator++(int)
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 ...
MemoryBypasserIterator< T, U > & operator++()
This class bypasses pointer access in iterators to pointers, thus allowing the use of algorithms that...
reference operator[](difference_type off) const
EIGEN_STRONG_INLINE const AdjointReturnType t() const
Transpose.
MemoryBypasserIterator< T, U > & operator+=(difference_type off)
Equivalent of std::bind1st for functions with non-const arguments.
Scalar * iterator
Definition: eigen_plugins.h:23
const Scalar * const_iterator
Definition: eigen_plugins.h:24
result_type operator()(argument_type &f)
NonConstBind1st< Op > nonConstBind1st(Op &o, typename Op::first_argument_type &t)
Use this function instead of directly calling NonConstBind1st.
void DeleteContainer(T &container)
A function which deletes a container of pointers.
An object for clearing an object (invokes its method ".clear()") given a pointer or smart-pointer...
A smart pointer to a CObject object.
Definition: CObject.h:32
MemoryBypasserIterator< T, U > & operator-=(difference_type off)
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.
This template encapsulates a member function without arguments and a single object into a function...
MemoryBypasserIterator< T, U > operator--(int)
MemoryBypasserIterator< T, U > bypassPointer(const T &baseIterator)
Sintactic sugar for MemoryBypasserIterator.
NonConstBind2nd(Op &o, typename Op::second_argument_type &t)
void operator()(mrpt::utils::CObjectPtr &ptr)
MemoryBypasserIterator< T, U > operator+(difference_type off) 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.
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...
An object for clearing an object->second (invokes its method "clear()") given a pointer or smart-poin...
MemoryBypasserIterator< T, U > operator-(difference_type off) const
void operator()(mrpt::utils::CObjectPtr &ptr)
difference_type operator-(const MemoryBypasserIterator< T, U > &it) const
An object for transforming between types/classes, intended for being used in STL algorithms.
bool operator!=(const MemoryBypasserIterator< T, U > &i) const
NonConstBind1st(Op &o, typename Op::first_argument_type &t)
MemoryBypasserIterator< T, U > & operator--()
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...
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...
result_type operator()(argument_type &s)
bool operator==(const MemoryBypasserIterator< T, U > &i) const



Page generated by Doxygen 1.8.11 for MRPT 1.4.0 SVN:Unversioned directory at Mon Jul 4 10:31:07 UTC 2016