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 metaprogramming_H
00029 #define metaprogramming_H
00030
00031 #include <mrpt/utils/CSerializable.h>
00032
00033 namespace mrpt
00034 {
00035 namespace utils
00036 {
00037
00038
00039
00040 namespace metaprogramming
00041 {
00042
00043
00044
00045
00046 struct ObjectDelete {
00047 template<typename T>
00048 inline void operator()(const T *ptr) {
00049 delete ptr;
00050 }
00051 };
00052
00053
00054 template<typename T> inline void DeleteContainer(T &container) {
00055 for_each(container.begin(),container.end(),ObjectDelete());
00056 }
00057
00058
00059
00060
00061 struct ObjectClear {
00062 template<typename T>
00063 inline void operator()(T &ptr) {
00064 if (ptr) ptr->clear();
00065 }
00066 };
00067
00068
00069
00070 struct ObjectClear2 {
00071 template<typename T>
00072 inline void operator()(T &ptr){
00073 ptr.clear();
00074 }
00075 };
00076
00077
00078 struct ObjectClearSecond {
00079 template<typename T>
00080 inline void operator()(T obj) {
00081 obj.second.clear();
00082 }
00083 };
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 template <typename TARGET_TYPE>
00094 struct ObjectConvert {
00095 template<typename T>
00096 inline TARGET_TYPE operator()(const T &val) {
00097 return TARGET_TYPE(val);
00098 }
00099 };
00100
00101
00102
00103 struct ObjectMakeUnique {
00104 typedef mrpt::utils::CObjectPtr argument_type;
00105 typedef void result_type;
00106 inline void operator()(mrpt::utils::CObjectPtr &ptr) {
00107 ptr.make_unique();
00108 }
00109 };
00110
00111
00112 struct ObjectPairMakeUnique {
00113 template <typename T>
00114 inline void operator()(T &ptr) {
00115 ptr.first.make_unique();
00116 ptr.second.make_unique();
00117 }
00118 };
00119
00120
00121
00122 struct ObjectClearUnique {
00123 typedef mrpt::utils::CObjectPtr argument_type;
00124 typedef void result_type;
00125 inline void operator()(mrpt::utils::CObjectPtr &ptr)
00126 {
00127 ptr.clear_unique();
00128 }
00129 };
00130
00131
00132 struct ObjectReadFromStream
00133 {
00134 private:
00135 CStream *m_stream;
00136 public:
00137 inline ObjectReadFromStream(CStream *stream) : m_stream(stream) { }
00138
00139
00140 template <typename T>
00141 inline void operator()(T &obj)
00142 {
00143 (*m_stream) >> obj;
00144 }
00145 };
00146
00147
00148 struct ObjectWriteToStream
00149 {
00150 private:
00151 CStream *m_stream;
00152 public:
00153 inline ObjectWriteToStream(CStream *stream) : m_stream(stream) { }
00154
00155
00156 template <typename T>
00157 inline void operator()(const T &ptr)
00158 {
00159 (*m_stream) << ptr;
00160 }
00161 };
00162
00163
00164
00165
00166
00167 template<typename it_src, typename it_dst>
00168 inline void copy_typecasting(it_src first, it_src last,it_dst target)
00169 {
00170 for (it_src i=first; i!=last ; ++i,++target)
00171 *target = static_cast<typename it_dst::value_type>(*i);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 template<typename src_container, typename dst_container>
00185 inline void copy_container_typecasting(const src_container &src, dst_container &trg)
00186 {
00187 trg.resize( src.size() );
00188 typename src_container::const_iterator i = src.begin();
00189 typename src_container::const_iterator last = src.end();
00190 typename dst_container::iterator target = trg.begin();
00191 for ( ; i!=last ; ++i,++target)
00192 *target = static_cast<typename dst_container::value_type>(*i);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 template<typename T,typename U> class MemoryBypasserIterator {
00202 private:
00203 T baseIterator;
00204 public:
00205 typedef typename T::iterator_category iterator_category;
00206 typedef U value_type;
00207 typedef typename T::difference_type difference_type;
00208 typedef U *pointer;
00209 typedef U &reference;
00210 inline MemoryBypasserIterator(const T &bi):baseIterator(bi) {}
00211 inline reference operator*() {
00212 return *(*baseIterator);
00213 }
00214 inline MemoryBypasserIterator<T,U> &operator++() {
00215 ++baseIterator;
00216 return *this;
00217 }
00218 inline MemoryBypasserIterator<T,U> operator++(int) {
00219 MemoryBypasserIterator it=*this;
00220 ++baseIterator;
00221 return it;
00222 }
00223 inline MemoryBypasserIterator<T,U> &operator--() {
00224 --baseIterator;
00225 return *this;
00226 }
00227 inline MemoryBypasserIterator<T,U> operator--(int) {
00228 MemoryBypasserIterator it=*this;
00229 --baseIterator;
00230 return *this;
00231 }
00232 inline MemoryBypasserIterator<T,U> &operator+=(difference_type off) {
00233 baseIterator+=off;
00234 return *this;
00235 }
00236 inline MemoryBypasserIterator<T,U> operator+(difference_type off) const {
00237 return (MemoryBypasserIterator<T,U>(*this))+=off;
00238 }
00239 inline MemoryBypasserIterator<T,U> &operator-=(difference_type off) {
00240 baseIterator-=off;
00241 return *this;
00242 }
00243 inline MemoryBypasserIterator<T,U> operator-(difference_type off) const {
00244 return (MemoryBypasserIterator<T,U>(*this))-=off;
00245 }
00246 inline difference_type operator-(const MemoryBypasserIterator<T,U> &it) const {
00247 return baseIterator-it.baseIterator;
00248 }
00249 inline reference operator[](difference_type off) const {
00250 return *(this+off);
00251 }
00252 inline bool operator==(const MemoryBypasserIterator<T,U> &i) const {
00253 return baseIterator==i.baseIterator;
00254 }
00255 inline bool operator!=(const MemoryBypasserIterator<T,U> &i) const {
00256 return baseIterator!=i.baseIterator;
00257 }
00258 inline bool operator<(const MemoryBypasserIterator<T,U> &i) const {
00259 return baseIterator<i.baseIterator;
00260 }
00261 };
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 template<typename U,typename T> inline MemoryBypasserIterator<T,U> bypassPointer(const T &baseIterator) {
00273 return MemoryBypasserIterator<T,U>(baseIterator);
00274 }
00275
00276
00277
00278
00279
00280
00281 template<typename T,typename U1,typename U2,typename V> class BinaryMemberFunctionWrapper {
00282 private:
00283 typedef T (V::*MemberFunction)(U1,U2);
00284 V &obj;
00285 MemberFunction func;
00286 public:
00287 typedef U1 first_argument_type;
00288 typedef U2 second_argument_type;
00289 typedef T result_type;
00290 inline BinaryMemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
00291 inline T operator()(U1 p1,U2 p2) {
00292 return (obj.*func)(p1,p2);
00293 }
00294 };
00295
00296
00297
00298
00299 template<typename T,typename U,typename V> class UnaryMemberFunctionWrapper {
00300 private:
00301 typedef T (V::*MemberFunction)(U);
00302 V &obj;
00303 MemberFunction func;
00304 public:
00305 typedef U argument_type;
00306 typedef T result_type;
00307 inline UnaryMemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
00308 inline T operator()(U p) {
00309 return (obj.*func)(p);
00310 }
00311 };
00312
00313
00314
00315
00316 template<typename T,typename V> class MemberFunctionWrapper {
00317 private:
00318 typedef T (V::*MemberFunction)(void);
00319 V &obj;
00320 MemberFunction func;
00321 public:
00322 inline MemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
00323 inline T operator()() {
00324 return (obj.*func)();
00325 }
00326 };
00327
00328
00329
00330 template<typename T,typename U1,typename U2,typename V> inline BinaryMemberFunctionWrapper<T,U1,U2,V> wrapMember(V &obj,T (V::*fun)(U1,U2)) {
00331 return BinaryMemberFunctionWrapper<T,U1,U2,V>(obj,fun);
00332 }
00333 template<typename T,typename U,typename V> inline UnaryMemberFunctionWrapper<T,U,V> wrapMember(V &obj,T (V::*fun)(U)) {
00334 return UnaryMemberFunctionWrapper<T,U,V>(obj,fun);
00335 }
00336 template<typename T,typename V> inline MemberFunctionWrapper<T,V> wrapMember(V &obj,T (V::*fun)(void)) {
00337 return MemberFunctionWrapper<T,V>(obj,fun);
00338 }
00339
00340
00341
00342 template<typename Op> class NonConstBind1st {
00343 private:
00344 Op &op;
00345 typename Op::first_argument_type &val;
00346 public:
00347 typedef typename Op::second_argument_type argument_type;
00348 typedef typename Op::result_type result_type;
00349 NonConstBind1st(Op &o,typename Op::first_argument_type &t):op(o),val(t) {}
00350 inline result_type operator()(argument_type &s) {
00351 return op(val,s);
00352 }
00353 };
00354
00355
00356 template<typename Op> inline NonConstBind1st<Op> nonConstBind1st(Op &o,typename Op::first_argument_type &t) {
00357 return NonConstBind1st<Op>(o,t);
00358 }
00359
00360
00361 template<typename Op> class NonConstBind2nd {
00362 private:
00363 Op &op;
00364 typename Op::second_argument_type &val;
00365 public:
00366 typedef typename Op::first_argument_type argument_type;
00367 typedef typename Op::result_type result_type;
00368 NonConstBind2nd(Op &o,typename Op::second_argument_type &t):op(o),val(t) {}
00369 inline result_type operator()(argument_type &f) {
00370 return op(f,val);
00371 }
00372 };
00373
00374
00375 template<typename Op> inline NonConstBind2nd<Op> nonConstBind2nd(Op &o,typename Op::second_argument_type &t) {
00376 return NonConstBind2nd<Op>(o,t);
00377 }
00378
00379
00380
00381 }
00382 }
00383 }
00384 #endif