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
15namespace 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>
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;
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) {}
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 }
185 baseIterator+=off;
186 return *this;
187 }
189 return (MemoryBypasserIterator<T,U>(*this))+=off;
190 }
192 baseIterator-=off;
193 return *this;
194 }
196 return (MemoryBypasserIterator<T,U>(*this))-=off;
197 }
199 return baseIterator-it.baseIterator;
200 }
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;
238 public:
241 typedef T result_type;
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;
256 public:
257 typedef U argument_type;
258 typedef T result_type;
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;
273 public:
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) {}
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) {}
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
A smart pointer to a CObject object.
Definition CObject.h:33
This template encapsulates a binary member function and a single object into a function expecting the...
This template encapsulates a member function without arguments and a single object into a function.
This class bypasses pointer access in iterators to pointers, thus allowing the use of algorithms that...
bool operator==(const MemoryBypasserIterator< T, U > &i) const
MemoryBypasserIterator< T, U > operator--(int)
bool operator<(const MemoryBypasserIterator< T, U > &i) const
reference operator[](difference_type off) const
MemoryBypasserIterator< T, U > & operator-=(difference_type off)
bool operator!=(const MemoryBypasserIterator< T, U > &i) const
difference_type operator-(const MemoryBypasserIterator< T, U > &it) const
MemoryBypasserIterator< T, U > operator+(difference_type off) const
MemoryBypasserIterator< T, U > operator-(difference_type off) const
MemoryBypasserIterator< T, U > & operator+=(difference_type off)
MemoryBypasserIterator< T, U > operator++(int)
Equivalent of std::bind1st for functions with non-const arguments.
NonConstBind1st(Op &o, typename Op::first_argument_type &t)
Equivalent of std::bind2nd for functions with non-const arguments.
NonConstBind2nd(Op &o, typename Op::second_argument_type &t)
This template encapsulates an unary member function and a single object into a function expecting the...
EIGEN_STRONG_INLINE const AdjointReturnType t() const
Transpose.
MemoryBypasserIterator< T, U > bypassPointer(const T &baseIterator)
Sintactic sugar for MemoryBypasserIterator.
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...
NonConstBind2nd< Op > nonConstBind2nd(Op &o, typename Op::second_argument_type &t)
Do not directly use the NonConstBind2nd class directly.
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...
void DeleteContainer(T &container)
A function which deletes a container of pointers.
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.
NonConstBind1st< Op > nonConstBind1st(Op &o, typename Op::first_argument_type &t)
Use this function instead of directly calling NonConstBind1st.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
An object for clearing an object (invokes its method ".clear()") given a pointer or smart-pointer,...
An object for clearing an object (invokes its method "->clear()") given a pointer or smart-pointer,...
An object for clearing an object->second (invokes its method "clear()") given a pointer or smart-poin...
An object for making smart pointers unique (ie, making copies if necessary), intended for being used ...
void operator()(mrpt::utils::CObjectPtr &ptr)
An object for transforming between types/classes, intended for being used in STL algorithms.
An object for deleting pointers (intended for STL algorithms)
An object for making smart pointers unique (ie, making copies if necessary), intended for being used ...
void operator()(mrpt::utils::CObjectPtr &ptr)
An object for making smart pointers unique (ie, making copies if necessary), intended for being used ...



Page generated by Doxygen 1.9.8 for MRPT 1.4.0 SVN: at Wed Dec 6 15:06:50 UTC 2023