Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:53

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 {
0052   public:
0053     using iterator_category = std::random_access_iterator_tag;
0054     using value_type = Ptr<T>;
0055     using pointer = Ptr<T>*;
0056     using reference = Ptr<T> const;  // otherwise boost::range does not work
0057                                      // const, because this is a const_iterator
0058     using iterator = PtrVectorItr<T>;
0059     using difference_type = std::ptrdiff_t;
0060 
0061     PtrVectorItr(std::vector<void const*>::const_iterator const& iItr, PtrVector<T> const* iBase)
0062         : iter_(iItr), base_(iBase) {}
0063 
0064     Ptr<T> const operator*() const { return base_->fromItr(iter_); }
0065 
0066     Ptr<T> const operator[](difference_type n) const {  // Otherwise the
0067       return base_->fromItr(iter_ + n);                 // boost::range
0068     }                                                   // doesn't have []
0069 
0070     PtrHolder<T> operator->() const { return PtrHolder<T>(this->operator*()); }
0071 
0072     iterator& operator++() {
0073       ++iter_;
0074       return *this;
0075     }
0076     iterator& operator--() {
0077       --iter_;
0078       return *this;
0079     }
0080     iterator& operator+=(difference_type n) {
0081       iter_ += n;
0082       return *this;
0083     }
0084     iterator& operator-=(difference_type n) {
0085       iter_ -= n;
0086       return *this;
0087     }
0088 
0089     iterator operator++(int) {
0090       iterator it(*this);
0091       ++iter_;
0092       return it;
0093     }
0094     iterator operator--(int) {
0095       iterator it(*this);
0096       --iter_;
0097       return it;
0098     }
0099     iterator operator+(difference_type n) const {
0100       iterator it(*this);
0101       it.iter_ += n;
0102       return it;
0103     }
0104     iterator operator-(difference_type n) const {
0105       iterator it(*this);
0106       it.iter_ -= n;
0107       return it;
0108     }
0109 
0110     difference_type operator-(iterator const& rhs) const { return this->iter_ - rhs.iter_; }
0111 
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     bool operator>(iterator const& rhs) const { return this->iter_ > rhs.iter_; }
0116     bool operator<=(iterator const& rhs) const { return this->iter_ <= rhs.iter_; }
0117     bool operator>=(iterator const& rhs) const { return this->iter_ >= rhs.iter_; }
0118 
0119   private:
0120     std::vector<void const*>::const_iterator iter_;
0121     PtrVector<T> const* base_;
0122   };
0123 
0124   template <typename T>
0125   class PtrVector : public PtrVectorBase {
0126   public:
0127     using const_iterator = PtrVectorItr<T>;
0128     using iterator = PtrVectorItr<T>;  // make boost::sub_range happy (std allows this)
0129     using value_type = Ptr<T>;
0130     using member_type = T;
0131     using collection_type = void;
0132 
0133     friend class PtrVectorItr<T>;
0134     PtrVector() : PtrVectorBase() {}
0135     explicit PtrVector(ProductID const& iId) : PtrVectorBase(iId) {}
0136     PtrVector(PtrVector<T> const& iOther) : PtrVectorBase(iOther) {}
0137 
0138     template <typename U>
0139     PtrVector(PtrVector<U> const& iOther) : PtrVectorBase(iOther) {
0140       static_assert(std::is_base_of<T, U>::value, "PtrVector being copied is not of compatible type");
0141     }
0142 
0143     // ---------- const member functions ---------------------
0144 
0145     Ptr<T> operator[](unsigned long const iIndex) const { return this->makePtr<Ptr<T> >(iIndex); }
0146 
0147     const_iterator begin() const { return const_iterator(this->void_begin(), this); }
0148 
0149     const_iterator end() const { return const_iterator(this->void_end(), this); }
0150     // ---------- member functions ---------------------------
0151 
0152     void push_back(Ptr<T> const& iPtr) {
0153       this->push_back_base(
0154           iPtr.refCore(), iPtr.key(), iPtr.hasProductCache() ? iPtr.operator->() : static_cast<void const*>(nullptr));
0155     }
0156 
0157     template <typename U>
0158     void push_back(Ptr<U> const& iPtr) {
0159       //check that types are assignable
0160       static_assert(std::is_base_of<T, U>::value,
0161                     "Ptr used in push_back can not be converted to type used by PtrVector.");
0162       this->push_back_base(
0163           iPtr.refCore(), iPtr.key(), iPtr.hasProductCache() ? iPtr.operator->() : static_cast<void const*>(nullptr));
0164     }
0165 
0166     void swap(PtrVector& other) { this->PtrVectorBase::swap(other); }
0167 
0168     PtrVector& operator=(PtrVector const& rhs) {
0169       PtrVector temp(rhs);
0170       this->swap(temp);
0171       return *this;
0172     }
0173 
0174     void fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const;
0175 
0176     //Used by ROOT storage
0177     CMS_CLASS_VERSION(8)
0178 
0179   private:
0180     //PtrVector const& operator=(PtrVector const&); // stop default
0181     std::type_info const& typeInfo() const override { return typeid(T); }
0182 
0183     // ---------- member data --------------------------------
0184     Ptr<T> fromItr(std::vector<void const*>::const_iterator const& iItr) const { return this->makePtr<Ptr<T> >(iItr); }
0185   };
0186 
0187   template <typename T>
0188   void PtrVector<T>::fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const {
0189     pointers.reserve(this->size());
0190     for (const_iterator i = begin(), e = end(); i != e; ++i) {
0191       Ptr<T> ref = *i;
0192       T const* address = ref.isNull() ? nullptr : &*ref;
0193       pointers.push_back(address);
0194       helpers.push_back(FillViewHelperVector::value_type(ref.id(), ref.key()));
0195     }
0196   }
0197 
0198   template <typename T>
0199   inline void fillView(PtrVector<T> const& obj,
0200                        ProductID const&,
0201                        std::vector<void const*>& pointers,
0202                        FillViewHelperVector& helpers) {
0203     obj.fillView(pointers, helpers);
0204   }
0205 
0206   template <typename T>
0207   struct has_fillView<PtrVector<T> > {
0208     static bool const value = true;
0209   };
0210 
0211   // Free swap function
0212   template <typename T>
0213   inline void swap(PtrVector<T>& lhs, PtrVector<T>& rhs) {
0214     lhs.swap(rhs);
0215   }
0216 }  // namespace edm
0217 #endif