File indexing completed on 2021-02-14 12:53:02
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 bool operator!() const { return isNull(); }
0071
0072
0073 ProductID id() const { return product_.id(); }
0074
0075
0076 EDProductGetter const* productGetter() const { return product_.productGetter(); }
0077
0078
0079 bool hasCache() const { return product_.productPtr() != nullptr; }
0080
0081 RefToBaseProd<T>& operator=(const RefToBaseProd<T>& other);
0082
0083 void swap(RefToBaseProd<T>&);
0084
0085
0086 CMS_CLASS_VERSION(10)
0087 private:
0088
0089 RefCore const& refCore() const { return product_; }
0090
0091 View<T> const* viewPtr() const { return reinterpret_cast<const View<T>*>(product_.productPtr()); }
0092
0093 RefCore product_;
0094 };
0095
0096 template <typename T>
0097 inline RefToBaseProd<T>::RefToBaseProd(Handle<View<T>> const& handle)
0098 : product_(handle.id(), nullptr, nullptr, false) {
0099 product_.setProductPtr(new View<T>(*handle));
0100 }
0101
0102 template <typename T>
0103 inline RefToBaseProd<T>::RefToBaseProd(const RefToBaseProd<T>& ref) : product_(ref.product_) {
0104 if (product_.productPtr()) {
0105 product_.setProductPtr(ref.viewPtr() ? (new View<T>(*ref)) : nullptr);
0106 }
0107 }
0108
0109 template <typename T>
0110 inline RefToBaseProd<T>& RefToBaseProd<T>::operator=(const RefToBaseProd<T>& other) {
0111 RefToBaseProd<T> temp(other);
0112 this->swap(temp);
0113 return *this;
0114 }
0115
0116
0117 template <typename T>
0118 inline View<T> const& RefToBaseProd<T>::operator*() const {
0119 return *operator->();
0120 }
0121
0122
0123 template <typename T>
0124 inline View<T> const* RefToBaseProd<T>::operator->() const {
0125
0126 auto getter = product_.productGetter();
0127 if (getter != nullptr) {
0128 if (product_.isNull()) {
0129 Exception::throwThis(errors::InvalidReference, "attempting get view from a null RefToBaseProd.\n");
0130 }
0131 ProductID tId = product_.id();
0132 std::vector<void const*> pointers;
0133 FillViewHelperVector helpers;
0134 WrapperBase const* prod = getter->getIt(tId);
0135 if (prod == nullptr) {
0136 Exception::throwThis(errors::InvalidReference, "attempting to get view from an unavailable RefToBaseProd.");
0137 }
0138 prod->fillView(tId, pointers, helpers);
0139 std::unique_ptr<View<T>> tmp{new View<T>(pointers, helpers, getter)};
0140 if (product_.tryToSetProductPtrForFirstTime(tmp.get())) {
0141 tmp.release();
0142 }
0143 }
0144 return viewPtr();
0145 }
0146
0147 template <typename T>
0148 inline void RefToBaseProd<T>::swap(RefToBaseProd<T>& other) {
0149 edm::swap(product_, other.product_);
0150 }
0151
0152 template <typename T>
0153 inline bool operator==(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0154 return lhs.refCore() == rhs.refCore();
0155 }
0156
0157 template <typename T>
0158 inline bool operator!=(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0159 return !(lhs == rhs);
0160 }
0161
0162 template <typename T>
0163 inline bool operator<(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0164 return (lhs.refCore() < rhs.refCore());
0165 }
0166
0167 template <typename T>
0168 inline void swap(edm::RefToBaseProd<T> const& lhs, edm::RefToBaseProd<T> const& rhs) {
0169 lhs.swap(rhs);
0170 }
0171 }
0172
0173 #include "DataFormats/Common/interface/FillView.h"
0174
0175 namespace edm {
0176 template <typename T>
0177 template <typename C>
0178 inline RefToBaseProd<T>::RefToBaseProd(const RefProd<C>& ref) : product_(ref.refCore()) {
0179 std::vector<void const*> pointers;
0180 FillViewHelperVector helpers;
0181 fillView(*ref.product(), ref.id(), pointers, helpers);
0182 product_.setProductPtr(new View<T>(pointers, helpers, ref.refCore().productGetter()));
0183 }
0184
0185 template <typename T>
0186 template <typename C>
0187 inline RefToBaseProd<T>::RefToBaseProd(Handle<C> const& handle)
0188 : product_(handle.id(), handle.product(), nullptr, false) {
0189 std::vector<void const*> pointers;
0190 FillViewHelperVector helpers;
0191 fillView(*handle, handle.id(), pointers, helpers);
0192 product_.setProductPtr(new View<T>(pointers, helpers, nullptr));
0193 }
0194
0195 template <typename T>
0196 template <typename C>
0197 inline RefToBaseProd<T>::RefToBaseProd(OrphanHandle<C> const& handle)
0198 : product_(handle.id(), handle.product(), nullptr, false) {
0199 std::vector<void const*> pointers;
0200 FillViewHelperVector helpers;
0201 fillView(*handle, handle.id(), pointers, helpers);
0202 product_.setProductPtr(new View<T>(pointers, helpers, nullptr));
0203 }
0204
0205 template <typename T>
0206 inline RefToBaseProd<T>::RefToBaseProd(ProductID const& id, EDProductGetter const* getter)
0207 : product_(id, nullptr, getter, false) {}
0208 }
0209
0210 #endif