File indexing completed on 2024-04-06 12:03:53
0001 #ifndef DataFormats_Common_RefToBaseProd_h
0002 #define DataFormats_Common_RefToBaseProd_h
0003
0004
0005
0006
0007
0008
0009 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0010
0011 #include "DataFormats/Common/interface/EDProductfwd.h"
0012 #include "DataFormats/Common/interface/FillView.h"
0013 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0014 #include "DataFormats/Common/interface/Handle.h"
0015 #include "DataFormats/Common/interface/OrphanHandle.h"
0016 #include "DataFormats/Common/interface/RefCore.h"
0017 #include "DataFormats/Common/interface/RefProd.h"
0018 #include "DataFormats/Common/interface/View.h"
0019 #include "DataFormats/Common/interface/WrapperBase.h"
0020 #include "DataFormats/Provenance/interface/ProductID.h"
0021 #include "FWCore/Utilities/interface/EDMException.h"
0022
0023 #include <utility>
0024 #include <vector>
0025
0026 namespace edm {
0027
0028 template <typename T>
0029 class RefToBaseProd {
0030 public:
0031 typedef View<T> product_type;
0032
0033
0034 RefToBaseProd() : product_() {}
0035
0036 template <typename C>
0037 explicit RefToBaseProd(Handle<C> const& handle);
0038 explicit RefToBaseProd(Handle<View<T>> const& handle);
0039 template <typename C>
0040 explicit RefToBaseProd(OrphanHandle<C> const& handle);
0041 RefToBaseProd(const RefToBaseProd<T>&);
0042 template <typename C>
0043 explicit RefToBaseProd(const RefProd<C>&);
0044 RefToBaseProd(ProductID const&, EDProductGetter const*);
0045
0046
0047 ~RefToBaseProd() { delete viewPtr(); }
0048
0049
0050 product_type const& operator*() const;
0051
0052
0053 product_type const* operator->() const;
0054
0055
0056
0057 product_type const* get() const { return isNull() ? nullptr : this->operator->(); }
0058
0059
0060
0061 product_type const* product() const { return isNull() ? 0 : this->operator->(); }
0062
0063
0064 bool isNull() const { return !isNonnull(); }
0065
0066
0067 bool isNonnull() const { return product_.isNonnull(); }
0068
0069
0070
0071
0072
0073 bool isAvailable() const { return product_.isAvailable(); }
0074
0075
0076 bool operator!() const { return isNull(); }
0077
0078
0079 ProductID id() const { return product_.id(); }
0080
0081
0082 EDProductGetter const* productGetter() const { return product_.productGetter(); }
0083
0084
0085 bool hasCache() const { return product_.productPtr() != nullptr; }
0086
0087 RefToBaseProd<T>& operator=(const RefToBaseProd<T>& other);
0088
0089 void swap(RefToBaseProd<T>&);
0090
0091
0092 CMS_CLASS_VERSION(10)
0093 private:
0094
0095 RefCore const& refCore() const { return product_; }
0096
0097 View<T> const* viewPtr() const { return reinterpret_cast<const View<T>*>(product_.productPtr()); }
0098
0099 RefCore product_;
0100 };
0101
0102 template <typename T>
0103 inline RefToBaseProd<T>::RefToBaseProd(Handle<View<T>> const& handle)
0104 : product_(handle.id(), nullptr, nullptr, false) {
0105 product_.setProductPtr(new View<T>(*handle));
0106 }
0107
0108 template <typename T>
0109 inline RefToBaseProd<T>::RefToBaseProd(const RefToBaseProd<T>& ref) : product_(ref.product_) {
0110 if (product_.productPtr()) {
0111 product_.setProductPtr(ref.viewPtr() ? (new View<T>(*ref)) : nullptr);
0112 }
0113 }
0114
0115 template <typename T>
0116 inline RefToBaseProd<T>& RefToBaseProd<T>::operator=(const RefToBaseProd<T>& other) {
0117 RefToBaseProd<T> temp(other);
0118 this->swap(temp);
0119 return *this;
0120 }
0121
0122
0123 template <typename T>
0124 inline View<T> const& RefToBaseProd<T>::operator*() const {
0125 return *operator->();
0126 }
0127
0128
0129 template <typename T>
0130 inline View<T> const* RefToBaseProd<T>::operator->() const {
0131
0132 auto getter = product_.productGetter();
0133 if (getter != nullptr) {
0134 if (product_.isNull()) {
0135 Exception::throwThis(errors::InvalidReference, "attempting get view from a null RefToBaseProd.\n");
0136 }
0137 ProductID tId = product_.id();
0138 std::vector<void const*> pointers;
0139 FillViewHelperVector helpers;
0140 WrapperBase const* prod = getter->getIt(tId);
0141 if (prod == nullptr) {
0142 Exception::throwThis(errors::InvalidReference, "attempting to get view from an unavailable RefToBaseProd.");
0143 }
0144 prod->fillView(tId, pointers, helpers);
0145 std::unique_ptr<View<T>> tmp{new View<T>(pointers, helpers, getter)};
0146 if (product_.tryToSetProductPtrForFirstTime(tmp.get())) {
0147 tmp.release();
0148 }
0149 }
0150 return viewPtr();
0151 }
0152
0153 template <typename T>
0154 inline void RefToBaseProd<T>::swap(RefToBaseProd<T>& other) {
0155 edm::swap(product_, other.product_);
0156 }
0157
0158 template <typename T>
0159 inline bool operator==(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0160 return lhs.refCore() == rhs.refCore();
0161 }
0162
0163 template <typename T>
0164 inline bool operator!=(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0165 return !(lhs == rhs);
0166 }
0167
0168 template <typename T>
0169 inline bool operator<(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0170 return (lhs.refCore() < rhs.refCore());
0171 }
0172
0173 template <typename T>
0174 inline void swap(edm::RefToBaseProd<T> const& lhs, edm::RefToBaseProd<T> const& rhs) {
0175 lhs.swap(rhs);
0176 }
0177 }
0178
0179 #include "DataFormats/Common/interface/FillView.h"
0180
0181 namespace edm {
0182 template <typename T>
0183 template <typename C>
0184 inline RefToBaseProd<T>::RefToBaseProd(const RefProd<C>& ref) : product_(ref.refCore()) {
0185 std::vector<void const*> pointers;
0186 FillViewHelperVector helpers;
0187 fillView(*ref.product(), ref.id(), pointers, helpers);
0188 product_.setProductPtr(new View<T>(pointers, helpers, ref.refCore().productGetter()));
0189 }
0190
0191 template <typename T>
0192 template <typename C>
0193 inline RefToBaseProd<T>::RefToBaseProd(Handle<C> const& handle)
0194 : product_(handle.id(), handle.product(), nullptr, false) {
0195 std::vector<void const*> pointers;
0196 FillViewHelperVector helpers;
0197 fillView(*handle, handle.id(), pointers, helpers);
0198 product_.setProductPtr(new View<T>(pointers, helpers, nullptr));
0199 }
0200
0201 template <typename T>
0202 template <typename C>
0203 inline RefToBaseProd<T>::RefToBaseProd(OrphanHandle<C> const& handle)
0204 : product_(handle.id(), handle.product(), nullptr, false) {
0205 std::vector<void const*> pointers;
0206 FillViewHelperVector helpers;
0207 fillView(*handle, handle.id(), pointers, helpers);
0208 product_.setProductPtr(new View<T>(pointers, helpers, nullptr));
0209 }
0210
0211 template <typename T>
0212 inline RefToBaseProd<T>::RefToBaseProd(ProductID const& id, EDProductGetter const* getter)
0213 : product_(id, nullptr, getter, false) {}
0214 }
0215
0216 #endif