File indexing completed on 2024-04-06 12:03:53
0001 #ifndef DataFormats_Common_refcore_implementation_h
0002 #define DataFormats_Common_refcore_implementation_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <limits>
0025 #include <cstdint>
0026 #include <atomic>
0027
0028
0029
0030
0031 namespace edm {
0032 class EDProductGetter;
0033
0034 namespace refcoreimpl {
0035 const unsigned short kTransientBit = 0x8000;
0036 const unsigned short kProcessIndexMask = 0x3FFF;
0037 const std::uintptr_t kCacheIsProductPtrBit = 0x1;
0038 const std::uintptr_t kCacheIsProductPtrMask = std::numeric_limits<std::uintptr_t>::max() ^ kCacheIsProductPtrBit;
0039
0040 inline bool cacheIsProductPtr(void const* iPtr) {
0041 return 0 == (reinterpret_cast<std::uintptr_t>(iPtr) & refcoreimpl::kCacheIsProductPtrBit);
0042 }
0043
0044 inline void setCacheIsProductGetter(std::atomic<void const*>& ptr, EDProductGetter const* iGetter) {
0045 std::uintptr_t tmp = reinterpret_cast<std::uintptr_t>(iGetter);
0046 tmp |= refcoreimpl::kCacheIsProductPtrBit;
0047 ptr.store(reinterpret_cast<void const*>(tmp));
0048 }
0049
0050
0051 inline void setCacheIsProductGetter(void const*& ptr, EDProductGetter const* iGetter) {
0052 std::uintptr_t tmp = reinterpret_cast<std::uintptr_t>(iGetter);
0053 tmp |= refcoreimpl::kCacheIsProductPtrBit;
0054 ptr = reinterpret_cast<void const*>(tmp);
0055 }
0056
0057 inline void setCacheIsItem(std::atomic<void const*>& iCache, void const* iNewValue) { iCache = iNewValue; }
0058
0059 inline bool tryToSetCacheItemForFirstTime(std::atomic<void const*>& iCache, void const* iNewValue) {
0060 auto cache = iCache.load();
0061 if (not cacheIsProductPtr(cache)) {
0062 return iCache.compare_exchange_strong(cache, iNewValue);
0063 }
0064 return false;
0065 }
0066
0067 inline void const* productPtr(std::atomic<void const*> const& iCache) {
0068 auto tmp = iCache.load();
0069 return refcoreimpl::cacheIsProductPtr(tmp) ? tmp : static_cast<void const*>(nullptr);
0070 }
0071
0072 inline EDProductGetter const* productGetter(std::atomic<void const*> const& iCache) {
0073 auto tmp = iCache.load();
0074 return (!refcoreimpl::cacheIsProductPtr(tmp))
0075 ? reinterpret_cast<EDProductGetter const*>(reinterpret_cast<std::uintptr_t>(tmp) &
0076 refcoreimpl::kCacheIsProductPtrMask)
0077 : static_cast<EDProductGetter const*>(nullptr);
0078 }
0079
0080 }
0081 }
0082
0083 #define ID_IMPL return ProductID(processIndex_ & refcoreimpl::kProcessIndexMask, productIndex_)
0084
0085 #define PRODUCTPTR_IMPL return refcoreimpl::productPtr(cachePtr_)
0086
0087 #define ISNONNULL_IMPL return isTransient() ? productPtr() != nullptr : id().isValid()
0088
0089 #define PRODUCTGETTER_IMPL return refcoreimpl::productGetter(cachePtr_)
0090
0091 #define ISTRANSIENT_IMPL return 0 != (processIndex_ & refcoreimpl::kTransientBit)
0092
0093 #define SETTRANSIENT_IMPL processIndex_ |= refcoreimpl::kTransientBit
0094
0095 #define SETCACHEISPRODUCTPTR_IMPL(_item_) refcoreimpl::setCacheIsItem(cachePtr_, _item_)
0096
0097 #define SETCACHEISPRODUCTGETTER_IMPL(_getter_) refcoreimpl::setCacheIsProductGetter(cachePtr_, _getter_)
0098
0099 #endif