Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ReferenceCounterImpl.h
Go to the documentation of this file.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ReferenceCounterImpl.h (C) 2000-2026 */
9/* */
10/* Implementations related to the reference counter manager. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_BASE_REFERENCECOUNTERIMPL_H
13#define ARCCORE_BASE_REFERENCECOUNTERIMPL_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "ArccoreGlobal.h"
18#include "arccore/base/ReferenceCounter.h"
19#include "arccore/base/RefBase.h"
20
21#include <atomic>
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arccore
38{
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
43template <class T> ARCCORE_EXPORT void
45addReference(T* t)
46{
47 if constexpr (requires { t->_internalAddReference(); })
48 t->_internalAddReference();
49 else
50 t->addReference();
51}
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
56template <class T> ARCCORE_EXPORT void
59{
60 if constexpr (requires { t->_internalRemoveReference(); }) {
61 bool need_destroy = t->_internalRemoveReference();
62 if (need_destroy)
63 delete t;
64 }
65 else
66 t->removeReference();
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72} // namespace Arccore
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
77namespace Arcane
78{
79
80/*---------------------------------------------------------------------------*/
81/*---------------------------------------------------------------------------*/
82
94class ARCCORE_BASE_EXPORT ReferenceCounterImpl
95{
96 template <typename InstanceType> friend class impl::ReferenceCounterWrapper;
97
98 public:
99
100 virtual ~ReferenceCounterImpl() = default;
101
102 public:
103
104 ARCCORE_DEPRECATED_REASON("Y2025: use _internalAddReference() instead")
105 void addReference()
106 {
107 ++m_nb_ref;
108 }
109
110 ARCCORE_DEPRECATED_REASON("Y2025: use _internalRemoveReference() instead")
111 void removeReference()
112 {
113 // Decrements and returns the previous value.
114 // If it equals 1, it means there are no more references
115 // on the object and it must be destroyed.
116 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
117 if (v == 1) {
119 delete this;
120 }
121 }
122
123 public:
124
125 void _internalAddReference()
126 {
127 ++m_nb_ref;
128 }
129 bool _internalRemoveReference()
130 {
131 // Decrements and returns the previous value.
132 // If it equals 1, it means there are no more references
133 // on the object and it must potentially be destroyed.
134 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
135 if (v == 1)
136 return _destroyThisReference();
137 return false;
138 }
139
140 private:
141
142 // Methods accessible only from ReferenceCounterWrapper
143 void _setExternalDeleter(RefBase::DeleterBase* v)
144 {
145 delete m_external_deleter;
146 m_external_deleter = v;
147 }
148 RefBase::DeleterBase* _externalDeleter() const
149 {
150 return m_external_deleter;
151 }
152
153 private:
154
155 std::atomic<Int32> m_nb_ref = 0;
156 RefBase::DeleterBase* m_external_deleter = nullptr;
157
158 private:
159
162 {
163 if (!m_external_deleter)
164 return true;
165 bool do_delete = false;
166 if (!m_external_deleter->m_no_destroy) {
167 bool is_destroyed = m_external_deleter->_destroyHandle(this, m_external_deleter->m_handle);
168 if (!is_destroyed) {
169 do_delete = true;
170 }
171 }
172 delete m_external_deleter;
173 m_external_deleter = nullptr;
174 return do_delete;
175 }
176};
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
185#define ARCCORE_INTERNAL_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(OPTIONAL_OVERRIDE) \
186 private: \
187\
188 using BaseCounterType = ::Arcane::ReferenceCounterImpl; \
189\
190 public: \
191\
192 BaseCounterType* _internalReferenceCounter() OPTIONAL_OVERRIDE \
193 { \
194 return this; \
195 } \
196 void _internalAddReference() OPTIONAL_OVERRIDE \
197 { \
198 BaseCounterType::_internalAddReference(); \
199 } \
200 bool _internalRemoveReference() OPTIONAL_OVERRIDE \
201 { \
202 return BaseCounterType::_internalRemoveReference(); \
203 }
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
228#define ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS() \
229 ARCCORE_INTERNAL_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(override)
230
231/*---------------------------------------------------------------------------*/
232/*---------------------------------------------------------------------------*/
233
250#define ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS(class_name) \
251 template class ExternalReferenceCounterAccessor<class_name>
252
253/*---------------------------------------------------------------------------*/
254/*---------------------------------------------------------------------------*/
255
256} // namespace Arcane
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
261#endif
Definitions and globals of Arccore.
Thread-safe implementation of a reference counter.
bool _destroyThisReference()
Returns true if the instance must be destroyed by calling operator delete().
Wrapper around a class managing its own reference counter.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int32_t Int32
Signed integer type of 32 bits.
Namespace of Arccore.