File indexing completed on 2024-04-06 12:03:53
0001 #ifndef DataFormats_Common_RefCore_h
0002 #define DataFormats_Common_RefCore_h
0003
0004
0005
0006
0007
0008
0009 #include "DataFormats/Provenance/interface/ProductID.h"
0010 #include "DataFormats/Common/interface/refcore_implementation.h"
0011
0012 #include <algorithm>
0013 #include <typeinfo>
0014 #include <atomic>
0015
0016 namespace edm {
0017 class RefCoreWithIndex;
0018 class EDProductGetter;
0019 class WrapperBase;
0020
0021 class RefCore {
0022
0023
0024 friend class RefCoreWithIndex;
0025
0026 public:
0027 RefCore() : cachePtr_(nullptr), processIndex_(0), productIndex_(0) {}
0028
0029 RefCore(ProductID const& theId, void const* prodPtr, EDProductGetter const* prodGetter, bool transient);
0030
0031 RefCore(RefCore const&);
0032
0033 RefCore& operator=(RefCore const&);
0034
0035 RefCore(RefCore&& iOther) noexcept : processIndex_(iOther.processIndex_), productIndex_(iOther.productIndex_) {
0036 cachePtr_.store(iOther.cachePtr_.load(std::memory_order_relaxed), std::memory_order_relaxed);
0037 }
0038
0039 RefCore& operator=(RefCore&& iOther) noexcept {
0040 cachePtr_.store(iOther.cachePtr_.load(std::memory_order_relaxed), std::memory_order_relaxed);
0041 processIndex_ = iOther.processIndex_;
0042 productIndex_ = iOther.productIndex_;
0043 return *this;
0044 }
0045
0046 ~RefCore() noexcept {}
0047
0048 ProductID id() const { ID_IMPL; }
0049
0050
0051 void const* productPtr() const { PRODUCTPTR_IMPL; }
0052
0053
0054
0055
0056
0057 void setProductPtr(void const* prodPtr) const { setCacheIsProductPtr(prodPtr); }
0058
0059
0060
0061
0062
0063 bool tryToSetProductPtrForFirstTime(void const* prodPtr) const {
0064 return refcoreimpl::tryToSetCacheItemForFirstTime(cachePtr_, prodPtr);
0065 }
0066
0067
0068 bool isNull() const { return !isNonnull(); }
0069
0070
0071 bool isNonnull() const { ISNONNULL_IMPL; }
0072
0073
0074 bool operator!() const { return isNull(); }
0075
0076
0077
0078
0079 bool isAvailable() const;
0080
0081 EDProductGetter const* productGetter() const { PRODUCTGETTER_IMPL; }
0082
0083 void setProductGetter(EDProductGetter const* prodGetter) const;
0084
0085 WrapperBase const* getProductPtr(std::type_info const& type, EDProductGetter const* prodGetter) const;
0086
0087 WrapperBase const* tryToGetProductPtr(std::type_info const& type, EDProductGetter const* prodGetter) const;
0088
0089
0090 std::tuple<WrapperBase const*, unsigned int> getThinnedProductPtr(std::type_info const& type,
0091 unsigned int key,
0092 EDProductGetter const* prodGetter) const;
0093
0094
0095 bool isThinnedAvailable(unsigned int key, EDProductGetter const* prodGetter) const;
0096
0097 void productNotFoundException(std::type_info const& type) const;
0098
0099 void wrongTypeException(std::type_info const& expectedType, std::type_info const& actualType) const;
0100
0101 void nullPointerForTransientException(std::type_info const& type) const;
0102
0103 void swap(RefCore&) noexcept;
0104
0105 bool isTransient() const { ISTRANSIENT_IMPL; }
0106
0107 int isTransientInt() const { return isTransient() ? 1 : 0; }
0108
0109 void pushBackItem(RefCore const& productToBeInserted, bool checkPointer);
0110
0111 void pushBackRefItem(RefCore const& productToBeInserted);
0112
0113 private:
0114 RefCore(void const* iCache, ProcessIndex iProcessIndex, ProductIndex iProductIndex)
0115 : cachePtr_(iCache), processIndex_(iProcessIndex), productIndex_(iProductIndex) {}
0116 void setId(ProductID const& iId);
0117 void setTransient() { SETTRANSIENT_IMPL; }
0118 void setCacheIsProductPtr(const void* iItem) const { SETCACHEISPRODUCTPTR_IMPL(iItem); }
0119 void setCacheIsProductGetter(EDProductGetter const* iGetter) const { SETCACHEISPRODUCTGETTER_IMPL(iGetter); }
0120 bool cachePtrIsInvalid() const {
0121 return 0 == (reinterpret_cast<std::uintptr_t>(cachePtr_.load()) & refcoreimpl::kCacheIsProductPtrMask);
0122 }
0123
0124
0125
0126
0127 mutable std::atomic<void const*> cachePtr_;
0128
0129
0130
0131
0132
0133 ProcessIndex processIndex_;
0134 ProductIndex productIndex_;
0135 };
0136
0137 inline bool operator==(RefCore const& lhs, RefCore const& rhs) {
0138 return lhs.isTransient() == rhs.isTransient() &&
0139 (lhs.isTransient() ? lhs.productPtr() == rhs.productPtr() : lhs.id() == rhs.id());
0140 }
0141
0142 inline bool operator!=(RefCore const& lhs, RefCore const& rhs) { return !(lhs == rhs); }
0143
0144 inline bool operator<(RefCore const& lhs, RefCore const& rhs) {
0145 return lhs.isTransient() ? (rhs.isTransient() ? lhs.productPtr() < rhs.productPtr() : false)
0146 : (rhs.isTransient() ? true : lhs.id() < rhs.id());
0147 }
0148
0149 inline void RefCore::swap(RefCore& other) noexcept {
0150 std::swap(processIndex_, other.processIndex_);
0151 std::swap(productIndex_, other.productIndex_);
0152 other.cachePtr_.store(cachePtr_.exchange(other.cachePtr_.load()));
0153 }
0154
0155 inline void swap(edm::RefCore& lhs, edm::RefCore& rhs) { lhs.swap(rhs); }
0156 }
0157
0158 #endif