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 copy_typecasting(src.begin(),src.end(),trg.begin());
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 template<typename T,typename U> class MemoryBypasserIterator {
00194 private:
00195 T baseIterator;
00196 public:
00197 typedef typename T::iterator_category iterator_category;
00198 typedef U value_type;
00199 typedef typename T::difference_type difference_type;
00200 typedef U *pointer;
00201 typedef U &reference;
00202 inline MemoryBypasserIterator(const T &bi):baseIterator(bi) {}
00203 inline reference operator*() {
00204 return *(*baseIterator);
00205 }
00206 inline MemoryBypasserIterator<T,U> &operator++() {
00207 ++baseIterator;
00208 return *this;
00209 }
00210 inline MemoryBypasserIterator<T,U> operator++(int) {
00211 MemoryBypasserIterator it=*this;
00212 ++baseIterator;
00213 return it;
00214 }
00215 inline MemoryBypasserIterator<T,U> &operator--() {
00216 --baseIterator;
00217 return *this;
00218 }
00219 inline MemoryBypasserIterator<T,U> operator--(int) {
00220 MemoryBypasserIterator it=*this;
00221 --baseIterator;
00222 return *this;
00223 }
00224 inline MemoryBypasserIterator<T,U> &operator+=(difference_type off) {
00225 baseIterator+=off;
00226 return *this;
00227 }
00228 inline MemoryBypasserIterator<T,U> operator+(difference_type off) const {
00229 return (MemoryBypasserIterator<T,U>(*this))+=off;
00230 }
00231 inline MemoryBypasserIterator<T,U> &operator-=(difference_type off) {
00232 baseIterator-=off;
00233 return *this;
00234 }
00235 inline MemoryBypasserIterator<T,U> operator-(difference_type off) const {
00236 return (MemoryBypasserIterator<T,U>(*this))-=off;
00237 }
00238 inline difference_type operator-(const MemoryBypasserIterator<T,U> &it) const {
00239 return baseIterator-it.baseIterator;
00240 }
00241 inline reference operator[](difference_type off) const {
00242 return *(this+off);
00243 }
00244 inline bool operator==(const MemoryBypasserIterator<T,U> &i) const {
00245 return baseIterator==i.baseIterator;
00246 }
00247 inline bool operator!=(const MemoryBypasserIterator<T,U> &i) const {
00248 return baseIterator!=i.baseIterator;
00249 }
00250 inline bool operator<(const MemoryBypasserIterator<T,U> &i) const {
00251 return baseIterator<i.baseIterator;
00252 }
00253 };
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 template<typename U,typename T> inline MemoryBypasserIterator<T,U> bypassPointer(const T &baseIterator) {
00265 return MemoryBypasserIterator<T,U>(baseIterator);
00266 }
00267
00268
00269
00270
00271
00272
00273 template<typename T,typename U1,typename U2,typename V> class BinaryMemberFunctionWrapper {
00274 private:
00275 typedef T (V::*MemberFunction)(U1,U2);
00276 V &obj;
00277 MemberFunction func;
00278 public:
00279 typedef U1 first_argument_type;
00280 typedef U2 second_argument_type;
00281 typedef T result_type;
00282 inline BinaryMemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
00283 inline T operator()(U1 p1,U2 p2) {
00284 return (obj.*func)(p1,p2);
00285 }
00286 };
00287
00288
00289
00290
00291 template<typename T,typename U,typename V> class UnaryMemberFunctionWrapper {
00292 private:
00293 typedef T (V::*MemberFunction)(U);
00294 V &obj;
00295 MemberFunction func;
00296 public:
00297 typedef U argument_type;
00298 typedef T result_type;
00299 inline UnaryMemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
00300 inline T operator()(U p) {
00301 return (obj.*func)(p);
00302 }
00303 };
00304
00305
00306
00307
00308 template<typename T,typename V> class MemberFunctionWrapper {
00309 private:
00310 typedef T (V::*MemberFunction)(void);
00311 V &obj;
00312 MemberFunction func;
00313 public:
00314 inline MemberFunctionWrapper(V &o,MemberFunction f):obj(o),func(f) {}
00315 inline T operator()() {
00316 return (obj.*func)();
00317 }
00318 };
00319
00320
00321
00322 template<typename T,typename U1,typename U2,typename V> inline BinaryMemberFunctionWrapper<T,U1,U2,V> wrapMember(V &obj,T (V::*fun)(U1,U2)) {
00323 return BinaryMemberFunctionWrapper<T,U1,U2,V>(obj,fun);
00324 }
00325 template<typename T,typename U,typename V> inline UnaryMemberFunctionWrapper<T,U,V> wrapMember(V &obj,T (V::*fun)(U)) {
00326 return UnaryMemberFunctionWrapper<T,U,V>(obj,fun);
00327 }
00328 template<typename T,typename V> inline MemberFunctionWrapper<T,V> wrapMember(V &obj,T (V::*fun)(void)) {
00329 return MemberFunctionWrapper<T,V>(obj,fun);
00330 }
00331
00332
00333
00334 template<typename Op> class NonConstBind1st {
00335 private:
00336 Op &op;
00337 typename Op::first_argument_type &val;
00338 public:
00339 typedef typename Op::second_argument_type argument_type;
00340 typedef typename Op::result_type result_type;
00341 NonConstBind1st(Op &o,typename Op::first_argument_type &t):op(o),val(t) {}
00342 inline result_type operator()(argument_type &s) {
00343 return op(val,s);
00344 }
00345 };
00346
00347
00348 template<typename Op> inline NonConstBind1st<Op> nonConstBind1st(Op &o,typename Op::first_argument_type &t) {
00349 return NonConstBind1st<Op>(o,t);
00350 }
00351
00352
00353 template<typename Op> class NonConstBind2nd {
00354 private:
00355 Op &op;
00356 typename Op::second_argument_type &val;
00357 public:
00358 typedef typename Op::first_argument_type argument_type;
00359 typedef typename Op::result_type result_type;
00360 NonConstBind2nd(Op &o,typename Op::second_argument_type &t):op(o),val(t) {}
00361 inline result_type operator()(argument_type &f) {
00362 return op(f,val);
00363 }
00364 };
00365
00366
00367 template<typename Op> inline NonConstBind2nd<Op> nonConstBind2nd(Op &o,typename Op::second_argument_type &t) {
00368 return NonConstBind2nd<Op>(o,t);
00369 }
00370
00371 }
00372 }
00373 }
00374 #endif