Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_Common_RefVectorBase_h
0002 #define DataFormats_Common_RefVectorBase_h
0003 
0004 /*----------------------------------------------------------------------
0005   
0006 RefVectorBase: Base class for a vector of interproduct references.
0007 
0008 
0009 ----------------------------------------------------------------------*/
0010 
0011 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0012 #include "DataFormats/Common/interface/EDProductfwd.h"
0013 #include "DataFormats/Common/interface/RefCore.h"
0014 #include <vector>
0015 
0016 namespace edm {
0017 
0018   class EDProductGetter;
0019 
0020   class RefVectorMemberPointersHolder {
0021   public:
0022     RefVectorMemberPointersHolder() {}
0023     std::vector<void const*> const& memberPointers() const { return memberPointers_; }
0024     std::vector<void const*>& memberPointers() { return memberPointers_; }
0025 
0026   private:
0027     std::vector<void const*> memberPointers_;
0028   };
0029 
0030   template <typename KEY>
0031   class RefVectorBase {
0032   public:
0033     typedef std::vector<KEY> keys_type;
0034     typedef KEY key_type;
0035     typedef typename keys_type::size_type size_type;
0036     /// Default constructor needed for reading from persistent store. Not for direct use.
0037     RefVectorBase() : product_(), keys_() {}
0038     RefVectorBase(RefVectorBase const& rhs)
0039         : product_(rhs.product_), keys_(rhs.keys_), memberPointersHolder_(rhs.memberPointersHolder_) {}
0040     RefVectorBase(RefVectorBase&& rhs) noexcept
0041         : product_(std::move(rhs.product_)),
0042           keys_(std::move(rhs.keys_)),
0043           memberPointersHolder_(std::move(rhs.memberPointersHolder_)) {}
0044 
0045     RefVectorBase& operator=(RefVectorBase const& rhs) {
0046       RefVectorBase temp(rhs);
0047       this->swap(temp);
0048       return *this;
0049     }
0050     RefVectorBase& operator=(RefVectorBase&& rhs) noexcept {
0051       product_ = std::move(rhs.product_);
0052       keys_ = std::move(rhs.keys_);
0053       memberPointersHolder_ = std::move(rhs.memberPointersHolder_);
0054       return *this;
0055     }
0056 
0057     explicit RefVectorBase(ProductID const& productID,
0058                            void const* prodPtr = nullptr,
0059                            EDProductGetter const* prodGetter = nullptr)
0060         : product_(productID, prodPtr, prodGetter, false), keys_() {}
0061 
0062     /// Destructor
0063     ~RefVectorBase() noexcept {}
0064 
0065     /// Accessor for product ID and product getter
0066     RefCore const& refCore() const { return product_; }
0067 
0068     void const* cachedMemberPointer(size_type idx) const {
0069       return memberPointers().empty() ? nullptr : memberPointers()[idx];
0070     }
0071 
0072     /// Accessor for vector of keys and pointers
0073     keys_type const& keys() const { return keys_; }
0074 
0075     /// Is vector empty?
0076     bool empty() const { return keys_.empty(); }
0077 
0078     /// Size of vector
0079     size_type size() const { return keys_.size(); }
0080 
0081     void pushBack(RefCore const& product, KEY const& key) {
0082       product_.pushBackRefItem(product);
0083       if (product.productPtr() != nullptr) {
0084         if (memberPointers().empty()) {
0085           memberPointersHolder_.memberPointers().resize(keys_.size(), nullptr);
0086         }
0087         memberPointersHolder_.memberPointers().push_back(product.productPtr());
0088         keys_.push_back(key);
0089         return;
0090       } else {
0091         if (!memberPointers().empty()) {
0092           memberPointersHolder_.memberPointers().push_back(nullptr);
0093         }
0094         keys_.push_back(key);
0095       }
0096     }
0097 
0098     /// Capacity of vector
0099     size_type capacity() const { return keys_.capacity(); }
0100 
0101     /// Reserve space for vector
0102     void reserve(size_type n) { keys_.reserve(n); }
0103 
0104     /// erase an element from the vector
0105     typename keys_type::iterator eraseAtIndex(size_type index) {
0106       memberPointersHolder_.memberPointers().erase(memberPointersHolder_.memberPointers().begin() + index);
0107       return keys_.erase(keys_.begin() + index);
0108     }
0109 
0110     /// clear the vector
0111     void clear() {
0112       keys_.clear();
0113       memberPointersHolder_.memberPointers().clear();
0114       product_ = RefCore();
0115     }
0116 
0117     /// swap two vectors
0118     void swap(RefVectorBase<KEY>& other) noexcept {
0119       product_.swap(other.product_);
0120       keys_.swap(other.keys_);
0121       memberPointersHolder_.memberPointers().swap(other.memberPointersHolder_.memberPointers());
0122     }
0123 
0124     //Needed for ROOT storage
0125     CMS_CLASS_VERSION(13)
0126 
0127   private:
0128     std::vector<void const*> const& memberPointers() const { return memberPointersHolder_.memberPointers(); }
0129 
0130     RefCore product_;
0131     keys_type keys_;
0132     RefVectorMemberPointersHolder memberPointersHolder_;
0133   };
0134 
0135   /// Equality operator
0136   template <typename KEY>
0137   bool operator==(RefVectorBase<KEY> const& lhs, RefVectorBase<KEY> const& rhs) {
0138     return lhs.refCore() == rhs.refCore() && lhs.keys() == rhs.keys();
0139   }
0140 
0141   /// Inequality operator
0142   template <typename KEY>
0143   bool operator!=(RefVectorBase<KEY> const& lhs, RefVectorBase<KEY> const& rhs) {
0144     return !(lhs == rhs);
0145   }
0146 
0147   /// swap two vectors
0148   template <typename KEY>
0149   inline void swap(RefVectorBase<KEY>& a, RefVectorBase<KEY>& b) {
0150     a.swap(b);
0151   }
0152 
0153 }  // namespace edm
0154 #endif