File indexing completed on 2021-02-14 12:53:01
0001 #ifndef DataFormats_Common_Ptr_h
0002 #define DataFormats_Common_Ptr_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0023 #include "DataFormats/Common/interface/WrapperBase.h"
0024 #include "DataFormats/Common/interface/EDProductGetter.h"
0025 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0026 #include "DataFormats/Common/interface/GetProduct.h"
0027 #include "DataFormats/Common/interface/Handle.h"
0028 #include "DataFormats/Common/interface/OrphanHandle.h"
0029 #include "DataFormats/Common/interface/RefCore.h"
0030 #include "DataFormats/Common/interface/TestHandle.h"
0031 #include "DataFormats/Common/interface/traits.h"
0032 #include "DataFormats/Provenance/interface/ProductID.h"
0033
0034
0035 #include <type_traits>
0036
0037
0038 namespace edm {
0039 template <typename T>
0040 class Ptr {
0041 friend class PtrVectorBase;
0042
0043 public:
0044 typedef unsigned long key_type;
0045 typedef T value_type;
0046
0047
0048 template <typename C>
0049 Ptr(Handle<C> const& handle, key_type itemKey, bool = true)
0050 : core_(handle.id(), getItem_(handle.product(), itemKey), nullptr, false), key_(itemKey) {}
0051
0052
0053 template <typename C>
0054 Ptr(OrphanHandle<C> const& handle, key_type itemKey, bool = true)
0055 : core_(handle.id(), getItem_(handle.product(), itemKey), nullptr, false), key_(itemKey) {}
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 template <typename C>
0070 Ptr(C const* iProduct, key_type iItemKey, bool = true)
0071 : core_(ProductID(), iProduct != nullptr ? getItem_(iProduct, iItemKey) : nullptr, nullptr, true),
0072 key_(iProduct != nullptr ? iItemKey : key_traits<key_type>::value) {}
0073
0074 Ptr(T const* item, key_type iItemKey)
0075 : core_(ProductID(), item, nullptr, true), key_(item != nullptr ? iItemKey : key_traits<key_type>::value) {}
0076
0077
0078
0079
0080 template <typename C>
0081 Ptr(TestHandle<C> const& handle, key_type itemKey, bool = true)
0082 : core_(handle.id(), getItem_(handle.product(), itemKey), nullptr, true), key_(itemKey) {}
0083
0084
0085
0086
0087 Ptr(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0088 : core_(productID, nullptr, mustBeNonZero(prodGetter, "Ptr", productID), false), key_(itemKey) {}
0089
0090
0091
0092
0093
0094
0095
0096
0097 Ptr(ProductID const& productID, T const* item, key_type item_key)
0098 : core_(productID, item, nullptr, false), key_(item_key) {}
0099
0100 Ptr(ProductID const& productID, T const* item, key_type item_key, bool transient)
0101 : core_(productID, item, nullptr, transient), key_(item_key) {}
0102
0103
0104
0105
0106
0107 explicit Ptr(ProductID const& iId) : core_(iId, nullptr, nullptr, false), key_(key_traits<key_type>::value) {}
0108
0109 Ptr() : core_(), key_(key_traits<key_type>::value) {}
0110
0111 template <typename U>
0112 Ptr(Ptr<U> const& iOther, std::enable_if_t<std::is_base_of<T, U>::value>* = nullptr)
0113 : core_(iOther.id(),
0114 (iOther.hasProductCache() ? static_cast<T const*>(iOther.get()) : static_cast<T const*>(nullptr)),
0115 iOther.productGetter(),
0116 iOther.isTransient()),
0117 key_(iOther.key()) {
0118
0119
0120 if (iOther.hasProductCache() and not hasProductCache()) {
0121 core_.setProductPtr(static_cast<T const*>(iOther.get()));
0122 }
0123 }
0124
0125 template <typename U>
0126 explicit Ptr(Ptr<U> const& iOther, std::enable_if_t<std::is_base_of<U, T>::value>* = nullptr)
0127 : core_(iOther.id(), dynamic_cast<T const*>(iOther.get()), nullptr, iOther.isTransient()), key_(iOther.key()) {}
0128
0129
0130 ~Ptr() {}
0131
0132
0133 T const& operator*() const;
0134
0135
0136 T const* operator->() const;
0137
0138
0139 T const* get() const { return isNull() ? nullptr : this->operator->(); }
0140
0141
0142 bool isNull() const { return !isNonnull(); }
0143
0144
0145
0146 bool isNonnull() const { return key_traits<key_type>::value != key_; }
0147
0148 bool operator!() const { return isNull(); }
0149
0150
0151
0152 bool isAvailable() const;
0153
0154
0155 bool isTransient() const { return core_.isTransient(); }
0156
0157
0158 ProductID id() const { return core_.id(); }
0159
0160
0161 EDProductGetter const* productGetter() const { return core_.productGetter(); }
0162
0163 key_type key() const { return key_; }
0164
0165 bool hasProductCache() const { return nullptr != core_.productPtr(); }
0166
0167 RefCore const& refCore() const { return core_; }
0168
0169
0170 void const* product() const { return nullptr; }
0171
0172
0173 CMS_CLASS_VERSION(10)
0174
0175 private:
0176 template <typename C>
0177 T const* getItem_(C const* product, key_type iKey);
0178
0179 void getData_(bool throwIfNotFound = true) const {
0180 EDProductGetter const* getter = productGetter();
0181 if (getter != nullptr) {
0182 WrapperBase const* prod = getter->getIt(core_.id());
0183 unsigned int iKey = key_;
0184 if (prod == nullptr) {
0185 auto optionalProd = getter->getThinnedProduct(core_.id(), key_);
0186 if (not optionalProd.has_value()) {
0187 if (throwIfNotFound) {
0188 core_.productNotFoundException(typeid(T));
0189 } else {
0190 return;
0191 }
0192 }
0193 std::tie(prod, iKey) = *optionalProd;
0194 }
0195 void const* ad = nullptr;
0196 prod->setPtr(typeid(T), iKey, ad);
0197 core_.setProductPtr(ad);
0198 }
0199 }
0200
0201 RefCore core_;
0202 key_type key_;
0203 };
0204
0205 template <typename T>
0206 template <typename C>
0207 T const* Ptr<T>::getItem_(C const* iProduct, key_type iKey) {
0208 assert(iProduct != nullptr);
0209 typename C::const_iterator it = iProduct->begin();
0210 std::advance(it, iKey);
0211 T const* address = detail::GetProduct<C>::address(it);
0212 return address;
0213 }
0214
0215
0216 template <typename T>
0217 inline T const& Ptr<T>::operator*() const {
0218 getData_();
0219 return *reinterpret_cast<T const*>(core_.productPtr());
0220 }
0221
0222
0223 template <typename T>
0224 inline T const* Ptr<T>::operator->() const {
0225 getData_();
0226 return reinterpret_cast<T const*>(core_.productPtr());
0227 }
0228
0229 template <typename T>
0230 inline bool Ptr<T>::isAvailable() const {
0231 getData_(false);
0232 return hasProductCache();
0233 }
0234
0235 template <typename T>
0236 inline bool operator==(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0237 return lhs.refCore() == rhs.refCore() && lhs.key() == rhs.key();
0238 }
0239
0240 template <typename T>
0241 inline bool operator!=(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0242 return !(lhs == rhs);
0243 }
0244
0245 template <typename T>
0246 inline bool operator<(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0247
0248
0249 return (lhs.refCore() == rhs.refCore() ? lhs.key() < rhs.key() : lhs.refCore() < rhs.refCore());
0250 }
0251 }
0252
0253
0254
0255 #include "DataFormats/Common/interface/HolderToVectorTrait_Ptr_specialization.h"
0256 #include <vector>
0257
0258 namespace edm {
0259 template <typename T>
0260 inline void fillView(std::vector<edm::Ptr<T> > const& obj,
0261 ProductID const& id,
0262 std::vector<void const*>& pointers,
0263 FillViewHelperVector& helpers) {
0264 pointers.reserve(obj.size());
0265 helpers.reserve(obj.size());
0266 for (auto const& p : obj) {
0267 if (p.isAvailable()) {
0268 pointers.push_back(p.get());
0269 } else {
0270 pointers.push_back(nullptr);
0271 }
0272 helpers.emplace_back(p.id(), p.key());
0273 }
0274 }
0275 }
0276
0277 #endif