Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

LCRTRelations.h

Go to the documentation of this file.
00001 #ifndef LCRTRelations_H
00002 #define LCRTRelations_H 1
00003 
00004 #include <iostream>
00005 #include <vector>
00006 #include <list>
00007 #include <map>
00008 
00009 namespace lcrtrel_helper{
00010 
00011   //------------------ internal helper typdefs, function and classes ----------
00012 
00013   template <bool B>
00014   struct can_call_ext{};
00015   template <>
00016   struct can_call_ext<true>{ static void check(){/* no_op */ } ; };
00017 
00018   /** Function pointer for delete function */
00019   typedef void (*DeleteFPtr)(void*) ;
00020 
00021   /** Simple init function for simple pointers */
00022   struct SimplePtrInit{ static void* init() { return 0 ; } } ;
00023 
00024   /** Empty delete function for pointers w/o ownership */
00025   struct NoDelete{ static void clean(void *v) { /* no_op */ } } ;
00026 
00027   /** Factory for objects of type  T*/
00028   template <class T>
00029   struct CreationPtrInit{ static void* init() { return new T ; } } ;
00030 
00031   /** Delete function for pointers w/ ownership.*/
00032   template <class T>
00033   struct DeletePtr{ static void clean(void *v) { delete (T*) v ; } } ;
00034 
00035 
00036   /** Delete function for containers of owned objects */
00037   template <class T>
00038   struct DeleteElements{
00039 
00040     static void clean(void *v) { 
00041       T* vec = static_cast<T*>(v) ;
00042       for( typename T::iterator it = vec->begin();it != vec->end(); ++it){
00043         delete *it ;
00044       }
00045       delete vec  ;    
00046     } 
00047   };
00048 
00049 
00050   /** Map of pointers to extension obbjects*/
00051   typedef std::map< unsigned , void * > PtrMap ;
00052 
00053   /** Vector of delete  functions */
00054   typedef std::vector< DeleteFPtr > DPtrVec ;
00055 
00056   /** Vector of pointers to extension obbjects*/
00057   //typedef std::vector< void * > PtrVec ;
00058 
00059 
00060   /** Base class for all extensions and relations */
00061   template <class U, class T , class I, class D, bool b>
00062   struct LCBaseTraits{
00063   
00064     typedef T*  ptr ;  /**<base pointer type  */
00065     typedef U tag ;    // this ensures that a new class instance is created for every user extension
00066   
00067     static const int allowed_to_call_ext = b ;
00068   
00069     static void clean(void *v) {
00070       D::clean( v ) ;
00071     }
00072     static ptr init() {
00073       return (ptr) I::init() ;
00074     }
00075     static DeleteFPtr deletePtr() { return  &clean ; }  ;
00076   };
00077 
00078 
00079   /** Base class for all extensions and relations of single objects */
00080   template <class U, class T , class I=SimplePtrInit, class D=NoDelete , bool b=1>
00081   struct LCBaseLinkTraits : public LCBaseTraits<U,T,I,D,b>{
00082 
00083     typedef LCBaseTraits<U,T,I,D,b> base ;
00084 
00085     typedef T*& ext_type ;                 // return value of  ext<>()
00086     typedef T*  rel_type ;                 // return value of  rel<>() 
00087     typedef typename base::ptr obj_ptr ;   // pointer to object
00088 
00089     static const bool is_container=false ;
00090   };
00091 
00092   /** Base class for all containers of extensions and relations, vectors, lists,... */
00093   template <class U, class T , class I=CreationPtrInit<T>, class D=DeletePtr<T> , bool b=1>
00094   struct LCBaseLinkContainerTraits : public LCBaseTraits<U,T,I,D,b>{
00095 
00096     typedef LCBaseTraits<U,T,I,D,b> base ;
00097 
00098     typedef       T*  ext_type ;              // return value of  ext<>()
00099     typedef const T*  rel_type ;              // return value of  rel<>() 
00100     typedef typename T::value_type obj_ptr ;  // pointer to object
00101 
00102     typedef typename T::iterator iterator ;
00103     typedef typename T::const_iterator const_iterator ;
00104 
00105     static const bool is_container=true ;
00106   };
00107 
00108 
00109   /** Helper class for relations */
00110   template <class U, class T> 
00111   struct RelationOneSide  : 
00112     public LCBaseLinkTraits<U,T,SimplePtrInit,NoDelete,false> {};
00113   
00114   
00115   /** Helper class for relations */
00116   template <class U, class T> 
00117   struct RelationManySide :
00118     public LCBaseLinkContainerTraits< U, std::list<T*>,
00119                                       CreationPtrInit< std::list<T*> > , 
00120                                       DeletePtr<std::list<T*> > ,false  > {};
00121   
00122   /** Helper class for relations */
00123   template <class U> struct FromRelation{} ;
00124   
00125   /** Helper class for relations */
00126   template <class U> struct ToRelation{} ;
00127   
00128   
00129   /** Helper class for biderectional relations provides the to and from type*/
00130   template <class From, class To>
00131   struct BiDirectional{
00132     typedef From from  ;
00133     typedef To   to  ;
00134   } ;
00135   
00136   
00137   /** Helper functions that treat single objects and containers */ 
00138   template <bool is_container>
00139   struct objorcont{
00140 
00141     template <class T, class S>
00142     inline static void add( T t, S s) { t->push_back( s )  ; }
00143 
00144     template <class T, class S>
00145     inline static void remove( T t, S s) { t->remove( s )  ; }
00146   };
00147 
00148 
00149   /** Helper functions specialization for single objects*/ 
00150   template <>
00151   struct objorcont<false>{
00152 
00153     template <class T, class S> 
00154     inline static void add( T& t, S s) { t = s ; }
00155 
00156     template <class T, class S>
00157     inline static void remove( T& t, S s) { t = 0 ; }
00158   };
00159 
00160   //-----------end of  internal helper typdefs, function and classes ----------
00161 
00162 
00163 } // end namespace lcrtrel_helper
00164 
00165 namespace lcrtrel{
00166 
00167   using namespace lcrtrel_helper ;
00168 
00169   /** Simple Extension -  pointer to an object of type T. 
00170    *  The class U needs to be the subclass  type, e.g.<br>
00171    *  struct MyAttributes : public LCExtension<MyAttributes,Attributes> {} ; <br>
00172    */
00173   template <class U, typename T> 
00174   struct LCExtension : public LCBaseLinkTraits< U, T > {};
00175 
00176   /** Simple Extension -  pointer to an object of type T where the ownership is taken over
00177    *  by the object holding the extension, i.e. it deletes the object when itself is deleted. 
00178    *  The class U needs to be the subclass  type, e.g.<br>
00179    *  struct MyAttributes : public LCExtension<MyAttributes,Attributes> {} ; <br>
00180    */
00181   template <class U, typename T> 
00182   class LCOwnedExtension : public LCBaseLinkTraits< U, T , SimplePtrInit , DeletePtr<T> > {};
00183 
00184 
00185   /** Extension vector holding pointers to objects of type T - no ownership of the objects is taken. */
00186   template <class U, class T> 
00187   class LCExtensionVector :
00188     public LCBaseLinkContainerTraits< U, std::vector<T*>,
00189                                       CreationPtrInit< std::vector<T*> > , 
00190                                       DeletePtr<std::vector<T*> > > {};
00191 
00192 
00193   /** Extension vector holding pointers to objects of type T - ownership of the objects is taken, i.e.
00194    *  all objects pointed to in the vector are deleted when the object itself is deleted.
00195    */
00196   template <class U, class T> 
00197   class LCOwnedExtensionVector : 
00198     public LCBaseLinkContainerTraits< U, std::vector<T*>,
00199                                       CreationPtrInit< std::vector<T*> > , 
00200                                       DeleteElements< std::vector<T*> > > {};
00201 
00202 
00203   /** Extension list holding pointers to objects of type T - no ownership of the objects is taken. */
00204   template <class U, class T> 
00205   class LCExtensionList :
00206     public LCBaseLinkContainerTraits< U, std::list<T*>,
00207                                       CreationPtrInit< std::list<T*> > , 
00208                                       DeletePtr<std::list<T*> > > {};
00209 
00210   /** Extension list holding pointers to objects of type T - ownership of the objects is taken, i.e.
00211    *  all objects pointed to in the vector are deleted when the object itself is deleted.
00212    */
00213   template <class U, class T> 
00214   class LCOwnedExtensionList : 
00215     public LCBaseLinkContainerTraits< U, std::list<T*>,
00216                                       CreationPtrInit< std::list<T*> > , 
00217                                       DeleteElements<  std::list<T*> > > {};
00218 
00219 
00220   /** One to one relation between two objects of type From and To */
00221   template <class U, class From, class To>
00222   struct LC1To1Relation : 
00223     public BiDirectional<RelationOneSide<FromRelation<U>,From>,
00224                          RelationOneSide<ToRelation<U>,To> > {
00225 
00226   } ; 
00227 
00228   /** One to many relation between one object of type From to many objects of type To */
00229   template <class U, class From, class To>
00230   struct LC1ToNRelation : 
00231     public BiDirectional<RelationOneSide<FromRelation<U>,From>,
00232                          RelationManySide<ToRelation<U>,To> > {
00233   } ; 
00234 
00235   /** Many to many relation between objects of type From to objects of type To */
00236   template <class U, class From, class To>
00237   struct LCNToNRelation : 
00238     public BiDirectional<RelationManySide<FromRelation<U>,From>,
00239                          RelationManySide<ToRelation<U>,To> > {
00240   } ; 
00241 
00242 
00243   /** Special Extension that allows to write int extensions directly (not through a pointer !). */
00244   template <class U >
00245   struct LCIntExtension{  // FIXME: need to check on 64 bit architecture...
00246     
00247     typedef int ptr ;  // base pointer type 
00248     
00249     typedef U tag ;     // this ensures that a new class instance is created for every user extension
00250     
00251     static const int allowed_to_call_ext = 1 ;
00252     
00253     static void clean(void *v) { }
00254 
00255     static ptr init() { 
00256       return 0 ; 
00257     }
00258     static DeleteFPtr deletePtr() { return  &clean ; }  ;
00259 
00260     typedef int& ext_type ;                
00261   };
00262 
00263 
00264   /** Special Extension that allows to write float extensions directly (not through a pointer !). */
00265   template <class U >
00266 
00267   struct LCFloatExtension{// FIXME: need to check on 64 bit architecture...
00268 
00269     typedef float  ptr ;  // base pointer type 
00270     typedef U tag ;     // this ensures that a new class instance is created for every user extension
00271     typedef float& ext_type ;     // return value of  ext<>()
00272   
00273     static const int allowed_to_call_ext = 1 ;
00274     static void clean(void *v) { }
00275     static ptr init() { return 0 ; }
00276     static DeleteFPtr deletePtr() { return  &clean ; }  ;
00277   };
00278 
00279 
00280   //--------------------------------------------------------------------
00281 
00282 
00283 
00284   class LCRTRelations ;
00285 
00286   /** Set the 1-to-1 relation between two objects - prexisting inconsistent relations 
00287       involving the two objects are deleted to enforce a consistent set of from-to relations. */
00288   template <class R> 
00289   void set_relation( typename R::from::obj_ptr f, 
00290                      typename R::to::obj_ptr t) ;
00291 
00292   /** Unset the 1-to-1 relation from f */
00293   template <class R> 
00294   void unset_relation(typename R::from::obj_ptr f );
00295 
00296 
00297   /** Add a link from f to t to an N-to-N relation ship  */
00298   template <class R> 
00299   void add_relation( typename R::from::obj_ptr f, 
00300                      typename R::to::obj_ptr t) ;
00301 
00302 
00303   /** Remove the link from from f to t from the N-to-N relation ship  */
00304   template <class R> 
00305   void remove_relation( typename R::from::obj_ptr f, 
00306                         typename R::to::obj_ptr t) ;
00307 
00308 
00309   /** Removes all relations from the given object */
00310   template <class R> 
00311   void remove_relations(typename R::from::obj_ptr f );
00312 
00313 
00314   /** Merge the relations from f2 to f1 - after this call f1 will hold all 
00315    *  the relations and f2 will be empty. 
00316    */
00317   template <class R> 
00318   void merge_relations( typename R::from::obj_ptr f1, 
00319                         typename R::from::obj_ptr f2) ;
00320 
00321 
00322 
00323   /** Base class that provides run time (user) extensions and relation between objects. 
00324    * Every subclass object of LCRTRelations (and thus LCObbject) will automatically have 
00325    * the following functionality:<br>
00326    * <ul>
00327    * <li>extension of the object with arbitrary (even non-LCObject) classes</li>
00328    * <li>extension of single objects or vectors, lists of objects</li>
00329    * <li>optionally ownership is taken for extension objects (memory management)</li>
00330    * <li>relations to other subclasses of LCRTRelations:
00331    *  <ul>
00332    *  <li>one to one</li>
00333    *  <li>one to many</li>
00334    *  <li>many to many</li>
00335    *  </li></ul>
00336    * </ul>
00337    * 
00338    * The described functionality is provided through the two templated member functions:<br>
00339    * ext<class V>() <br>
00340    * rel<class V>() <br>
00341    * the class V is a user defined so called traits class, that uniquely tags the 
00342    * extension/relationship and defines the types of the objects involved. <br>
00343    * For extensions users have to subclass one of the following classes:<br>
00344    * LCExtension, LCOwnedExtension, LCIntExtension, LCFloatExtension,<br>
00345    * LCExtensionVector, LCExtensionList, LCOwnedExtensionVector, LCOwnedExtensionList. <br>
00346    * For example 
00347    * the following defines a user extension of a vector of strings that are owned by the 
00348    * object (i.e. deleted when the object is deleted):<br>
00349    * <p><b>
00350    * struct ParticleIDs : LCOwnedExtensionVector<ParticleIDs, std::string> {};<br>
00351    * </b>
00352    * &nbsp;&nbsp;&nbsp;(note: the first template parameter has to be the class itself !)
00353    * <p>
00354    * This extension can then be used  anywhere in the following code for all LCObjects, e.g.:<br>
00355    * <p><b>
00356    *   MCParticle*  mcp = dynamic_cast<MCParticle*>( mcpcol->getElementAt(i) ) ;<br>
00357    *    mcp->ext<ParticleIDs>()->push_back( new std::string("charged")  )  ;<br>
00358    *    mcp->ext<ParticleIDs>()->push_back( new std::string("hadron")  )  ;<br>
00359    *    mcp->ext<ParticleIDs>()->push_back( new std::string("pion")  )  ;<br>
00360    * </b><p>
00361    * and be read out again: <br>
00362    * <p><b>
00363    *    ParticleIDs::ext_type pidv =  mcp->ext<ParticleIDs>() ;<br>
00364    *    for( ParticleIDs::const_iterator ipid = pidv->begin() ; ipid != pidv->end(); ++ipid){<br>
00365    *     &nbsp;&nbsp; std::cout << **ipid << ", " ;<br>
00366    *    }<br>
00367    *</b><p>
00368    * <p>
00369    * Similarily the following defines a one to many relationship between Tracks and Clusters:<br>
00370    * <p><b>
00371    * struct TrkCluLink : LC1ToNRelation<TrkCluLink,Track,Cluster> {} ; <br>
00372    * </b><p>
00373    * Relations are allways biderectional, i.e. there is a <b>from</b> and a <b>to</b> side.
00374    * They can then be set and modified with the following functions:<br>
00375    * set_relation(), unset_relation(), add_relation(), <br>
00376    * remove_relation(), remove_relations(),
00377    * merge_relations(). <br>
00378    * For example:<br>
00379    * <p>
00380    * <b>
00381    *    Track*   trk = dynamic_cast<Track*>   ( trkcol->getElementAt(j) ) ; <br>
00382    *    //... <br>
00383    *    Cluster* clu = dynamic_cast<Cluster*> ( clucol->getElementAt(k) ) ; <br>
00384    *    add_relation<TrkCluLink>( trk ,clu ); <br>
00385    *</b><p>
00386    * The many side can then  be read out with a const_iterator and the one side with a 
00387    * normal pointer:<br>
00388    * <p><b>
00389    *    Track* trk =  clu->rel<TrkCluLink::from>() ; <br>
00390    *    //...<br>
00391         TrkCluLink::to::rel_type clulist =  trk->rel<TrkCluLink::to>() ; <br>
00392         for( TrkCluLink::to::const_iterator iclu = clulist->begin() ; iclu != clulist->end() ; ++iclu ){ <br>
00393           &nbsp;&nbsp;Cluster* clu = *iclu ;  // iterator is of type pointer to container element <br>
00394           &nbsp;&nbsp;std::cout <<  "   assigned cluster with E = " << clu->getEnergy() << std::endl ;  <br>
00395         }
00396    *</b>
00397    * <p>
00398    * More examples can be found in <b>$LCIO/src/cpp/src/EXAMPLES/lcrtrelations.cc</b>.
00399    */
00400 
00401   class LCRTRelations{
00402   
00403     // declare functions for relation handling as friends
00404     template <class R> 
00405     friend void set_relation( typename R::from::obj_ptr f, 
00406                               typename R::to::obj_ptr t);
00407     template <class R> 
00408     friend void unset_relation(typename R::from::obj_ptr f );
00409 
00410     template <class R> 
00411     friend void add_relation( typename R::from::obj_ptr f, 
00412                               typename R::to::obj_ptr t) ;
00413     template <class R> 
00414     friend void remove_relation( typename R::from::obj_ptr f, 
00415                                  typename R::to::obj_ptr t) ;
00416     template <class R> 
00417     friend void remove_relations(typename R::from::obj_ptr f );
00418 
00419     template <class R> 
00420     friend void merge_relations( typename R::from::obj_ptr f1, 
00421                                  typename R::from::obj_ptr f2) ;
00422   
00423   public:
00424   
00425     /** Provides access to an extension object - the type and ownership is defined 
00426      *  by the class V which should be a subtype of LCExtension, LCOwnedExtension,
00427      *  LCExtensionVector, LCExtensionList,...
00428      */
00429     template <class V>
00430     inline typename V::ext_type  ext() { 
00431 
00432       //      static char check[ V::allowed_to_call_ext] ;
00433       can_call_ext<V::allowed_to_call_ext>::check() ;
00434 
00435       return  ptr<V>() ;
00436     }
00437   
00438 
00439     /** Provides read access to relations - the object types and their connectivity 
00440      *  are defined by the class V which has to be a subtype of either 
00441      *  LC1To1Relation, LC1ToNRelation or LCNToNRelation.
00442      */
00443     template <class V>
00444     inline typename V::rel_type rel() {
00445     
00446       return  ptr<V>() ;
00447     }
00448   
00449   
00450 
00451     //   LCRTRelations() { 
00452     //     _vec = new PtrVec( 32  ) ; // initialize to prevent from to many resizes
00453     //   }
00454     //   ~LCRTRelations() {
00455     //    for( unsigned i=0 ; i< cleaners().size() ; ++i){
00456     //      cleaners()[i]( _vec->operator[](i)  ) ;  // call the delete function
00457     //    }
00458     //    delete _vec ;
00459     //   }
00460 
00461 
00462 
00463     ~LCRTRelations() {
00464       for( PtrMap::iterator it = _map.begin() ; it != _map.end() ; ++it ){
00465         cleaners()[ it->first ] ( it->second ) ;  // call the delete function
00466       }
00467     }
00468   
00469     //   void print(){
00470     //     std::cout << " ---- LCRTRelations -- : " << std::endl ;
00471     //     typedef std::map< void * , void*  > MyPtrMap ;
00472     //     MyPtrMap& map = *(MyPtrMap*) &_map ;
00473     //     for( MyPtrMap::iterator it = map.begin() ;
00474     //   it != map.end() ; ++it ){
00475     //       std::cout << "      ----   key : " << &(it->first) << " value " 
00476     //          <<  (void*)it->second  << std::endl ;
00477     //     }
00478     //   }
00479 
00480 
00481   protected:
00482 
00483     //   /** Returns the reference to the pointer to the extension/relation object */
00484     //   template <class V>
00485     //   inline typename V::ptr & ptr() {
00486     
00487     //     typedef std::vector< typename V::ptr  > MyPtrVec ;
00488     //     MyPtrVec* vec = (MyPtrVec*) _vec ;
00489 
00490     //     unsigned id =  typeID<V>()  ;
00491 
00492     //     if( ! (vec->size() > id )  ) {
00493     //       vec->resize( id + 1 ) ;
00494     //     }
00495 
00496     //     typename V::ptr& p =  vec->operator[](id) ;
00497 
00498     //     if( p == 0 ) 
00499     //       p = V::init() ;
00500 
00501     //     return  p ;
00502     //   }
00503   
00504 
00505 
00506     /** Returns the reference to the pointer to the extension/relation object */
00507     template <class V>
00508     typename V::ptr & ptr() {
00509     
00510       typedef std::map< unsigned , typename V::ptr  > MyPtrMap ;
00511     
00512       MyPtrMap* map = (MyPtrMap*) &_map ;
00513     
00514       typename MyPtrMap::iterator it = map->find( typeID<V>() ) ;
00515     
00516       if( it == map->end() )
00517         it = map->insert( map->begin(), 
00518                           std::make_pair(  typeID<V>() , V::init() )) ;
00519     
00520       return  it->second  ;
00521     }
00522 
00523   private:
00524   
00525     static DPtrVec& cleaners(){
00526       static DPtrVec v ;
00527       return v ;
00528     }
00529   
00530     inline unsigned nextID(DeleteFPtr cp){
00531       static unsigned id(0) ;
00532 
00533       //     std::cout << " ---- nextID " << id+1  << " - delete Ptr  " 
00534       // <<  cp << std::endl ;
00535       
00536       cleaners().push_back( cp ) ;
00537 
00538       return id++ ;
00539     }
00540   
00541     template <class T>
00542     inline unsigned typeID(){
00543       static const unsigned uid  = nextID( T::deletePtr() ) ;
00544 
00545       return uid ;
00546     } 
00547   
00548   
00549     //   PtrVec* _vec ; 
00550     PtrMap _map ;
00551   
00552   } ;
00553   
00554 
00555   //----------------------- relation function definitions -----------------------------------
00556 
00557 
00558   template <class R> 
00559   void unset_relation(typename R::from::obj_ptr f){
00560   
00561     if( f != 0 ){
00562     
00563       LCRTRelations* t = f->LCRTRelations::rel<typename R::to>() ;
00564     
00565       if( t != 0 ) 
00566         t->LCRTRelations::ptr<typename R::from>() = 0 ;
00567     
00568       f->LCRTRelations::ptr<typename R::to>() = 0 ;
00569     }
00570   }
00571 
00572   template <class R> 
00573   void set_relation(typename R::from::obj_ptr f, typename R::to::obj_ptr t){
00574   
00575     // clear old relations first
00576     unset_relation<R>( f ) ;
00577     unset_relation<R>(t->LCRTRelations::rel<typename R::from>() ) ; 
00578   
00579     f->LCRTRelations::ptr<typename R::to>() =  t ;
00580     t->LCRTRelations::ptr<typename R::from>() =  f ;
00581   }
00582 
00583 
00584 
00585 
00586   template <class R> 
00587   void add_relation(  typename R::from::obj_ptr f, 
00588                       typename R::to::obj_ptr t){
00589 
00590     f->LCRTRelations::ptr<typename R::to>()->push_back( t ) ;
00591 
00592     //   std::cout << " ask to assign " << f << " to " << t << std::endl ;
00593     objorcont<R::from::is_container>::add( t->LCRTRelations::ptr<typename R::from>() , f ) ; 
00594   }
00595 
00596 
00597 
00598 
00599   template <class R> 
00600   void remove_relation( typename R::from::obj_ptr f, 
00601                         typename R::to::obj_ptr t ) {
00602   
00603     f->LCRTRelations::ptr<typename R::to>()->remove( t ) ;
00604 
00605     objorcont<R::from::is_container>::remove( t->LCRTRelations::ptr<typename R::from>() , f ) ; 
00606   }
00607 
00608 
00609   template <class R> 
00610   void remove_relations( typename R::from::obj_ptr f ) {
00611   
00612     typename R::to::ptr cl = f->LCRTRelations::ptr<typename R::to>() ;
00613   
00614     for( typename R::to::iterator it = cl->begin(); it!=cl->end(); ++it){
00615     
00616       objorcont<R::from::is_container>::remove((*it)->LCRTRelations::ptr<typename R::from>(), f ) ; 
00617 
00618     }
00619     cl->clear() ;
00620   }
00621 
00622   template <class R> 
00623   void merge_relations(typename R::from::obj_ptr f1, 
00624                        typename R::from::obj_ptr f2 ) {
00625   
00626     typename R::to::ptr  lt2 = f2->LCRTRelations::ptr<typename R::to>() ;
00627   
00628     for( typename R::to::iterator it = lt2->begin() ;it !=  lt2->end() ; it++ ){
00629     
00630       objorcont<R::from::is_container>::remove( (*it)->LCRTRelations::ptr<typename R::from>(), f2 ) ; 
00631       objorcont<R::from::is_container>::add( (*it)->LCRTRelations::ptr<typename R::from>(), f1 ) ; 
00632     }
00633 
00634     f1->LCRTRelations::ptr<typename R::to>()->merge( *lt2 ) ;
00635   }
00636 
00637 
00638 } // end namespace
00639 
00640 #endif

Generated on Sun Jun 3 06:32:00 2007 for A TPC Tracking Environment by  doxygen 1.3.9.1