Go to the documentation of this file.00001
00009 #ifndef __rtslam_parents_H__
00010 #define __rtslam_parents_H__
00011
00012 #include <list>
00013 #include <vector>
00014 #include <iostream>
00015 #include <boost/smart_ptr.hpp>
00016 #include <boost/bind.hpp>
00017
00018 #include "rtslam/rtSlam.hpp"
00019
00020
00021 namespace jafar {
00026 namespace rtslam {
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 template<class Child>
00039 class ParentOf {
00040 public:
00041 typedef boost::shared_ptr<Child> Child_ptr;
00042 typedef std::list<Child_ptr> ChildList;
00043
00044 public:
00045 ChildList childList;
00046
00047 public:
00048 ~ParentOf(void) {
00049
00050 }
00051
00052 void registerChild(const Child_ptr & ptr) {
00053 childList.push_back(ptr);
00054 }
00055 void unregisterChild(const Child_ptr & ptr) {
00056
00057 childList.remove(ptr);
00058
00059 }
00060
00061 void display(std::ostream& os) const {
00062 os << "PTR LIST [ ";
00063 for (typename ChildList::const_iterator iter = childList.begin(); iter
00064 != childList.end(); ++iter) {
00065 os << iter->get() << " ";
00066 }
00067 os << " ]";
00068 }
00069 };
00070
00071
00072
00073
00074
00075 #define ENABLE_ACCESS_TO_CHILDREN(Child,typeName,accessName) \
00076 public: typedef ParentOf<Child>::ChildList typeName##List; \
00077 typeName##List & accessName##List( void ) \
00078 { return ParentOf<Child>::childList; } \
00079 const typeName##List & accessName##List( void ) const \
00080 { return ParentOf<Child>::childList; } \
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 template<class Parent>
00092 class ChildOf {
00093 public:
00094 typedef boost::weak_ptr<Parent> Parent_wptr;
00095 typedef boost::shared_ptr<Parent> Parent_ptr;
00096
00097 private:
00098 Parent_wptr parent_wptr;
00099
00100 public:
00101
00103 ~ChildOf(void) {
00104 unlinkFromParent();
00105 }
00106
00107 void linkToParent(const boost::shared_ptr<Parent> & ptr) {
00108 parent_wptr = ptr;
00109 }
00111 void unlinkFromParent(void) {
00112 parent_wptr.reset();
00113 }
00114
00117 Parent_ptr parentPtr(void) {
00118 Parent_ptr sptr = parent_wptr.lock();
00119 if (!sptr) {
00120 std::cerr << __FILE__ << ":" << __LINE__ << " ChildOf::parentPtr threw weak" << std::endl;
00121 throw "WEAK";
00122 }
00123 return sptr;
00124 }
00125 const Parent_ptr parentPtr(void) const {
00126 Parent_ptr sptr = parent_wptr.lock();
00127 if (!sptr) {
00128 std::cerr << __FILE__ << ":" << __LINE__ << " ChildOf::parentPtr threw weak" << std::endl;
00129 throw "WEAK";
00130 }
00131 return sptr;
00132 }
00133 Parent& parent(void) {
00134 Parent_ptr sptr = parent_wptr.lock();
00135 if (!sptr) {
00136 std::cerr << __FILE__ << ":" << __LINE__ << " ChildOf::parent threw weak" << std::endl;
00137 throw "WEAK";
00138 }
00139 return *sptr;
00140 }
00141 const Parent& parent(void) const {
00142 Parent_ptr sptr = parent_wptr.lock();
00143 if (!sptr) {
00144 std::cerr << __FILE__ << ":" << __LINE__ << " ChildOf::parent const threw weak" << std::endl;
00145 throw "WEAK";
00146 }
00147 return *sptr;
00148 }
00149
00150 void display(std::ostream& os) const {
00151 os << this << "->" << parent_wptr.lock().get();
00152 }
00153
00154 };
00155
00156
00157
00158
00159
00160
00161
00162
00163 #define ENABLE_LINK_TO_FATHER(Parent,Child) \
00164 public: void linkToParent( boost::shared_ptr<Parent> ptr ) \
00165 { \
00166 ChildOf<Parent>::linkToParent(ptr); \
00167 ptr->ParentOf<Child>::registerChild(shared_from_this()); \
00168 }
00169
00170
00171
00172 #define ENABLE_LINK_TO_PARENT(Parent,name,Child) \
00173 public: void linkToParent##name( boost::shared_ptr<Parent> ptr ) \
00174 { \
00175 ChildOf<Parent>::linkToParent(ptr); \
00176 ptr->ParentOf<Child>::registerChild(shared_from_this()); \
00177 }
00178
00179
00180
00181
00182
00183 #define ENABLE_ACCESS_TO_FATHER(Parent) \
00184 public: \
00185 boost::shared_ptr<Parent> father##Ptr( void ) \
00186 { return ChildOf<Parent>::parentPtr(); } \
00187 const boost::shared_ptr<Parent> father##Ptr( void ) const \
00188 { return ChildOf<Parent>::parentPtr(); } \
00189 Parent& father( void ) \
00190 { return ChildOf<Parent>::parent(); } \
00191 const Parent& father( void ) const \
00192 { return ChildOf<Parent>::parent(); }
00193
00194
00195
00196
00197 #define ENABLE_ACCESS_TO_PARENT(Parent,accessName) \
00198 public: \
00199 boost::shared_ptr<Parent> accessName##Ptr( void ) \
00200 { return ChildOf<Parent>::parentPtr(); } \
00201 const boost::shared_ptr<Parent> accessName##Ptr( void ) const \
00202 { return ChildOf<Parent>::parentPtr(); } \
00203 Parent& accessName( void ) \
00204 { return ChildOf<Parent>::parent(); } \
00205 const Parent& accessName( void ) const \
00206 { return ChildOf<Parent>::parent(); }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 template<class Parent>
00222 class SpecificChildOf {
00223 public:
00224 typedef boost::weak_ptr<Parent> Parent_wptr;
00225 typedef boost::shared_ptr<Parent> Parent_ptr;
00226
00227 public:
00228 Parent_wptr parent_wptr;
00229
00230 public:
00231
00233 ~SpecificChildOf(void) {
00234 unlinkFromParent();
00235 }
00236
00237 template<class ParentAbstract>
00238 void linkToParentSpecific(const boost::shared_ptr<ParentAbstract> & ptr) {
00239 boost::shared_ptr<Parent> spec_ptr =
00240 SPTR_CAST<Parent>(ptr);
00241 parent_wptr = spec_ptr;
00242 }
00243
00244 void linkToParentSpecific(const boost::shared_ptr<Parent> & ptr) {
00245 parent_wptr = ptr;
00246 }
00247
00249 void unlinkFromParent(void) {
00250 parent_wptr.reset();
00251 }
00252
00255 Parent_ptr parentPtr(void) {
00256 Parent_ptr sptr = parent_wptr.lock();
00257 if (!sptr) {
00258 std::cerr << __FILE__ << ":" << __LINE__ << " SpecificChildOf::parentPtr threw weak" << std::endl;
00259 throw "WEAK";
00260 }
00261 return sptr;
00262 }
00263 Parent& parent(void) {
00264 Parent_ptr sptr = parent_wptr.lock();
00265 if (!sptr) {
00266 std::cerr << __FILE__ << ":" << __LINE__ << " SpecificChildOf::parent threw weak" << std::endl;
00267 throw "WEAK";
00268 }
00269 return *sptr;
00270 }
00271 const Parent& parent(void) const {
00272 Parent_ptr sptr = parent_wptr.lock();
00273 if (!sptr) {
00274 std::cerr << __FILE__ << ":" << __LINE__ << " SpecificChildOf::parent const threw weak" << std::endl;
00275 throw "WEAK";
00276 }
00277 return *sptr;
00278 }
00279
00280 void display(std::ostream& os) const {
00281 os << this << "->" << parent_wptr.lock().get();
00282 }
00283
00284 };
00285
00295 #define ENABLE_LINK_TO_SPECIFIC_FATHER(ParentGen,ParentSpec,Child) \
00296 public: void linkToParent( const boost::shared_ptr<ParentGen>& ptr ) \
00297 { \
00298 ChildOf<ParentGen>::linkToParent( ptr ); \
00299 SpecificChildOf<ParentSpec>::linkToParentSpecific( ptr ); \
00300 ptr->ParentOf<Child>::registerChild(shared_from_this()); \
00301 } \
00302 void linkToParent( const boost::shared_ptr<ParentSpec>& ptr ) \
00303 { \
00304 ChildOf<ParentGen>::linkToParent( ptr ); \
00305 SpecificChildOf<ParentSpec>::linkToParentSpecific( ptr ); \
00306 ptr->ParentOf<Child>::registerChild(shared_from_this()); \
00307 }
00308
00309 #define ENABLE_LINK_TO_SPECIFIC_PARENT(ParentGen,ParentSpec,name,Child) \
00310 public: void linkToParent##name( const boost::shared_ptr<ParentGen>& ptr ) \
00311 { \
00312 ChildOf<ParentGen>::linkToParent( ptr ); \
00313 SpecificChildOf<ParentSpec>::linkToParentSpecific( ptr ); \
00314 ptr->ParentOf<Child>::registerChild(shared_from_this()); \
00315 } \
00316 void linkToParent##name( const boost::shared_ptr<ParentSpec>& ptr ) \
00317 { \
00318 ChildOf<ParentGen>::linkToParent( ptr ); \
00319 SpecificChildOf<ParentSpec>::linkToParentSpecific( ptr ); \
00320 ptr->ParentOf<Child>::registerChild(shared_from_this()); \
00321 }
00322
00323
00324
00325
00326 #define ENABLE_ACCESS_TO_SPECIFIC_PARENT(Parent,accessName) \
00327 public: boost::shared_ptr<Parent> accessName##Ptr( void ) \
00328 { return SpecificChildOf<Parent>::parentPtr(); } \
00329 Parent& accessName( void ) \
00330 { return SpecificChildOf<Parent>::parent(); } \
00331 const Parent& accessName( void ) const \
00332 { return SpecificChildOf<Parent>::parent(); }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 template<class Child>
00361 class WeakParentOf {
00362 public:
00363 typedef boost::shared_ptr<Child> Child_ptr;
00364 typedef boost::weak_ptr<Child> Child_wptr;
00365 typedef std::vector<Child_wptr> ChildList;
00366
00367 protected:
00368
00369
00370
00371
00372
00373
00374 template< class basic_iterator>
00375 class generic_iterator
00376 {
00377 public:
00378 typedef Child_ptr Insider;
00379
00380 protected:
00381 basic_iterator iter;
00382 private:
00383 generic_iterator( void ) {}
00384 public:
00385 generic_iterator( const basic_iterator& i ) : iter(i) {}
00386 generic_iterator& operator++ ( void ) { iter++; return *this; }
00387 generic_iterator& operator++ ( int ) { iter++; return *this; }
00388 friend bool operator== ( const generic_iterator & i1, const generic_iterator & i2 )
00389 { return i1.iter == i2.iter; }
00390 friend bool operator!= ( const generic_iterator & i1, const generic_iterator & i2 )
00391 { return i1.iter != i2.iter; }
00392 friend bool operator== ( const generic_iterator & i1, const basic_iterator & i2 )
00393 { return i1.iter == i2; }
00394 friend bool operator!= ( const generic_iterator & i1, const basic_iterator & i2 )
00395 { return i1.iter != i2; }
00396 friend bool operator== ( const basic_iterator & i1, const generic_iterator & i2 )
00397 { return i1 == i2.iter; }
00398 friend bool operator!= ( const basic_iterator & i1, const generic_iterator & i2 )
00399 { return i1 != i2.iter; }
00400
00401 operator bool ( void )
00402 { return (! iter->expired()); }
00403
00404 Insider operator* (void)
00405 {
00406 Insider ptr = iter->lock();
00407 if(! ptr )
00408 {
00409 std::cerr << __FILE__ << ":" << __LINE__ << " WeakParentOf::operator* threw weak" << std::endl;
00410 throw "WEAK";
00411 }
00412 return ptr;
00413 }
00414 };
00415
00416 typedef typename WeakParentOf<Child>::ChildList ExChildList;
00417 typedef typename WeakParentOf<Child>::ChildList::iterator basic_iterator;
00418 typedef typename WeakParentOf<Child>::ChildList::const_iterator basic_const_iterator;
00419
00420 public:
00421 typedef generic_iterator<basic_iterator> iterator;
00422 typedef generic_iterator<basic_const_iterator> const_iterator;
00423
00424 public:
00425 ChildList childList;
00426
00427 public:
00428 ~WeakParentOf(void) {
00429
00430 }
00431
00432 void registerChild(const Child_ptr & ptr) {
00433 Child_wptr wptr = ptr;
00434 childList.push_back(wptr);
00435 }
00436
00437
00438
00439 struct WeakPtrComparison
00440 {
00441 Child_ptr refptr;
00442 WeakPtrComparison( const Child_ptr & ptr ) : refptr(ptr) {}
00443 bool operator() (const Child_wptr & wptr)
00444 {
00445 Child_ptr ptr = wptr.lock();
00446 return refptr == ptr;
00447 }
00448 };
00449
00450
00451 void unregisterChild(const Child_ptr & ptr)
00452 {
00453 childList.erase(remove_if(childList.begin(), childList.end(),
00454 WeakPtrComparison(ptr) ),
00455 childList.end());
00456 }
00457
00458
00459
00460
00461
00462
00463 void cleanExpired( void )
00464 {
00465 childList.erase(remove_if(childList.begin(), childList.end(),
00466 boost::bind(&Child_wptr::expired,_1) ),
00467 childList.end());
00468 }
00469
00470 void display(std::ostream& os) const {
00471 os << "PTR LIST [ ";
00472 for ( const_iterator iter = childList.begin(); iter!= childList.end(); ++iter)
00473 {
00474 if( iter )
00475 {Child_ptr toto = *iter; os << toto.get() << " ";}
00476 else { os << "--expired-- ";}
00477 }
00478 os << " ]";
00479 }
00480 };
00481
00482
00483
00484
00485
00486 #define ENABLE_ACCESS_TO_WEAK_CHILDREN(Child,typeName,accessName) \
00487 public: typedef WeakParentOf<Child>::ChildList typeName##List; \
00488 typeName##List & accessName##List( void ) \
00489 { return WeakParentOf<Child>::childList; } \
00490 const typeName##List & accessName##List( void ) const \
00491 { return WeakParentOf<Child>::childList; }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 #define ENABLE_LINK_TO_WEAK_PARENT(Parent,Child) \
00505 void linkToWeakParent##Parent( boost::shared_ptr<Parent> ptr ) \
00506 { \
00507 ChildOf<Parent>::linkToParent(ptr); \
00508 ptr->WeakParentOf<Child>::registerChild \
00509 (boost::enable_shared_from_this<Child>::shared_from_this()); \
00510 }
00511
00512
00513
00514
00515
00516 #define UNREGISTER_FROM_WEAK_PARENT(Parent) \
00517 try { ChildOf<Parent>::parentPtr()->cleanExpired(); } \
00518 catch(const char *e) { if (strcmp(e,"WEAK")) throw e; }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 #define ENABLE_LINK_TO_WEAK_SPECIFIC_PARENT(ParentAbs,ParentSpec,ChildAbs,ChildSpec,name) \
00566 void linkToWeakParent##name( boost::shared_ptr<ParentSpec> ptr ) \
00567 { \
00568 ChildOf<ParentSpec>::linkToParent(ptr); \
00569 ptr->WeakParentOf<ChildSpec>::registerChild \
00570 (SPTR_CAST<ChildSpec>(shared_from_this())); \
00571 ChildOf<ParentAbs>::linkToParent(ptr); \
00572 ptr->WeakParentOf<ChildAbs>::registerChild(shared_from_this()); \
00573 }
00574
00575
00576
00577
00578 #define UNREGISTER_FROM_WEAK_SPECIFIC_PARENT(Parent,Child) \
00579 try { ChildOf<Parent>::parentPtr()->WeakParentOf<Child>::cleanExpired(); } \
00580 catch(const char *e) { if (strcmp(e,"WEAK")) throw e; }
00581
00582 }}
00583
00584 #endif // #ifndef __rtslam_parents_H__