LCIO  02.17
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LCRTRelations.h
Go to the documentation of this file.
1 #ifndef LCRTRelations_H
2 #define LCRTRelations_H 1
3 
4 #include <iostream>
5 #include <vector>
6 #include <list>
7 #include <map>
8 #ifndef __CINT__
9 #include <typeindex>
10 #endif
11 #include <memory>
12 
13 #include <Exceptions.h>
14 
15 namespace lcrtrel_helper{
16 
17  //------------------ internal helper typdefs, function and classes ----------
18 
19  template <bool B>
20  struct can_call_ext{};
21  template <>
22  struct can_call_ext<true>{ static void check(){/* no_op */ } ; };
23 
24  // /** Function pointer for delete function */
25  // typedef void (*DeleteFPtr)(void*) ;
26 
28  struct SimplePtrInit{ static void* init() { return 0 ; } } ;
29 
31  template <class T>
32  struct CreationPtrInit{ static void* init() { return new T ; } } ;
33 
35  struct NoDelete{ static void clean(void *) { /* no_op */ } } ;
36 
38  template <class T>
39  struct DeletePtr{ static void clean(void *v) { delete (T*) v ; } } ;
40 
42  template <class T>
43  struct DeleteElements {
44  static void clean(void *v) {
45  T* vec = static_cast<T*>(v) ;
46  for( typename T::iterator it = vec->begin();it != vec->end(); ++it){
47  delete *it ;
48  }
49  delete vec ;
50  }
51  };
52 
53 
54  // /** Map of pointers to extension obbjects*/
55  // typedef std::map< unsigned , void * > PtrMap ;
56 
57  // /** Vector of delete functions */
58  // typedef std::vector< DeleteFPtr > DPtrVec ;
59 
61  //typedef std::vector< void * > PtrVec ;
62 
63 
65  template <class U, class T , class I, class D, bool b>
66  struct LCBaseTraits {
67  // traits definitions
68  typedef T* ptr ;
69  typedef U tag ; // this ensures that a new class instance is created for every user extension
70  static const int allowed_to_call_ext = b ;
71 
72  LCBaseTraits<U, T, I, D, b>(const LCBaseTraits&) = delete ;
74 
75  public:
78  _pointer = (ptr) I::init();
79  }
80 
83  D::clean( _pointer );
84  }
85 
87  inline ptr& pointer() {
88  return _pointer;
89  }
90 
91  protected:
93  };
94 
95 
97  template <class U, class T , class I=SimplePtrInit, class D=NoDelete , bool b=1>
98  struct LCBaseLinkTraits : public LCBaseTraits<U,T,I,D,b>{
99 
101 
102  typedef T*& ext_type ; // return value of ext<>()
103  typedef T* rel_type ; // return value of rel<>()
104  typedef typename base::ptr obj_ptr ; // pointer to object
105 
106  static const bool is_container=false ;
107  };
108 
110  template <class U, class T , class I=CreationPtrInit<T>, class D=DeletePtr<T> , bool b=1>
111  struct LCBaseLinkContainerTraits : public LCBaseTraits<U,T,I,D,b>{
112 
114 
115  typedef T* ext_type ; // return value of ext<>()
116  typedef const T* rel_type ; // return value of rel<>()
117  typedef typename T::value_type obj_ptr ; // pointer to object
118 
119  typedef typename T::iterator iterator ;
120  typedef typename T::const_iterator const_iterator ;
121 
122  static const bool is_container=true ;
123  };
124 
125 
127  template <class U, class T>
128  struct RelationOneSide :
129  public LCBaseLinkTraits<U,T,SimplePtrInit,NoDelete,false> {};
130 
131 
133  template <class U, class T>
135  public LCBaseLinkContainerTraits< U, std::list<T*>,
136  CreationPtrInit< std::list<T*> > ,
137  DeletePtr<std::list<T*> > ,false > {};
138 
140  template <class U> struct FromRelation{} ;
141 
143  template <class U> struct ToRelation{} ;
144 
145 
147  template <class From, class To>
149  typedef From from ;
150  typedef To to ;
151  } ;
152 
153 
155  template <bool is_container>
156  struct objorcont{
157 
158  template <class T, class S>
159  inline static void add( T t, S s) { t->push_back( s ) ; }
160 
161  template <class T, class S>
162  inline static void remove( T t, S s) { t->remove( s ) ; }
163  };
164 
165 
167  template <>
168  struct objorcont<false>{
169 
170  template <class T, class S>
171  inline static void add( T& t, S s) { t = s ; }
172 
173  template <class T, class S>
174  inline static void remove( T& t, S ) { t = 0 ; }
175  };
176 
177  //-----------end of internal helper typdefs, function and classes ----------
178 
179 
180 } // end namespace lcrtrel_helper
181 
182 namespace lcrtrel{
183 
184  using namespace lcrtrel_helper ;
185 
190  template <class U, typename T>
191  struct LCExtension : public LCBaseLinkTraits< U, T > {};
192 
198  template <class U, typename T>
199  class LCOwnedExtension : public LCBaseLinkTraits< U, T , SimplePtrInit , DeletePtr<T> > {};
200 
201 
203  template <class U, class T>
205  public LCBaseLinkContainerTraits< U, std::vector<T*>,
206  CreationPtrInit< std::vector<T*> > ,
207  DeletePtr<std::vector<T*> > > {};
208 
209 
213  template <class U, class T>
215  public LCBaseLinkContainerTraits< U, std::vector<T*>,
216  CreationPtrInit< std::vector<T*> > ,
217  DeleteElements< std::vector<T*> > > {};
218 
219 
221  template <class U, class T>
223  public LCBaseLinkContainerTraits< U, std::list<T*>,
224  CreationPtrInit< std::list<T*> > ,
225  DeletePtr<std::list<T*> > > {};
226 
230  template <class U, class T>
232  public LCBaseLinkContainerTraits< U, std::list<T*>,
233  CreationPtrInit< std::list<T*> > ,
234  DeleteElements< std::list<T*> > > {};
235 
236 
238  template <class U, class From, class To>
239  struct LC1To1Relation :
240  public BiDirectional<RelationOneSide<FromRelation<U>,From>,
241  RelationOneSide<ToRelation<U>,To> > {
242 
243  } ;
244 
246  template <class U, class From, class To>
247  struct LC1ToNRelation :
248  public BiDirectional<RelationOneSide<FromRelation<U>,From>,
249  RelationManySide<ToRelation<U>,To> > {
250  } ;
251 
253  template <class U, class From, class To>
254  struct LCNToNRelation :
255  public BiDirectional<RelationManySide<FromRelation<U>,From>,
256  RelationManySide<ToRelation<U>,To> > {
257  } ;
258 
259 
261  template <class U >
262  struct LCIntExtension{
263 
264  typedef long ptr ; // base pointer type - use long to work for 64 bit (long is 32 on 32-bit systems/64 on 64bit systems)
265  typedef long& ext_type ;
266  typedef U tag ; // this ensures that a new class instance is created for every user extension
267  static const int allowed_to_call_ext = 1 ;
268 
271  LCIntExtension<U>() = default ;
272 
275  ~LCIntExtension<U>() = default ;
276 
278  inline ptr& pointer() {
279  return _pointer;
280  }
281 
282  private:
283  ptr _pointer{0};
284  };
285 
286 
287 
288  template <class U >
289  struct LCFloatExtension{// FIXME: need to check on 64 bit architecture...
290 
291 #ifdef __i386__
292  typedef float ptr ; // base pointer type
293  typedef float& ext_type ; // return value of ext<>()
294 
295 #else // use double on 64bit systems
296  typedef double ptr ; // base pointer type
297  typedef double& ext_type ; // return value of ext<>()
298 #endif
299  typedef U tag ; // this ensures that a new class instance is created for every user extension
300  static const int allowed_to_call_ext = 1 ;
301 
304  LCFloatExtension<U>() = default ;
305 
308  ~LCFloatExtension<U>() = default ;
309 
311  inline ptr& pointer() {
312  return _pointer;
313  }
314 
315  private:
316  ptr _pointer{0};
317  };
318 
319 
320  template <class U >
322 
323  typedef bool ptr ; // base pointer type
324  typedef bool& ext_type ;
325  typedef U tag ; // this ensures that a new class instance is created for every user extension
326  static const int allowed_to_call_ext = 1 ;
327 
330  LCBoolExtension<U>() = default ;
331 
334  ~LCBoolExtension<U>() = default ;
335 
337  inline ptr& pointer() {
338  return _pointer;
339  }
340 
341  private:
342  ptr _pointer{false};
343  };
344 
345 
346  //--------------------------------------------------------------------
347 
348 
349 
350  class LCRTRelations ;
351 
352  // exclude from dictionary (template lookup does not work)
353 #ifndef __CINT__
354 
357  template <class R>
358  void set_relation( typename R::from::obj_ptr f,
359  typename R::to::obj_ptr t) ;
360 
362  template <class R>
363  void unset_relation(typename R::from::obj_ptr f );
364 
365 
367  template <class R>
368  void add_relation( typename R::from::obj_ptr f,
369  typename R::to::obj_ptr t) ;
370 
371 
373  template <class R>
374  void remove_relation( typename R::from::obj_ptr f,
375  typename R::to::obj_ptr t) ;
376 
377 
379  template <class R>
380  void remove_relations(typename R::from::obj_ptr f );
381 
382 
386  template <class R>
387  void merge_relations( typename R::from::obj_ptr f1,
388  typename R::from::obj_ptr f2) ;
389 
390 
391 
471 
472  // declare functions for relation handling as friends
473  template <class R>
474  friend void set_relation( typename R::from::obj_ptr f,
475  typename R::to::obj_ptr t);
476  template <class R>
477  friend void unset_relation(typename R::from::obj_ptr f );
478 
479  template <class R>
480  friend void add_relation( typename R::from::obj_ptr f,
481  typename R::to::obj_ptr t) ;
482  template <class R>
483  friend void remove_relation( typename R::from::obj_ptr f,
484  typename R::to::obj_ptr t) ;
485  template <class R>
486  friend void remove_relations(typename R::from::obj_ptr f );
487 
488  template <class R>
489  friend void merge_relations( typename R::from::obj_ptr f1,
490  typename R::from::obj_ptr f2) ;
491 
492  public:
493  // traits definitions
497 
498  public:
503  template <class V>
504  inline typename V::ext_type ext() {
506  return ptr<V>() ;
507  }
508 
513  template <class V>
514  inline const typename V::ext_type ext() const {
516  return ptr<V>() ;
517  }
518 
523  template <class V>
524  inline typename V::rel_type rel() {
525  return ptr<V>() ;
526  }
527 
528  private:
531  template <class V>
532  typename V::ptr & ptr() const {
533  // Look in extension map for the specific user type
534  auto iter = _extensionMap.find( std::type_index( typeid( V ) ) ) ;
535  // The final user extension
536  std::shared_ptr<V> userExtension = nullptr ;
537 
538  if( iter != _extensionMap.end() ) {
539  // get the user extension
540  userExtension = std::static_pointer_cast<V>( iter->second ) ;
541  }
542  else {
543  userExtension = std::make_shared<V>();
544  ext_map::value_type element(
545  std::type_index( typeid(V) ) , // the user extension element type info
546  userExtension // the user extension itself
547  );
548  iter = _extensionMap.insert( element ).first;
549  }
550  if( nullptr == userExtension ) {
551  throw EVENT::Exception(" Invalid user extension cast !!! ") ;
552  }
553  return userExtension->pointer();
554  }
555 
556  private:
558  mutable ext_map _extensionMap {};
559  } ;
560 
561 
562  //----------------------- relation function definitions -----------------------------------
563 
564 
565  template <class R>
566  void unset_relation(typename R::from::obj_ptr f){
567 
568  if( f != 0 ){
569 
570  LCRTRelations* t = f->LCRTRelations::template rel<typename R::to>() ;
571 
572  if( t != 0 )
573  t->LCRTRelations::ptr<typename R::from>() = 0 ;
574 
575  f->LCRTRelations::template ptr<typename R::to>() = 0 ;
576  }
577  }
578 
579  template <class R>
580  void set_relation(typename R::from::obj_ptr f, typename R::to::obj_ptr t){
581 
582  // clear old relations first
583  unset_relation<R>( f ) ;
584  unset_relation<R>(t->LCRTRelations::template rel<typename R::from>() ) ;
585 
586  f->LCRTRelations::template ptr<typename R::to>() = t ;
587  t->LCRTRelations::template ptr<typename R::from>() = f ;
588  }
589 
590 
591 
592 
593  template <class R>
594  void add_relation( typename R::from::obj_ptr f,
595  typename R::to::obj_ptr t){
596 
597  f->LCRTRelations::template ptr<typename R::to>()->push_back( t ) ;
598 
599  // std::cout << " ask to assign " << f << " to " << t << std::endl ;
600  objorcont<R::from::is_container>::add( t->LCRTRelations::template ptr<typename R::from>() , f ) ;
601  }
602 
603 
604 
605 
606  template <class R>
607  void remove_relation( typename R::from::obj_ptr f,
608  typename R::to::obj_ptr t ) {
609 
610  f->LCRTRelations::template ptr<typename R::to>()->remove( t ) ;
611 
612  objorcont<R::from::is_container>::remove( t->LCRTRelations::template ptr<typename R::from>() , f ) ;
613  }
614 
615 
616  template <class R>
617  void remove_relations( typename R::from::obj_ptr f ) {
618 
619  typename R::to::ptr cl = f->LCRTRelations::template ptr<typename R::to>() ;
620 
621  for( typename R::to::iterator it = cl->begin(); it!=cl->end(); ++it){
622 
623  objorcont<R::from::is_container>::remove((*it)->LCRTRelations::template ptr<typename R::from>(), f ) ;
624 
625  }
626  cl->clear() ;
627  }
628 
629  template <class R>
630  void merge_relations(typename R::from::obj_ptr f1,
631  typename R::from::obj_ptr f2 ) {
632 
633  typename R::to::ptr lt2 = f2->LCRTRelations::template ptr<typename R::to>() ;
634 
635  for( typename R::to::iterator it = lt2->begin() ;it != lt2->end() ; it++ ){
636 
637  objorcont<R::from::is_container>::remove( (*it)->LCRTRelations::template ptr<typename R::from>(), f2 ) ;
638  objorcont<R::from::is_container>::add( (*it)->LCRTRelations::template ptr<typename R::from>(), f1 ) ;
639  }
640 
641  f1->LCRTRelations::template ptr<typename R::to>()->merge( *lt2 ) ;
642  }
643 #endif // __CINT__
644 
645 } // end namespace
646 
647 #endif
Factory for objects of type T.
Definition: LCRTRelations.h:32
Base exception class for LCIO - all other exceptions extend this.
Definition: Exceptions.h:21
ptr & pointer()
Extension data access.
void unset_relation(typename R::from::obj_ptr f)
Unset the 1-to-1 relation from f.
static void clean(void *)
Definition: LCRTRelations.h:35
void set_relation(typename R::from::obj_ptr f, typename R::to::obj_ptr t)
Set the 1-to-1 relation between two objects - prexisting inconsistent relations involving the two obj...
V::rel_type rel()
Provides read access to relations - the object types and their connectivity are defined by the class ...
Delete function for pointers w/ ownership.
Definition: LCRTRelations.h:39
Helper class for biderectional relations provides the to and from type.
ptr & pointer()
Extension data access.
LCBaseTraits< U, T, I, D, b > base
Delete function for containers of owned objects.
Definition: LCRTRelations.h:43
V::ptr & ptr() const
Returns the reference to the pointer to the extension/relation object.
static const int allowed_to_call_ext
Definition: LCRTRelations.h:70
void merge_relations(typename R::from::obj_ptr f1, typename R::from::obj_ptr f2)
Merge the relations from f2 to f1 - after this call f1 will hold all the relations and f2 will be emp...
Base class that provides run time (user) extensions and relation between objects. ...
LCBaseTraits< U, T, I, D, b > & operator=(const LCBaseTraits &)=delete
Helper class for relations.
Helper class for relations.
Function pointer for delete function.
Definition: LCRTRelations.h:28
void remove_relation(typename R::from::obj_ptr f, typename R::to::obj_ptr t)
Remove the link from from f to t from the N-to-N relation ship.
void remove_relations(typename R::from::obj_ptr f)
Removes all relations from the given object.
T * ptr
base pointer type
Definition: LCRTRelations.h:68
Base class for all extensions and relations of single objects.
Definition: LCRTRelations.h:98
T static_pointer_cast(T...args)
Helper class for relations.
Map of pointers to extension obbjects.
Definition: LCRTRelations.h:66
ptr & pointer()
Extension data access.
Simple Extension - pointer to an object of type T where the ownership is taken over by the object hol...
V::ext_type ext()
Provides access to an extension object - the type and ownership is defined by the class V which shoul...
Special Extension that allows to write int extensions directly (not through a pointer !)...
Empty delete function for pointers w/o ownership.
Definition: LCRTRelations.h:35
static void clean(void *v)
Definition: LCRTRelations.h:44
LCBaseTraits< U, T, I, D, b > base
static void remove(T t, S s)
Base class for all containers of extensions and relations, vectors, lists,...
void add_relation(typename R::from::obj_ptr f, typename R::to::obj_ptr t)
Add a link from f to t to an N-to-N relation ship.
std::type_index ext_index
static void clean(void *v)
Definition: LCRTRelations.h:39
ptr & pointer()
Extension data access.
Definition: LCRTRelations.h:87
Extension list holding pointers to objects of type T - ownership of the objects is taken...
Extension vector holding pointers to objects of type T - ownership of the objects is taken...
One to one relation between two objects of type From and To.
Extension vector holding pointers to objects of type T - no ownership of the objects is taken...
static void add(T t, S s)
const V::ext_type ext() const
Provides access to an extension object - the type and ownership is defined by the class V which shoul...
One to many relation between one object of type From to many objects of type To.
Helper functions that treat single objects and containers.
std::shared_ptr< void > ext_type
Many to many relation between objects of type From to objects of type To.
Extension list holding pointers to objects of type T - no ownership of the objects is taken...
std::map< ext_index, ext_type > ext_map
Simple Extension - pointer to an object of type T.
Helper class for relations.