PtrVectorBase

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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
#ifndef DataFormats_Common_PtrVectorBase_h
#define DataFormats_Common_PtrVectorBase_h
// -*- C++ -*-
//
// Package:     Common
// Class  :     PtrVectorBase
//
/**\class edm::PtrVectorBase

 Description: Base class for PtrVector

 Usage:
    This class defines the common behavior for the PtrVector template class instances

*/
//
// Original Author:  Chris Jones
//         Created:  Wed Oct 24 15:26:45 EDT 2007
//

// user include files
#include "DataFormats/Common/interface/RefCore.h"

// system include files
#include <typeinfo>
#include <vector>
#include <cassert>

// forward declarations

namespace edm {
  class PtrVectorBase {
  public:
    typedef unsigned long key_type;
    typedef key_type size_type;

    explicit PtrVectorBase(ProductID const& productID,
                           void const* prodPtr = nullptr,
                           EDProductGetter const* prodGetter = nullptr)
        : core_(productID, prodPtr, prodGetter, false), indicies_(), cachedItems_(nullptr) {}

    PtrVectorBase(const PtrVectorBase&);

    PtrVectorBase& operator=(const PtrVectorBase&) = delete;

    virtual ~PtrVectorBase();

    // ---------- const member functions ---------------------
    /// Checks for null
    bool isNull() const { return !isNonnull(); }

    /// Checks for non-null
    //bool isNonnull() const {return id().isValid(); }
    bool isNonnull() const { return core_.isNonnull(); }

    /// Checks for null
    bool operator!() const { return isNull(); }

    /// Accessor for product ID.
    ProductID id() const { return core_.id(); }

    /// Accessor for product getter.
    EDProductGetter const* productGetter() const { return core_.productGetter(); }

    bool hasCache() const { return cachedItems_; }

    /// True if the data is in memory or is available in the Event
    /// No type checking is done.
    bool isAvailable() const;

    /// Is the RefVector empty
    bool empty() const { return indicies_.empty(); }

    /// Size of the RefVector
    size_type size() const { return indicies_.size(); }

    /// Capacity of the RefVector
    size_type capacity() const { return indicies_.capacity(); }

    /// Clear the PtrVector
    void clear() {
      core_ = RefCore();
      indicies_.clear();
      if (cachedItems_) {
        delete cachedItems_.load();
        cachedItems_.store(nullptr);
      }
    }

    bool operator==(PtrVectorBase const& iRHS) const;
    // ---------- static member functions --------------------

    // ---------- member functions ---------------------------
    /// Reserve space for RefVector
    void reserve(size_type n) {
      indicies_.reserve(n);
      if (cachedItems_) {
        (*cachedItems_).reserve(n);
      }
    }

    void setProductGetter(EDProductGetter* iGetter) const { core_.setProductGetter(iGetter); }

    bool isTransient() const { return core_.isTransient(); }

    void const* product() const { return nullptr; }

  protected:
    PtrVectorBase();

    /// swap
    void swap(PtrVectorBase& other);

    void push_back_base(RefCore const& core, key_type iKey, void const* iData);

    std::vector<void const*>::const_iterator void_begin() const {
      getProduct_();
      if (not checkCachedItems()) {
        return emptyCache().begin();
      }
      return (*cachedItems_).begin();
    }
    std::vector<void const*>::const_iterator void_end() const {
      getProduct_();
      if (not checkCachedItems()) {
        return emptyCache().end();
      }
      return (*cachedItems_).end();
    }

    template <typename TPtr>
    TPtr makePtr(unsigned long iIndex) const {
      if (isTransient()) {
        return TPtr(reinterpret_cast<typename TPtr::value_type const*>((*cachedItems_)[iIndex]), indicies_[iIndex]);
      }
      if (hasCache() && ((*cachedItems_)[iIndex] != nullptr || productGetter() == nullptr)) {
        return TPtr(
            this->id(), reinterpret_cast<typename TPtr::value_type const*>((*cachedItems_)[iIndex]), indicies_[iIndex]);
      }
      return TPtr(this->id(), indicies_[iIndex], productGetter());
    }

    template <typename TPtr>
    TPtr makePtr(std::vector<void const*>::const_iterator const iIt) const {
      if (isTransient()) {
        return TPtr(reinterpret_cast<typename TPtr::value_type const*>(*iIt), indicies_[iIt - (*cachedItems_).begin()]);
      }
      if (hasCache() && (*iIt != nullptr || productGetter() == nullptr)) {
        return TPtr(this->id(),
                    reinterpret_cast<typename TPtr::value_type const*>(*iIt),
                    indicies_[iIt - (*cachedItems_).begin()]);
      }
      return TPtr(this->id(), indicies_[iIt - (*cachedItems_).begin()], productGetter());
    }

  private:
    void getProduct_() const;
    //virtual std::type_info const& typeInfo() const = 0;
    virtual std::type_info const& typeInfo() const {
      assert(false);
      return typeid(void);
    }

    //returns false if the cache is not yet set
    bool checkCachedItems() const;

    //Used when we need an iterator but cache is not yet set
    static const std::vector<void const*>& emptyCache();

    // ---------- member data --------------------------------
    RefCore core_;
    std::vector<key_type> indicies_;
    mutable std::atomic<std::vector<void const*>*> cachedItems_;  //! transient
  };
}  // namespace edm

#endif