File indexing completed on 2023-03-17 10:49:19
0001 #ifndef DataFormats_Common_Association_h
0002 #define DataFormats_Common_Association_h
0003
0004
0005
0006
0007
0008
0009
0010 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0011 #include "DataFormats/Common/interface/Ref.h"
0012 #include "DataFormats/Common/interface/RefProd.h"
0013 #include "DataFormats/Common/interface/ValueMap.h"
0014
0015 namespace edm {
0016
0017 template <typename C>
0018 class Association : private ValueMap<int> {
0019 public:
0020 typedef int index;
0021 typedef ValueMap<index> base;
0022 typedef typename base::offset offset;
0023 typedef edm::RefProd<C> refprod_type;
0024 typedef Ref<typename refprod_type::product_type> reference_type;
0025
0026 Association() : base() {}
0027 template <typename H>
0028 explicit Association(const H& h) : base(), ref_(h) {}
0029
0030
0031 using base::rawIndexOf;
0032
0033 template <typename RefKey>
0034 reference_type operator[](const RefKey& r) const {
0035 return get(r.id(), r.key());
0036 }
0037
0038
0039 reference_type get(size_t rawIdx) const {
0040 index i = values_[rawIdx];
0041 if (i < 0)
0042 return reference_type();
0043 size_t k = i;
0044 if (k >= ref_->size())
0045 throwIndexMapBound();
0046 return reference_type(ref_, k);
0047 }
0048
0049 reference_type get(ProductID id, size_t idx) const { return get(rawIndexOf(id, idx)); }
0050
0051 Association<C>& operator+=(const Association<C>& o) {
0052 add(o);
0053 return *this;
0054 }
0055 void setRef(const refprod_type& ref) {
0056 if (ref_.isNull()) {
0057 ref_ = ref;
0058 } else {
0059 if (ref_.id() != ref.id())
0060 throwRefSet();
0061 }
0062 }
0063 bool contains(ProductID id) const { return base::contains(id); }
0064 size_t size() const { return base::size(); }
0065 bool empty() const { return base::empty(); }
0066 void clear() { base::clear(); }
0067 refprod_type ref() const { return ref_; }
0068 void swap(Association& other) {
0069 this->ValueMap<int>::swap(other);
0070 ref_.swap(other.ref_);
0071 }
0072 Association& operator=(Association const& rhs) {
0073 Association temp(rhs);
0074 this->swap(temp);
0075 return *this;
0076 }
0077
0078 class Filler : public helper::Filler<Association<C> > {
0079 typedef helper::Filler<Association<C> > base;
0080
0081 public:
0082 explicit Filler(Association<C>& association) : base(association) {}
0083 void add(const Association<C>& association) {
0084 base::map_.setRef(association.ref());
0085 base::add(association);
0086 }
0087 };
0088
0089
0090 const id_offset_vector& ids() const { return ids_; }
0091
0092 using base::id_offset_vector;
0093
0094
0095 CMS_CLASS_VERSION(10)
0096
0097 private:
0098 refprod_type ref_;
0099 void throwIndexMapBound() const {
0100 Exception::throwThis(errors::InvalidReference, "Association: index in the map out of upper boundary\n");
0101 }
0102 void throwRefSet() const {
0103 Exception::throwThis(errors::InvalidReference, "Association: reference to product already set\n");
0104 }
0105
0106 void add(const Association<C>& o) {
0107 Filler filler(*this);
0108 filler.add(o);
0109 filler.fill();
0110 }
0111
0112 friend class helper::Filler<Association<C> >;
0113 };
0114
0115
0116 template <typename C>
0117 inline void swap(Association<C>& lhs, Association<C>& rhs) {
0118 lhs.swap(rhs);
0119 }
0120
0121 template <typename C>
0122 inline Association<C> operator+(const Association<C>& a1, const Association<C>& a2) {
0123 Association<C> a = a1;
0124 a += a2;
0125 return a;
0126 }
0127 }
0128
0129 #endif