Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:02

0001 #ifndef DataFormats_Common_RefToBaseVector_h
0002 #define DataFormats_Common_RefToBaseVector_h
0003 /**\class RefToBaseVector
0004  *
0005  * \author Luca Lista, INFN
0006  *
0007  */
0008 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0009 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0010 #include "DataFormats/Provenance/interface/ProductID.h"
0011 #include <algorithm>
0012 #include <memory>
0013 #include <utility>
0014 #include <vector>
0015 
0016 namespace edm {
0017   template <typename T>
0018   class RefToBase;
0019   template <typename T>
0020   class View;
0021   template <typename C>
0022   class Handle;
0023   class EDProductGetter;
0024   namespace reftobase {
0025     template <typename T>
0026     class BaseVectorHolder;
0027     class RefVectorHolderBase;
0028   }  // namespace reftobase
0029 
0030   template <class T>
0031   class RefToBaseVector {
0032   public:
0033     typedef RefToBase<T> value_type;
0034     typedef T member_type;
0035     typedef reftobase::BaseVectorHolder<T> holder_type;
0036     typedef typename holder_type::size_type size_type;
0037     typedef typename holder_type::const_iterator const_iterator;
0038 
0039     RefToBaseVector();
0040     RefToBaseVector(RefToBaseVector const&);
0041     template <class REFV>
0042     explicit RefToBaseVector(REFV const&);
0043     template <typename C>
0044     explicit RefToBaseVector(Handle<C> const&);
0045     RefToBaseVector(std::shared_ptr<reftobase::RefVectorHolderBase> p);
0046     RefToBaseVector& operator=(RefToBaseVector const& iRHS);
0047     void swap(RefToBaseVector& other);
0048 
0049     ~RefToBaseVector();
0050 
0051     //void reserve(size_type n);
0052     void clear();
0053 
0054     value_type at(size_type idx) const;
0055     value_type operator[](size_type idx) const;
0056     bool isValid() const { return holder_ != nullptr; }
0057     bool isInvalid() const { return holder_ == nullptr; }
0058     bool empty() const;
0059     size_type size() const;
0060     //size_type capacity() const;
0061     ProductID id() const;
0062     EDProductGetter const* productGetter() const;
0063     const_iterator begin() const;
0064     const_iterator end() const;
0065 
0066     void push_back(const RefToBase<T>&);
0067 
0068     void fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const;
0069     std::unique_ptr<reftobase::RefVectorHolderBase> vectorHolder() const;
0070 
0071     /// Checks if collection is in memory or available
0072     /// in the Event. No type checking is done.
0073     bool isAvailable() const { return holder_->isAvailable(); }
0074 
0075     //Needed for ROOT storage
0076     CMS_CLASS_VERSION(10)
0077 
0078   private:
0079     holder_type* holder_;
0080   };
0081 }  // namespace edm
0082 
0083 #include "DataFormats/Common/interface/RefToBase.h"
0084 #include "DataFormats/Common/interface/VectorHolder.h"
0085 #include "DataFormats/Common/interface/IndirectVectorHolder.h"
0086 #include "DataFormats/Common/interface/RefVectorHolder.h"
0087 #include "FWCore/Utilities/interface/EDMException.h"
0088 #include "DataFormats/Common/interface/traits.h"
0089 
0090 namespace edm {
0091   template <class T>
0092   inline void swap(RefToBaseVector<T>& a, RefToBaseVector<T>& b) {
0093     a.swap(b);
0094   }
0095 
0096   template <class T>
0097   inline bool operator==(RefToBaseVector<T> const& a, RefToBaseVector<T> const& b) {
0098     if (a.isInvalid() && b.isInvalid())
0099       return true;
0100     if (a.isInvalid() || b.isInvalid())
0101       return false;
0102     return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
0103   }
0104 
0105   //--------------------------------------------------------------------
0106   // Implementation of RefToBaseVector<T>
0107   //--------------------------------------------------------------------
0108 
0109   template <class T>
0110   inline RefToBaseVector<T>::RefToBaseVector() : holder_(nullptr) {}
0111 
0112   template <class T>
0113   template <class REFV>
0114   inline RefToBaseVector<T>::RefToBaseVector(const REFV& iRef) : holder_(new reftobase::VectorHolder<T, REFV>(iRef)) {}
0115 
0116   template <class T>
0117   inline RefToBaseVector<T>::RefToBaseVector(const RefToBaseVector<T>& iOther)
0118       : holder_(iOther.holder_ ? iOther.holder_->clone() : nullptr) {}
0119 
0120   template <class T>
0121   inline RefToBaseVector<T>::RefToBaseVector(std::shared_ptr<reftobase::RefVectorHolderBase> p)
0122       : holder_(new reftobase::IndirectVectorHolder<T>(p)) {}
0123 
0124   template <class T>
0125   inline RefToBaseVector<T>& RefToBaseVector<T>::operator=(const RefToBaseVector& iRHS) {
0126     RefToBaseVector temp(iRHS);
0127     this->swap(temp);
0128     return *this;
0129   }
0130 
0131   template <class T>
0132   inline void RefToBaseVector<T>::swap(RefToBaseVector& other) {
0133     std::swap(holder_, other.holder_);
0134   }
0135 
0136   template <class T>
0137   inline RefToBaseVector<T>::~RefToBaseVector() {
0138     delete holder_;
0139   }
0140 
0141   template <class T>
0142   inline typename RefToBaseVector<T>::value_type RefToBaseVector<T>::at(size_type idx) const {
0143     if (holder_ == nullptr)
0144       Exception::throwThis(
0145           errors::InvalidReference, "Trying to dereference null RefToBaseVector<T> in method: at(", idx, ")\n");
0146     return holder_->at(idx);
0147   }
0148 
0149   template <class T>
0150   inline typename RefToBaseVector<T>::value_type RefToBaseVector<T>::operator[](size_type idx) const {
0151     return at(idx);
0152   }
0153 
0154   template <class T>
0155   inline bool RefToBaseVector<T>::empty() const {
0156     return holder_ ? holder_->empty() : true;
0157   }
0158 
0159   template <class T>
0160   inline typename RefToBaseVector<T>::size_type RefToBaseVector<T>::size() const {
0161     return holder_ ? holder_->size() : 0;
0162   }
0163 
0164   template <class T>
0165   inline void RefToBaseVector<T>::clear() {
0166     if (holder_ != nullptr)
0167       holder_->clear();
0168   }
0169 
0170   template <class T>
0171   inline ProductID RefToBaseVector<T>::id() const {
0172     return holder_ ? holder_->id() : ProductID();
0173   }
0174 
0175   template <class T>
0176   inline EDProductGetter const* RefToBaseVector<T>::productGetter() const {
0177     return holder_ ? holder_->productGetter() : nullptr;
0178   }
0179 
0180   template <class T>
0181   inline typename RefToBaseVector<T>::const_iterator RefToBaseVector<T>::begin() const {
0182     return holder_ ? holder_->begin() : const_iterator();
0183   }
0184 
0185   template <class T>
0186   inline typename RefToBaseVector<T>::const_iterator RefToBaseVector<T>::end() const {
0187     return holder_ ? holder_->end() : const_iterator();
0188   }
0189 
0190   template <typename T>
0191   void RefToBaseVector<T>::fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const {
0192     pointers.reserve(this->size());
0193     helpers.reserve(this->size());
0194     for (const_iterator i = begin(), e = end(); i != e; ++i) {
0195       RefToBase<T> ref = *i;
0196       member_type const* address = ref.isNull() ? nullptr : &*ref;
0197       pointers.push_back(address);
0198       helpers.push_back(FillViewHelperVector::value_type(ref.id(), ref.key()));
0199     }
0200   }
0201 
0202   // NOTE: the following implementation has unusual signature!
0203   template <typename T>
0204   inline void fillView(RefToBaseVector<T> const& obj,
0205                        ProductID const&,
0206                        std::vector<void const*>& pointers,
0207                        FillViewHelperVector& helpers) {
0208     obj.fillView(pointers, helpers);
0209   }
0210 
0211   template <typename T>
0212   struct has_fillView<RefToBaseVector<T> > {
0213     static bool const value = true;
0214   };
0215 
0216   template <typename T>
0217   void RefToBaseVector<T>::push_back(const RefToBase<T>& r) {
0218     if (holder_ == nullptr) {
0219       std::unique_ptr<reftobase::BaseVectorHolder<T> > p = r.holder_->makeVectorHolder();
0220       holder_ = p.release();
0221     }
0222     holder_->push_back(r.holder_);
0223   }
0224 
0225   template <typename T>
0226   std::unique_ptr<reftobase::RefVectorHolderBase> RefToBaseVector<T>::vectorHolder() const {
0227     return holder_ ? holder_->vectorHolder() : std::unique_ptr<reftobase::RefVectorHolderBase>();
0228   }
0229 }  // namespace edm
0230 
0231 #include "DataFormats/Common/interface/RefVector.h"
0232 #include "DataFormats/Common/interface/Handle.h"
0233 
0234 namespace edm {
0235 
0236   template <typename T>
0237   template <typename C>
0238   RefToBaseVector<T>::RefToBaseVector(const Handle<C>& h)
0239       : holder_(new reftobase::VectorHolder<
0240                 T,
0241                 RefVector<C, typename refhelper::ValueTrait<C>::value, typename refhelper::FindTrait<C, T>::value> >(
0242             h.id())) {}
0243 
0244 }  // namespace edm
0245 #endif