33class [[deprecated(
"Reliance on IObject::Destroy results in mismatched deallocation.")]]
34object_reference_counter final :
public iobject_ptr_ref<size_t>
38 typedef iobject_ptr_ref<size_t>::size_type size_type;
42 explicit object_reference_counter(U* pObjImpl):
43 m_szUseCount(), m_szWeakCount(1), m_pObjImpl(
ucom_cast<const
IObject*>(pObjImpl))
47 virtual ~object_reference_counter()
51 virtual void IncreaseUseCount()
56 virtual void DecreaseUseCount()
59 if (0 == --m_szUseCount)
66 virtual void IncreaseWeakCount()
71 virtual void DecreaseWeakCount()
74 if (0 == --m_szWeakCount)
80 virtual bool IncreaseUseCountNonZero()
82 size_type szExpected = m_szUseCount;
87 while (0 != szExpected && !m_szUseCount.compare_exchange_weak(szExpected, szExpected + 1))
90 return 0 != szExpected;
100 #pragma warning(push)
101 #pragma warning(disable : 4996)
102#elif defined(__GNUC__)
103 #pragma GCC diagnostic push
104 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
106 m_pObjImpl->Destroy();
109#elif defined(__GNUC__)
110 #pragma GCC diagnostic pop
112 m_pObjImpl =
nullptr;
117 ::std::atomic<size_type> m_szUseCount;
118 ::std::atomic<size_type> m_szWeakCount;
129 #pragma warning(push)
131 #pragma warning(disable : 4324)
134template<
typename T,
bool Fused>
138struct fused_storage<T, true>
140 union aligned_storage
143 constexpr aligned_storage() noexcept
147 ~aligned_storage() noexcept
155struct fused_storage<T, false>
160template<
typename T,
typename Allocator,
bool Fused = true>
161class fused_object_reference_counter final :
public ant::detail::iobject_ptr_ref<size_t>
164 using allocator_type =
165 typename ::std::allocator_traits<Allocator>::template rebind_alloc<fused_object_reference_counter>;
166 using object_allocator_type = ::std::
167 conditional_t<Fused, allocator_type, typename ::std::allocator_traits<Allocator>::template rebind_alloc<T>>;
169 template<
typename ExternalAllocator,
typename... Args>
170 static fused_object_reference_counter* Create(ExternalAllocator&& oExternalAllocator, Args&&... args)
172 allocator_type oAllocator(::std::forward<ExternalAllocator>(oExternalAllocator));
173 static_assert(::std::is_same_v<typename ::std::allocator_traits<allocator_type>::value_type,
174 fused_object_reference_counter>);
175 fused_object_reference_counter* pCounter = ::std::allocator_traits<allocator_type>::allocate(oAllocator, 1);
178 ::std::allocator_traits<allocator_type>::construct(oAllocator, pCounter, oAllocator,
179 ::std::forward<Args>(args)...);
183 ::std::allocator_traits<allocator_type>::deallocate(oAllocator, pCounter, 1);
186 return std::launder(pCounter);
189 fused_object_reference_counter() =
delete;
191 template<
typename... Args>
192 fused_object_reference_counter(
const allocator_type& allocator, Args&&... args):
193 m_oAllocator(allocator), m_szUseCount(0), m_szWeakCount(1), m_pObject(nullptr)
195 object_allocator_type oObjectAllocator(m_oAllocator);
199 pObject = &m_sObjectStorage.oBuffer.oInstance;
203 pObject = ::std::allocator_traits<object_allocator_type>::allocate(oObjectAllocator, 1);
207 ::std::allocator_traits<object_allocator_type>::construct(oObjectAllocator, pObject,
208 ::std::forward<Args>(args)...);
212 if constexpr (!Fused)
214 ::std::allocator_traits<object_allocator_type>::deallocate(oObjectAllocator, pObject, 1);
218 m_pObject = std::launder(pObject);
221 ~fused_object_reference_counter() =
default;
229 void IncreaseUseCount() noexcept final
override
231 m_szUseCount.fetch_add(1, ::std::memory_order_relaxed);
234 void DecreaseUseCount() final
override
236 if (1 == m_szUseCount.fetch_sub(1, ::std::memory_order_release))
238 ::std::atomic_thread_fence(::std::memory_order_acquire);
239 ::std::optional<::std::exception_ptr> eptr;
240 object_allocator_type oObjectAllocator(m_oAllocator);
243 ::std::allocator_traits<object_allocator_type>::destroy(oObjectAllocator, m_pObject);
247 eptr = ::std::current_exception();
249 if constexpr (!Fused)
251 ::std::allocator_traits<object_allocator_type>::deallocate(oObjectAllocator, m_pObject, 1);
257 ::std::rethrow_exception(std::move(*eptr));
262 void IncreaseWeakCount() noexcept final
override
264 m_szWeakCount.fetch_add(1, ::std::memory_order_relaxed);
267 void DecreaseWeakCount() final
override
269 if (1 == m_szWeakCount.fetch_sub(1, ::std::memory_order_release))
271 ::std::atomic_thread_fence(::std::memory_order_acquire);
272 ::std::optional<::std::exception_ptr> eptr;
273 static_assert(::std::is_same_v<typename ::std::allocator_traits<allocator_type>::value_type,
274 fused_object_reference_counter>);
275 allocator_type oAllocator(std::move(m_oAllocator));
276 auto pSelf = std::launder(
this);
279 ::std::allocator_traits<allocator_type>::destroy(oAllocator, pSelf);
283 eptr = std::current_exception();
285 ::std::allocator_traits<allocator_type>::deallocate(oAllocator, pSelf, 1);
288 ::std::rethrow_exception(std::move(*eptr));
293 bool IncreaseUseCountNonZero() noexcept final
override
295 size_type szExpected = m_szUseCount.load(std::memory_order_relaxed);
296 while (0 != szExpected &&
297 !m_szUseCount.compare_exchange_weak(szExpected, szExpected + 1, std::memory_order_acquire))
300 return 0 != szExpected;
303 allocator_type m_oAllocator;
304 ::std::atomic<size_t> m_szUseCount;
305 ::std::atomic<size_t> m_szWeakCount;
308 static constexpr std::size_t hardware_destructive_interference_size = 64;
310 alignas((::std::max) (hardware_destructive_interference_size,
311 alignof(fused_storage<T, Fused>))) fused_storage<T, Fused> m_sObjectStorage;
Namespace for all internally used functionality implemented.
Definition class_info.h:17
Namespace for all functionality of the ADTF UCOM SDK provided since v3.0.
Definition test_runtime.h:14
InterfacePointerType ucom_cast(ObjectPointerType i_pObject) noexcept
Definition ucom_cast.h:157
Namespace for all functionality of the ADTF UCOM SDK provided since v3.21.
Definition plugin_logging_intf.h:48
Namespace for the ADTF uCOM SDK.
Definition adtf_system.h:324
ant::IObject IObject
Alias always bringing the latest version of ant::IObject into scope.
Definition object_intf.h:109
Namespace for all functionality provided by ADTF and its SDKs.
Definition adtf_client_connector.h:14