File indexing completed on 2024-08-24 09:50:39
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 requires std::is_base_of_v<T, U>
0113 Ptr(Ptr<U> const& iOther)
0114 : core_(iOther.id(),
0115 (iOther.hasProductCache() ? static_cast<T const*>(iOther.get()) : static_cast<T const*>(nullptr)),
0116 iOther.productGetter(),
0117 iOther.isTransient()),
0118 key_(iOther.key()) {
0119
0120
0121 if (iOther.hasProductCache() and not hasProductCache()) {
0122 core_.setProductPtr(static_cast<T const*>(iOther.get()));
0123 }
0124 }
0125
0126 template <typename U>
0127 requires std::is_base_of_v<U, T>
0128 explicit Ptr(Ptr<U> const& iOther)
0129 : core_(iOther.id(), dynamic_cast<T const*>(iOther.get()), nullptr, iOther.isTransient()), key_(iOther.key()) {}
0130
0131
0132 ~Ptr() {}
0133
0134
0135 T const& operator*() const;
0136
0137
0138 T const* operator->() const;
0139
0140
0141 T const* get() const { return isNull() ? nullptr : this->operator->(); }
0142
0143
0144 bool isNull() const { return !isNonnull(); }
0145
0146
0147
0148 bool isNonnull() const { return key_traits<key_type>::value != key_; }
0149
0150 bool operator!() const { return isNull(); }
0151
0152
0153
0154
0155
0156 bool isAvailable() const;
0157
0158
0159 bool isTransient() const { return core_.isTransient(); }
0160
0161
0162 ProductID id() const { return core_.id(); }
0163
0164
0165 EDProductGetter const* productGetter() const { return core_.productGetter(); }
0166
0167 key_type key() const { return key_; }
0168
0169 bool hasProductCache() const { return nullptr != core_.productPtr(); }
0170
0171 RefCore const& refCore() const { return core_; }
0172
0173
0174 void const* product() const { return nullptr; }
0175
0176
0177 CMS_CLASS_VERSION(10)
0178
0179 private:
0180 template <typename C>
0181 T const* getItem_(C const* product, key_type iKey);
0182
0183 void getData_(bool throwIfNotFound = true) const {
0184 EDProductGetter const* getter = productGetter();
0185 if (getter != nullptr) {
0186 WrapperBase const* prod = getter->getIt(core_.id());
0187 unsigned int iKey = key_;
0188 if (prod == nullptr) {
0189 auto optionalProd = getter->getThinnedProduct(core_.id(), key_);
0190 if (not optionalProd.has_value()) {
0191 if (throwIfNotFound) {
0192 core_.productNotFoundException(typeid(T));
0193 } else {
0194 return;
0195 }
0196 }
0197 std::tie(prod, iKey) = *optionalProd;
0198 }
0199 void const* ad = nullptr;
0200 prod->setPtr(typeid(T), iKey, ad);
0201 core_.setProductPtr(ad);
0202 }
0203 }
0204
0205 RefCore core_;
0206 key_type key_;
0207 };
0208
0209 template <typename T>
0210 template <typename C>
0211 T const* Ptr<T>::getItem_(C const* iProduct, key_type iKey) {
0212 assert(iProduct != nullptr);
0213 typename C::const_iterator it = iProduct->begin();
0214 std::advance(it, iKey);
0215 T const* address = detail::GetProduct<C>::address(it);
0216 return address;
0217 }
0218
0219
0220 template <typename T>
0221 inline T const& Ptr<T>::operator*() const {
0222 getData_();
0223 return *reinterpret_cast<T const*>(core_.productPtr());
0224 }
0225
0226
0227 template <typename T>
0228 inline T const* Ptr<T>::operator->() const {
0229 getData_();
0230 return reinterpret_cast<T const*>(core_.productPtr());
0231 }
0232
0233 template <typename T>
0234 inline bool Ptr<T>::isAvailable() const {
0235 getData_(false);
0236 return hasProductCache();
0237 }
0238
0239 template <typename T>
0240 inline bool operator==(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0241 return lhs.refCore() == rhs.refCore() && lhs.key() == rhs.key();
0242 }
0243
0244 template <typename T>
0245 inline bool operator!=(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0246 return !(lhs == rhs);
0247 }
0248
0249 template <typename T>
0250 inline bool operator<(Ptr<T> const& lhs, Ptr<T> const& rhs) {
0251
0252
0253 return (lhs.refCore() == rhs.refCore() ? lhs.key() < rhs.key() : lhs.refCore() < rhs.refCore());
0254 }
0255 }
0256
0257
0258
0259 #include "DataFormats/Common/interface/HolderToVectorTrait_Ptr_specialization.h"
0260 #include <vector>
0261
0262 namespace edm {
0263 template <typename T>
0264 inline void fillView(std::vector<edm::Ptr<T> > const& obj,
0265 ProductID const& id,
0266 std::vector<void const*>& pointers,
0267 FillViewHelperVector& helpers) {
0268 pointers.reserve(obj.size());
0269 helpers.reserve(obj.size());
0270 for (auto const& p : obj) {
0271 if (p.isAvailable()) {
0272 pointers.push_back(p.get());
0273 } else {
0274 pointers.push_back(nullptr);
0275 }
0276 helpers.emplace_back(p.id(), p.key());
0277 }
0278 }
0279 }
0280
0281 #endif