Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
RefDeclarations.h
Aller à la documentation de ce fichier.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* RefDeclarations.h (C) 2000-2025 */
9/* */
10/* Déclarations liées à la gestion des références sur une instance. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_BASE_REFDECLARATIONS_H
13#define ARCCORE_BASE_REFDECLARATIONS_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
18
19#include <type_traits>
20#include <memory>
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25/*!
26 * \file RefDeclarations.h
27 *
28 * Ce fichier contient les déclarations et macros pour gérer classes
29 * utilisant les compteurs de référence. Pour l'implémentation il faut utiliser
30 * le fichier 'ReferenceCounterImpl.h'
31 */
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36// La classe ExternalReferenceCounterAccessor doit rester dans le namespace
37// Arccore pour compatiblité avec l'existant et la macro
38// ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS.
39namespace Arccore
40{
41template <class T>
43{
44 public:
45
46 static ARCCORE_EXPORT void addReference(T* t);
47 static ARCCORE_EXPORT void removeReference(T* t);
48};
49} // namespace Arccore
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54namespace Arcane
55{
57
58/*---------------------------------------------------------------------------*/
59/*---------------------------------------------------------------------------*/
60/*!
61 * \brief Structure servant à tagger les interfaces/classes qui utilisent
62 * un compteur de référence interne.
63 *
64 * Ce tag s'utilise via un typedef comme suit:
65 *
66 * \code
67 * class MyClass
68 * {
69 * public:
70 * using ReferenceCounterTagType = ReferenceCounterTag;
71 * public:
72 * void addReference();
73 * void removeReference();
74 * };
75 * \endcode
76 */
78
79/*---------------------------------------------------------------------------*/
80/*---------------------------------------------------------------------------*/
81
82constexpr int REF_TAG_SHARED_PTR = 0;
83constexpr int REF_TAG_REFERENCE_COUNTER = 1;
84
85/*!
86 * \brief Caractéristiques pour gérer les compteurs de référence.
87 *
88 * Par défaut, on utilise comme implémentation la classe std::shared_ptr.
89 */
90template<typename InstanceType,class T>
92{
93 static constexpr int TagId = REF_TAG_SHARED_PTR;
94};
95
96/*!
97 * \brief Spécialisation de la classe gérant un compteur de référence
98 * si la classe utilise le tag 'ReferenceCounterTag'.
99 *
100 * Dans ce cas, on utilise 'ReferenceCounter' comme implémentation.
101 */
102template<typename InstanceType>
103struct RefTraits<InstanceType,std::enable_if_t<std::is_same_v<typename InstanceType::ReferenceCounterTagType,ReferenceCounterTag>>>
104{
105 static constexpr int TagId = REF_TAG_REFERENCE_COUNTER;
106};
107
108//template<typename InstanceType,
109// int ImplTagId = RefTraits<InstanceType>::TagId>
110//class Ref;
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
115template<typename InstanceType,int TagType>
117
118/*---------------------------------------------------------------------------*/
119/*---------------------------------------------------------------------------*/
120
121namespace impl
122{
123//! Classe template pour vérifier si T a la méthode _internalRemoveReference()
124template <typename T, typename = int>
126: std::false_type
127{
128};
129template <typename T>
130struct HasInternalRemoveReference<T, decltype(&T::_internalRemoveReference, 0)>
131: std::true_type
132{
133};
134
135//! Classe template pour vérifier si T a la méthode _internalAddReference()
136template <typename T, typename = int>
138: std::false_type
139{
140};
141template <typename T>
142struct HasInternalAddReference<T, decltype(&T::_internalAddReference, 0)>
143: std::true_type
144{
145};
146
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151/*!
152 * \brief Accesseur des méthodes de gestion de compteurs de référence.
153 *
154 * Le classe T doit définir deux méthodes addReference() et removeReference()
155 * pour gérer les compteurs de références. removeReference() doit détruire
156 * l'instance si le compteur arrive à zéro.
157 */
158template<class T>
160{
161 public:
162 static void addReference(T* t)
163 {
165 t->_internalAddReference();
166 else
167 t->addReference();
168 }
169 static void removeReference(T* t)
170 {
172 bool need_destroy = t->_internalRemoveReference();
173 if (need_destroy)
174 delete t;
175 }
176 else
177 t->removeReference();
178 }
179};
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183/*!
184 * \brief Macro pour déclarer les méthodes virtuelles gérant les compteurs
185 * de référence.
186 *
187 * Cette macro s'utilise de la même manière que les déclarations
188 * de méthodes d'une interface. Elle permet de définir des méthodes virtuelles
189 * pure pour accèder aux informations des compteurs de référence.
190 *
191 * La classe implémentant l'interface doit utiliser la macro
192 * ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS() pour définir les
193 * méthodes virtuelles utilisées.
194 *
195 * \code
196 * class IMyInterface
197 * {
198 * ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS();
199 * public:
200 * virtual ~IMyInterface() = default;
201 * public:
202 * virtual void myMethod1() = 0;
203 * };
204 * \endcode
205 */
206#define ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS() \
207 private: \
208\
209 template <typename T> friend class ::Arccore::ExternalReferenceCounterAccessor; \
210 template <typename T> friend class Arcane::ReferenceCounterAccessor; \
211\
212 public: \
213\
214 using ReferenceCounterTagType = ::Arcane::ReferenceCounterTag; \
215 virtual ::Arcane::ReferenceCounterImpl* _internalReferenceCounter() = 0; \
216 virtual void _internalAddReference() =0;\
217 [[nodiscard]] virtual bool _internalRemoveReference() =0
218 // NOTE: les classes 'friend' sont nécessaires pour l'accès au destructeur.
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222/*!
223 * \brief Macro pour déclarer qu'une classe utilise un compteur de
224 * référence.
225 *
226 * La macro doit être utilisée en dehors de tout namespace. Par exemple:
227 *
228 * \code
229 * namespace MyNamespace
230 * {
231 * class MyClass;
232 * }
233 *
234 * ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(MyNamespace::MyClass);
235 * \endcode
236 *
237 * Il faudra ensuite utiliser la macro
238 * ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS() dans le fichier source pour
239 * définir les méthodes et types nécessaires
240 */
241#define ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(class_name) \
242 namespace Arcane \
243 { \
244 template <> \
245 struct RefTraits<class_name> \
246 { \
247 static constexpr int TagId = ::Arcane::REF_TAG_REFERENCE_COUNTER; \
248 }; \
249 template<>\
250class ReferenceCounterAccessor<class_name>\
251: public ExternalReferenceCounterAccessor<class_name>\
252{}; \
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
258} // End namespace Arcane
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
262
263namespace Arccore
264{
265using Arcane::ReferenceCounterTag;
266}
267
268/*---------------------------------------------------------------------------*/
269/*---------------------------------------------------------------------------*/
270
271#endif
272
Déclarations des types de la composante 'base' de Arccore.
Accesseur des méthodes de gestion de compteurs de référence.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Espace de nom de Arccore.
Caractéristiques pour gérer les compteurs de référence.
Structure servant à tagger les interfaces/classes qui utilisent un compteur de référence interne.
Classe template pour vérifier si T a la méthode _internalAddReference()
Classe template pour vérifier si T a la méthode _internalRemoveReference()