CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/DataFormats/Common/interface/Association.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_Association_h
00002 #define DataFormats_Common_Association_h
00003 /* \class Association<RefProd>
00004  *
00005  * \author Luca Lista, INFN
00006  *
00007  * \version $Id: Association.h,v 1.8 2009/11/04 15:30:19 wmtan Exp $
00008  *
00009  */
00010 
00011 #include "DataFormats/Common/interface/Ref.h"
00012 #include "DataFormats/Common/interface/RefProd.h"
00013 #include "DataFormats/Common/interface/ValueMap.h"
00014 
00015 namespace edm {
00016   
00017   template<typename C>
00018   class Association : private ValueMap<int> {
00019   public:
00020     typedef int index; // negative index == null reference
00021     typedef ValueMap<index> base;
00022     typedef typename base::offset offset;
00023     typedef edm::RefProd<C> refprod_type; // could be specialized for View
00024     typedef Ref<typename refprod_type::product_type> reference_type;
00025 
00026     Association() : base() { }
00027     template<typename H>
00028     explicit Association(const H & h) : base(), ref_(h) { }
00029 
00030     // import this function from ValueMap<int>
00031     using base::rawIndexOf;
00032  
00033     template<typename RefKey>
00034       reference_type operator[](const RefKey & r) const {
00035       return get(r.id(), r.key());
00036     }
00037 
00039     reference_type get(size_t rawIdx) const { 
00040       index i = values_[rawIdx];
00041       if(i < 0) return reference_type(); 
00042       size_t k = i;
00043       if (k >= ref_->size()) throwIndexMapBound();
00044       return reference_type(ref_,k);
00045     }
00046 
00047     reference_type get(ProductID id, size_t idx) const { 
00048       return get(rawIndexOf(id,idx));
00049     }
00050 
00051     Association<C> & operator+=(const Association<C> & o) {
00052       add(o);
00053       return *this;
00054     }
00055     void setRef(const refprod_type & ref) {
00056       if(ref_.isNull() ) {
00057         ref_ = ref;
00058       } else {
00059         if(ref_.id() != ref.id()) throwRefSet();
00060       }
00061     }
00062     bool contains(ProductID id) const { return base::contains(id); }
00063     size_t size() const { return base::size(); }
00064     bool empty() const { return base::empty(); }
00065     void clear() { base::clear(); }
00066     refprod_type ref() const { return ref_; }
00067     void swap(Association& other) {
00068       this->ValueMap<int>::swap(other);
00069       ref_.swap(other.ref_);
00070     }
00071     Association& operator=(Association const& rhs) {
00072       Association temp(rhs);
00073       this->swap(temp);
00074       return *this;
00075     }
00076 
00077     class Filler : public helper::Filler<Association<C> > {
00078       typedef helper::Filler<Association<C> > base;
00079     public:
00080       explicit Filler(Association<C> & association) : 
00081         base(association) { }
00082       void add(const Association<C> & association) {
00083         base::map_.setRef(association.ref());
00084         base::add(association);
00085       }
00086     };
00087 
00089     const id_offset_vector & ids() const { return ids_; }
00091     using base::id_offset_vector;
00092   private:
00093     refprod_type ref_;
00094     void throwIndexMapBound() const {
00095       Exception::throwThis(errors::InvalidReference, "Association: index in the map out of upper boundary\n");
00096     }
00097     void throwRefSet() const {
00098       Exception::throwThis(errors::InvalidReference, "Association: reference to product already set\n");
00099     }
00100 
00101     void add( const Association<C> & o ) {
00102       Filler filler(*this);
00103       filler.add(o);
00104       filler.fill();
00105     }
00106 
00107     friend class helper::Filler<Association<C> >;
00108   }; 
00109   
00110   // Free swap function
00111   template <typename C>
00112   inline void swap(Association<C>& lhs, Association<C>& rhs) {
00113     lhs.swap(rhs);
00114   }
00115 
00116   template<typename C>
00117   inline  Association<C> operator+( const Association<C> & a1,
00118                                        const Association<C> & a2 ) {
00119     Association<C> a = a1;
00120     a += a2;
00121     return a;
00122   }
00123 }
00124 
00125 #endif