Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:49:24

0001 #ifndef DataFormats_Common_PtrVector_h
0002 #define DataFormats_Common_PtrVector_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Common
0006 // Class  :     PtrVector
0007 //
0008 /**\class PtrVector PtrVector.h DataFormats/Common/interface/PtrVector.h
0009 
0010  Description: A container which returns edm::Ptr<>'s referring to items in one container in the edm::Event
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Original Author:  Chris Jones
0018 //         Created:  Wed Oct 24 15:26:50 EDT 2007
0019 //
0020 
0021 // user include files
0022 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0023 #include "DataFormats/Common/interface/Ptr.h"
0024 #include "DataFormats/Common/interface/PtrVectorBase.h"
0025 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0026 
0027 // system include files
0028 #include <type_traits>
0029 #include <typeinfo>
0030 #include <vector>
0031 
0032 // forward declarations
0033 namespace edm {
0034   class ProductID;
0035   template <typename T>
0036   class PtrVector;
0037 
0038   template <typename T>
0039   class PtrHolder {
0040   public:
0041     PtrHolder(Ptr<T> const& iPtr) : ptr_(iPtr) {}
0042 
0043     Ptr<T> const& operator*() const { return ptr_; }
0044     Ptr<T> const* operator->() const { return &ptr_; }
0045 
0046   private:
0047     Ptr<T> ptr_;
0048   };
0049 
0050   template <typename T>
0051   class PtrVectorItr : public std::iterator<std::random_access_iterator_tag, Ptr<T> > {
0052   public:
0053     typedef Ptr<T> const reference;  // otherwise boost::range does not work
0054                                      // const, because this is a const_iterator
0055     typedef PtrVectorItr<T> iterator;
0056     typedef typename std::iterator<std::random_access_iterator_tag, Ptr<T> >::difference_type difference_type;
0057 
0058     PtrVectorItr(std::vector<void const*>::const_iterator const& iItr, PtrVector<T> const* iBase)
0059         : iter_(iItr), base_(iBase) {}
0060 
0061     Ptr<T> const operator*() const { return base_->fromItr(iter_); }
0062 
0063     Ptr<T> const operator[](difference_type n) const {  // Otherwise the
0064       return base_->fromItr(iter_ + n);                 // boost::range
0065     }                                                   // doesn't have []
0066 
0067     PtrHolder<T> operator->() const { return PtrHolder<T>(this->operator*()); }
0068 
0069     iterator& operator++() {
0070       ++iter_;
0071       return *this;
0072     }
0073     iterator& operator--() {
0074       --iter_;
0075       return *this;
0076     }
0077     iterator& operator+=(difference_type n) {
0078       iter_ += n;
0079       return *this;
0080     }
0081     iterator& operator-=(difference_type n) {
0082       iter_ -= n;
0083       return *this;
0084     }
0085 
0086     iterator operator++(int) {
0087       iterator it(*this);
0088       ++iter_;
0089       return it;
0090     }
0091     iterator operator--(int) {
0092       iterator it(*this);
0093       --iter_;
0094       return it;
0095     }
0096     iterator operator+(difference_type n) const {
0097       iterator it(*this);
0098       it.iter_ += n;
0099       return it;
0100     }
0101     iterator operator-(difference_type n) const {
0102       iterator it(*this);
0103       it.iter_ -= n;
0104       return it;
0105     }
0106 
0107     difference_type operator-(iterator const& rhs) const { return this->iter_ - rhs.iter_; }
0108 
0109     bool operator==(iterator const& rhs) const { return this->iter_ == rhs.iter_; }
0110     bool operator!=(iterator const& rhs) const { return this->iter_ != rhs.iter_; }
0111     bool operator<(iterator const& rhs) const { return this->iter_ < rhs.iter_; }
0112     bool operator>(iterator const& rhs) const { return this->iter_ > rhs.iter_; }
0113     bool operator<=(iterator const& rhs) const { return this->iter_ <= rhs.iter_; }
0114     bool operator>=(iterator const& rhs) const { return this->iter_ >= rhs.iter_; }
0115 
0116   private:
0117     std::vector<void const*>::const_iterator iter_;
0118     PtrVector<T> const* base_;
0119   };
0120 
0121   template <typename T>
0122   class PtrVector : public PtrVectorBase {
0123   public:
0124     typedef PtrVectorItr<T> const_iterator;
0125     typedef PtrVectorItr<T> iterator;  // make boost::sub_range happy (std allows this)
0126     typedef Ptr<T> value_type;
0127     typedef T member_type;
0128     typedef void collection_type;
0129 
0130     friend class PtrVectorItr<T>;
0131     PtrVector() : PtrVectorBase() {}
0132     explicit PtrVector(ProductID const& iId) : PtrVectorBase(iId) {}
0133     PtrVector(PtrVector<T> const& iOther) : PtrVectorBase(iOther) {}
0134 
0135     template <typename U>
0136     PtrVector(PtrVector<U> const& iOther) : PtrVectorBase(iOther) {
0137       static_assert(std::is_base_of<T, U>::value, "PtrVector being copied is not of compatible type");
0138     }
0139 
0140     // ---------- const member functions ---------------------
0141 
0142     Ptr<T> operator[](unsigned long const iIndex) const { return this->makePtr<Ptr<T> >(iIndex); }
0143 
0144     const_iterator begin() const { return const_iterator(this->void_begin(), this); }
0145 
0146     const_iterator end() const { return const_iterator(this->void_end(), this); }
0147     // ---------- member functions ---------------------------
0148 
0149     void push_back(Ptr<T> const& iPtr) {
0150       this->push_back_base(
0151           iPtr.refCore(), iPtr.key(), iPtr.hasProductCache() ? iPtr.operator->() : static_cast<void const*>(nullptr));
0152     }
0153 
0154     template <typename U>
0155     void push_back(Ptr<U> const& iPtr) {
0156       //check that types are assignable
0157       static_assert(std::is_base_of<T, U>::value,
0158                     "Ptr used in push_back can not be converted to type used by PtrVector.");
0159       this->push_back_base(
0160           iPtr.refCore(), iPtr.key(), iPtr.hasProductCache() ? iPtr.operator->() : static_cast<void const*>(nullptr));
0161     }
0162 
0163     void swap(PtrVector& other) { this->PtrVectorBase::swap(other); }
0164 
0165     PtrVector& operator=(PtrVector const& rhs) {
0166       PtrVector temp(rhs);
0167       this->swap(temp);
0168       return *this;
0169     }
0170 
0171     void fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const;
0172 
0173     //Used by ROOT storage
0174     CMS_CLASS_VERSION(8)
0175 
0176   private:
0177     //PtrVector const& operator=(PtrVector const&); // stop default
0178     std::type_info const& typeInfo() const override { return typeid(T); }
0179 
0180     // ---------- member data --------------------------------
0181     Ptr<T> fromItr(std::vector<void const*>::const_iterator const& iItr) const { return this->makePtr<Ptr<T> >(iItr); }
0182   };
0183 
0184   template <typename T>
0185   void PtrVector<T>::fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const {
0186     pointers.reserve(this->size());
0187     for (const_iterator i = begin(), e = end(); i != e; ++i) {
0188       Ptr<T> ref = *i;
0189       T const* address = ref.isNull() ? nullptr : &*ref;
0190       pointers.push_back(address);
0191       helpers.push_back(FillViewHelperVector::value_type(ref.id(), ref.key()));
0192     }
0193   }
0194 
0195   template <typename T>
0196   inline void fillView(PtrVector<T> const& obj,
0197                        ProductID const&,
0198                        std::vector<void const*>& pointers,
0199                        FillViewHelperVector& helpers) {
0200     obj.fillView(pointers, helpers);
0201   }
0202 
0203   template <typename T>
0204   struct has_fillView<PtrVector<T> > {
0205     static bool const value = true;
0206   };
0207 
0208   // Free swap function
0209   template <typename T>
0210   inline void swap(PtrVector<T>& lhs, PtrVector<T>& rhs) {
0211     lhs.swap(rhs);
0212   }
0213 }  // namespace edm
0214 #endif