File indexing completed on 2024-04-06 12:03:52
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
0153
0154 bool isAvailable() const;
0155
0156
0157 bool isTransient() const { return core_.isTransient(); }
0158
0159
0160 ProductID id() const { return core_.id(); }
0161
0162
0163 EDProductGetter const* productGetter() const { return core_.productGetter(); }
0164
0165 key_type key() const { return key_; }
0166
0167 bool hasProductCache() const { return nullptr != core_.productPtr(); }
0168
0169 RefCore const& refCore() const { return core_; }
0170
0171
0172 void const* product() const { return nullptr; }
0173
0174
0175 CMS_CLASS_VERSION(10)
0176
0177 private:
0178 template <typename C>
0179 T const* getItem_(C const* product, key_type iKey);
0180
0181 void getData_(bool throwIfNotFound = true) const {
0182 EDProductGetter const* getter = productGetter();
0183 if (getter != nullptr) {
0184 WrapperBase const* prod = getter->getIt(core_.id());
0185 unsigned int iKey = key_;
0186 if (prod == nullptr) {
0187 auto optionalProd = getter->getThinnedProduct(core_.id(), key_);
0188 if (not optionalProd.has_value()) {
0189 if (throwIfNotFound) {
0190 core_.productNotFoundException(typeid(T));
0191 } else {
0192 return;
0193 }
0194 }
0195 std::tie(prod, iKey) = *optionalProd;
0196 }
0197 void const* ad = nullptr;
0198 prod->setPtr(typeid(T), iKey, ad);
0199 core_.setProductPtr(ad);
0200 }
0201 }
0202
0203 RefCore core_;
0204 key_type key_;
0205 };
0206
0207 template <typename T>
0208 template <typename C>
0209 T const* Ptr<T>::getItem_(C const* iProduct, key_type iKey) {
0210 assert(iProduct != nullptr);
0211 typename C::const_iterator it = iProduct->begin();
0212 std::advance(it, iKey);
0213 T const* address = detail::GetProduct<C>::address(it);
0214 return address;
0215 }
0216
0217
0218 template <typename T>
0219 inline T const& Ptr<T>::operator*() const {
0220 getData_();
0221 return *reinterpret_cast<T const*>(core_.productPtr());
0222 }
0223
0224
0225 template <typename T>
0226 inline T const* Ptr<T>::operator->() const {
0227 getData_();
0228 return reinterpret_cast<T const*>(core_.productPtr());
0229 }
0230
0231 template <typename T>
0232 inline bool Ptr<T>::isAvailable() const {
0233 getData_(false);
0234 return hasProductCache();
0235 }
0236
0237 template <typename T>
0238 inline bool operator==(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0239 return lhs.refCore() == rhs.refCore() && lhs.key() == rhs.key();
0240 }
0241
0242 template <typename T>
0243 inline bool operator!=(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0244 return !(lhs == rhs);
0245 }
0246
0247 template <typename T>
0248 inline bool operator<(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0249
0250
0251 return (lhs.refCore() == rhs.refCore() ? lhs.key() < rhs.key() : lhs.refCore() < rhs.refCore());
0252 }
0253 }
0254
0255
0256
0257 #include "DataFormats/Common/interface/HolderToVectorTrait_Ptr_specialization.h"
0258 #include <vector>
0259
0260 namespace edm {
0261 template <typename T>
0262 inline void fillView(std::vector<edm::Ptr<T> > const& obj,
0263 ProductID const& id,
0264 std::vector<void const*>& pointers,
0265 FillViewHelperVector& helpers) {
0266 pointers.reserve(obj.size());
0267 helpers.reserve(obj.size());
0268 for (auto const& p : obj) {
0269 if (p.isAvailable()) {
0270 pointers.push_back(p.get());
0271 } else {
0272 pointers.push_back(nullptr);
0273 }
0274 helpers.emplace_back(p.id(), p.key());
0275 }
0276 }
0277 }
0278
0279 #endif