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