Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_Common_PtrVectorBase_h
0002 #define DataFormats_Common_PtrVectorBase_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Common
0006 // Class  :     PtrVectorBase
0007 //
0008 /**\class edm::PtrVectorBase
0009 
0010  Description: Base class for PtrVector
0011 
0012  Usage:
0013     This class defines the common behavior for the PtrVector template class instances
0014 
0015 */
0016 //
0017 // Original Author:  Chris Jones
0018 //         Created:  Wed Oct 24 15:26:45 EDT 2007
0019 //
0020 
0021 // user include files
0022 #include "DataFormats/Common/interface/RefCore.h"
0023 
0024 // system include files
0025 #include <typeinfo>
0026 #include <vector>
0027 #include <cassert>
0028 
0029 // forward declarations
0030 
0031 namespace edm {
0032   class PtrVectorBase {
0033   public:
0034     typedef unsigned long key_type;
0035     typedef key_type size_type;
0036 
0037     explicit PtrVectorBase(ProductID const& productID,
0038                            void const* prodPtr = nullptr,
0039                            EDProductGetter const* prodGetter = nullptr)
0040         : core_(productID, prodPtr, prodGetter, false), indicies_(), cachedItems_(nullptr) {}
0041 
0042     PtrVectorBase(const PtrVectorBase&);
0043 
0044     PtrVectorBase& operator=(const PtrVectorBase&) = delete;
0045 
0046     virtual ~PtrVectorBase();
0047 
0048     // ---------- const member functions ---------------------
0049     /// Checks for null
0050     bool isNull() const { return !isNonnull(); }
0051 
0052     /// Checks for non-null
0053     //bool isNonnull() const {return id().isValid(); }
0054     bool isNonnull() const { return core_.isNonnull(); }
0055 
0056     /// Checks for null
0057     bool operator!() const { return isNull(); }
0058 
0059     /// Accessor for product ID.
0060     ProductID id() const { return core_.id(); }
0061 
0062     /// Accessor for product getter.
0063     EDProductGetter const* productGetter() const { return core_.productGetter(); }
0064 
0065     bool hasCache() const { return cachedItems_; }
0066 
0067     /// True if the data is in memory or is available in the Event
0068     /// No type checking is done.
0069     bool isAvailable() const;
0070 
0071     /// Is the RefVector empty
0072     bool empty() const { return indicies_.empty(); }
0073 
0074     /// Size of the RefVector
0075     size_type size() const { return indicies_.size(); }
0076 
0077     /// Capacity of the RefVector
0078     size_type capacity() const { return indicies_.capacity(); }
0079 
0080     /// Clear the PtrVector
0081     void clear() {
0082       core_ = RefCore();
0083       indicies_.clear();
0084       if (cachedItems_) {
0085         delete cachedItems_.load();
0086         cachedItems_.store(nullptr);
0087       }
0088     }
0089 
0090     bool operator==(PtrVectorBase const& iRHS) const;
0091     // ---------- static member functions --------------------
0092 
0093     // ---------- member functions ---------------------------
0094     /// Reserve space for RefVector
0095     void reserve(size_type n) {
0096       indicies_.reserve(n);
0097       if (cachedItems_) {
0098         (*cachedItems_).reserve(n);
0099       }
0100     }
0101 
0102     void setProductGetter(EDProductGetter* iGetter) const { core_.setProductGetter(iGetter); }
0103 
0104     bool isTransient() const { return core_.isTransient(); }
0105 
0106     void const* product() const { return nullptr; }
0107 
0108   protected:
0109     PtrVectorBase();
0110 
0111     /// swap
0112     void swap(PtrVectorBase& other);
0113 
0114     void push_back_base(RefCore const& core, key_type iKey, void const* iData);
0115 
0116     std::vector<void const*>::const_iterator void_begin() const {
0117       getProduct_();
0118       if (not checkCachedItems()) {
0119         return emptyCache().begin();
0120       }
0121       return (*cachedItems_).begin();
0122     }
0123     std::vector<void const*>::const_iterator void_end() const {
0124       getProduct_();
0125       if (not checkCachedItems()) {
0126         return emptyCache().end();
0127       }
0128       return (*cachedItems_).end();
0129     }
0130 
0131     template <typename TPtr>
0132     TPtr makePtr(unsigned long iIndex) const {
0133       if (isTransient()) {
0134         return TPtr(reinterpret_cast<typename TPtr::value_type const*>((*cachedItems_)[iIndex]), indicies_[iIndex]);
0135       }
0136       if (hasCache() && ((*cachedItems_)[iIndex] != nullptr || productGetter() == nullptr)) {
0137         return TPtr(
0138             this->id(), reinterpret_cast<typename TPtr::value_type const*>((*cachedItems_)[iIndex]), indicies_[iIndex]);
0139       }
0140       return TPtr(this->id(), indicies_[iIndex], productGetter());
0141     }
0142 
0143     template <typename TPtr>
0144     TPtr makePtr(std::vector<void const*>::const_iterator const iIt) const {
0145       if (isTransient()) {
0146         return TPtr(reinterpret_cast<typename TPtr::value_type const*>(*iIt), indicies_[iIt - (*cachedItems_).begin()]);
0147       }
0148       if (hasCache() && (*iIt != nullptr || productGetter() == nullptr)) {
0149         return TPtr(this->id(),
0150                     reinterpret_cast<typename TPtr::value_type const*>(*iIt),
0151                     indicies_[iIt - (*cachedItems_).begin()]);
0152       }
0153       return TPtr(this->id(), indicies_[iIt - (*cachedItems_).begin()], productGetter());
0154     }
0155 
0156   private:
0157     void getProduct_() const;
0158     //virtual std::type_info const& typeInfo() const = 0;
0159     virtual std::type_info const& typeInfo() const {
0160       assert(false);
0161       return typeid(void);
0162     }
0163 
0164     //returns false if the cache is not yet set
0165     bool checkCachedItems() const;
0166 
0167     //Used when we need an iterator but cache is not yet set
0168     static const std::vector<void const*>& emptyCache();
0169 
0170     // ---------- member data --------------------------------
0171     RefCore core_;
0172     std::vector<key_type> indicies_;
0173     mutable std::atomic<std::vector<void const*>*> cachedItems_;  //! transient
0174   };
0175 }  // namespace edm
0176 
0177 #endif