Arcane  4.1.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ReferenceCounterImpl.h
Aller à la documentation de ce fichier.
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/* Implémentations liées au gestionnaire de compteur de référence. */
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/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arccore
36{
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41template <class T> ARCCORE_EXPORT void
43addReference(T* t)
44{
45 if constexpr (requires { t->_internalAddReference(); })
46 t->_internalAddReference();
47 else
48 t->addReference();
49}
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54template <class T> ARCCORE_EXPORT void
57{
58 if constexpr (requires { t->_internalRemoveReference(); }) {
59 bool need_destroy = t->_internalRemoveReference();
60 if (need_destroy)
61 delete t;
62 }
63 else
64 t->removeReference();
65}
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69
70} // namespace Arccore
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
74
75namespace Arcane
76{
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
91class ARCCORE_BASE_EXPORT ReferenceCounterImpl
92{
93 template <typename InstanceType> friend class impl::ReferenceCounterWrapper;
94
95 public:
96
97 virtual ~ReferenceCounterImpl() = default;
98
99 public:
100
101 ARCCORE_DEPRECATED_REASON("Y2025: use _internalAddReference() instead")
102 void addReference()
103 {
104 ++m_nb_ref;
105 }
106
107 ARCCORE_DEPRECATED_REASON("Y2025: use _internalRemoveReference() instead")
108 void removeReference()
109 {
110 // Décrémente et retourne la valeur d'avant.
111 // Si elle vaut 1, cela signifie qu'on n'a plus de références
112 // sur l'objet et qu'il faut le détruire.
113 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
114 if (v == 1) {
116 delete this;
117 }
118 }
119
120 public:
121
122 void _internalAddReference()
123 {
124 ++m_nb_ref;
125 }
126 bool _internalRemoveReference()
127 {
128 // Décrémente et retourne la valeur d'avant.
129 // Si elle vaut 1, cela signifie qu'on n'a plus de références
130 // sur l'objet et qu'il faut éventuellement le détruire.
131 Int32 v = std::atomic_fetch_add(&m_nb_ref, -1);
132 if (v == 1)
133 return _destroyThisReference();
134 return false;
135 }
136
137 private:
138
139 // Méthodes accessibles uniquement depuis ReferenceCounterWrapper
140 void _setExternalDeleter(RefBase::DeleterBase* v)
141 {
142 delete m_external_deleter;
143 m_external_deleter = v;
144 }
145 RefBase::DeleterBase* _externalDeleter() const
146 {
147 return m_external_deleter;
148 }
149
150 private:
151
152 std::atomic<Int32> m_nb_ref = 0;
153 RefBase::DeleterBase* m_external_deleter = nullptr;
154
155 private:
156
159 {
160 if (!m_external_deleter)
161 return true;
162 bool do_delete = false;
163 if (!m_external_deleter->m_no_destroy) {
164 bool is_destroyed = m_external_deleter->_destroyHandle(this, m_external_deleter->m_handle);
165 if (!is_destroyed) {
166 do_delete = true;
167 }
168 }
169 delete m_external_deleter;
170 m_external_deleter = nullptr;
171 return do_delete;
172 }
173};
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
181#define ARCCORE_INTERNAL_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(OPTIONAL_OVERRIDE) \
182 private: \
183\
184 using BaseCounterType = ::Arcane::ReferenceCounterImpl; \
185\
186 public: \
187\
188 BaseCounterType* _internalReferenceCounter() OPTIONAL_OVERRIDE \
189 { \
190 return this; \
191 } \
192 void _internalAddReference() OPTIONAL_OVERRIDE \
193 { \
194 BaseCounterType::_internalAddReference(); \
195 } \
196 bool _internalRemoveReference() OPTIONAL_OVERRIDE \
197 { \
198 return BaseCounterType::_internalRemoveReference(); \
199 }
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
223#define ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS() \
224 ARCCORE_INTERNAL_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS(override)
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
245#define ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS(class_name) \
246 template class ExternalReferenceCounterAccessor<class_name>
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251} // End namespace Arccore
252
253/*---------------------------------------------------------------------------*/
254/*---------------------------------------------------------------------------*/
255
256#endif
Définitions et globaux de Arccore.
Implémentation thread-safe d'un compteur de référence.
bool _destroyThisReference()
Retourne true si l'instance doit être détruite par l'appel à operator delete()
Wrapper autour d'une classe gérant son propre compteur de référence.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int32_t Int32
Type entier signé sur 32 bits.
Espace de nom de Arccore.