RefVectorBase

RefVectorMemberPointersHolder

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
#ifndef DataFormats_Common_RefVectorBase_h
#define DataFormats_Common_RefVectorBase_h

/*----------------------------------------------------------------------
  
RefVectorBase: Base class for a vector of interproduct references.


----------------------------------------------------------------------*/

#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
#include "DataFormats/Common/interface/EDProductfwd.h"
#include "DataFormats/Common/interface/RefCore.h"
#include <vector>

namespace edm {

  class EDProductGetter;

  class RefVectorMemberPointersHolder {
  public:
    RefVectorMemberPointersHolder() {}
    std::vector<void const*> const& memberPointers() const { return memberPointers_; }
    std::vector<void const*>& memberPointers() { return memberPointers_; }

  private:
    std::vector<void const*> memberPointers_;
  };

  template <typename KEY>
  class RefVectorBase {
  public:
    typedef std::vector<KEY> keys_type;
    typedef KEY key_type;
    typedef typename keys_type::size_type size_type;
    /// Default constructor needed for reading from persistent store. Not for direct use.
    RefVectorBase() : product_(), keys_() {}
    RefVectorBase(RefVectorBase const& rhs)
        : product_(rhs.product_), keys_(rhs.keys_), memberPointersHolder_(rhs.memberPointersHolder_) {}
    RefVectorBase(RefVectorBase&& rhs) noexcept
        : product_(std::move(rhs.product_)),
          keys_(std::move(rhs.keys_)),
          memberPointersHolder_(std::move(rhs.memberPointersHolder_)) {}

    RefVectorBase& operator=(RefVectorBase const& rhs) {
      RefVectorBase temp(rhs);
      this->swap(temp);
      return *this;
    }
    RefVectorBase& operator=(RefVectorBase&& rhs) noexcept {
      product_ = std::move(rhs.product_);
      keys_ = std::move(rhs.keys_);
      memberPointersHolder_ = std::move(rhs.memberPointersHolder_);
      return *this;
    }

    explicit RefVectorBase(ProductID const& productID,
                           void const* prodPtr = nullptr,
                           EDProductGetter const* prodGetter = nullptr)
        : product_(productID, prodPtr, prodGetter, false), keys_() {}

    /// Destructor
    ~RefVectorBase() noexcept {}

    /// Accessor for product ID and product getter
    RefCore const& refCore() const { return product_; }

    void const* cachedMemberPointer(size_type idx) const {
      return memberPointers().empty() ? nullptr : memberPointers()[idx];
    }

    /// Accessor for vector of keys and pointers
    keys_type const& keys() const { return keys_; }

    /// Is vector empty?
    bool empty() const { return keys_.empty(); }

    /// Size of vector
    size_type size() const { return keys_.size(); }

    void pushBack(RefCore const& product, KEY const& key) {
      product_.pushBackRefItem(product);
      if (product.productPtr() != nullptr) {
        if (memberPointers().empty()) {
          memberPointersHolder_.memberPointers().resize(keys_.size(), nullptr);
        }
        memberPointersHolder_.memberPointers().push_back(product.productPtr());
        keys_.push_back(key);
        return;
      } else {
        if (!memberPointers().empty()) {
          memberPointersHolder_.memberPointers().push_back(nullptr);
        }
        keys_.push_back(key);
      }
    }

    /// Capacity of vector
    size_type capacity() const { return keys_.capacity(); }

    /// Reserve space for vector
    void reserve(size_type n) { keys_.reserve(n); }

    /// erase an element from the vector
    typename keys_type::iterator eraseAtIndex(size_type index) {
      memberPointersHolder_.memberPointers().erase(memberPointersHolder_.memberPointers().begin() + index);
      return keys_.erase(keys_.begin() + index);
    }

    /// clear the vector
    void clear() {
      keys_.clear();
      memberPointersHolder_.memberPointers().clear();
      product_ = RefCore();
    }

    /// swap two vectors
    void swap(RefVectorBase<KEY>& other) noexcept {
      product_.swap(other.product_);
      keys_.swap(other.keys_);
      memberPointersHolder_.memberPointers().swap(other.memberPointersHolder_.memberPointers());
    }

    //Needed for ROOT storage
    CMS_CLASS_VERSION(13)

  private:
    std::vector<void const*> const& memberPointers() const { return memberPointersHolder_.memberPointers(); }

    RefCore product_;
    keys_type keys_;
    RefVectorMemberPointersHolder memberPointersHolder_;
  };

  /// Equality operator
  template <typename KEY>
  bool operator==(RefVectorBase<KEY> const& lhs, RefVectorBase<KEY> const& rhs) {
    return lhs.refCore() == rhs.refCore() && lhs.keys() == rhs.keys();
  }

  /// Inequality operator
  template <typename KEY>
  bool operator!=(RefVectorBase<KEY> const& lhs, RefVectorBase<KEY> const& rhs) {
    return !(lhs == rhs);
  }

  /// swap two vectors
  template <typename KEY>
  inline void swap(RefVectorBase<KEY>& a, RefVectorBase<KEY>& b) {
    a.swap(b);
  }

}  // namespace edm
#endif