Arcane  v3.15.3.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
36namespace Arccore
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41/*!
42 * \brief Structure servant à tagger les interfaces/classes qui utilisent
43 * un compteur de référence interne.
44 *
45 * Ce tag s'utilise via un typedef comme suit:
46 *
47 * \code
48 * class MyClass
49 * {
50 * public:
51 * using ReferenceCounterTagType = ReferenceCounterTag;
52 * public:
53 * void addReference();
54 * void removeReference();
55 * };
56 * \endcode
57 */
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63constexpr int REF_TAG_SHARED_PTR = 0;
64constexpr int REF_TAG_REFERENCE_COUNTER = 1;
65
66/*!
67 * \brief Caractéristiques pour gérer les compteurs de référence.
68 *
69 * Par défaut, on utilise comme implémentation la classe std::shared_ptr.
70 */
71template<typename InstanceType,class T>
73{
74 static constexpr int TagId = REF_TAG_SHARED_PTR;
75};
76
77/*!
78 * \brief Spécialisation de la classe gérant un compteur de référence
79 * si la classe utilise le tag 'ReferenceCounterTag'.
80 *
81 * Dans ce cas, on utilise 'ReferenceCounter' comme implémentation.
82 */
83template<typename InstanceType>
84struct RefTraits<InstanceType,std::enable_if_t<std::is_same_v<typename InstanceType::ReferenceCounterTagType,ReferenceCounterTag>>>
85{
86 static constexpr int TagId = REF_TAG_REFERENCE_COUNTER;
87};
88
89//template<typename InstanceType,
90// int ImplTagId = RefTraits<InstanceType>::TagId>
91//class Ref;
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96template<typename InstanceType,int TagType>
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
102namespace impl
103{
104//! Classe template pour vérifier si T a la méthode _internalRemoveReference()
105template <typename T, typename = int>
107: std::false_type
108{
109};
110template <typename T>
111struct HasInternalRemoveReference<T, decltype(&T::_internalRemoveReference, 0)>
112: std::true_type
113{
114};
115
116//! Classe template pour vérifier si T a la méthode _internalAddReference()
117template <typename T, typename = int>
119: std::false_type
120{
121};
122template <typename T>
123struct HasInternalAddReference<T, decltype(&T::_internalAddReference, 0)>
124: std::true_type
125{
126};
127
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132/*!
133 * \brief Accesseur des méthodes de gestion de compteurs de référence.
134 *
135 * Le classe T doit définir deux méthodes addReference() et removeReference()
136 * pour gérer les compteurs de références. removeReference() doit détruire
137 * l'instance si le compteur arrive à zéro.
138 */
139template<class T>
141{
142 public:
143 static void addReference(T* t)
144 {
146 t->_internalAddReference();
147 else
148 t->addReference();
149 }
150 static void removeReference(T* t)
151 {
153 bool need_destroy = t->_internalRemoveReference();
154 if (need_destroy)
155 delete t;
156 }
157 else
158 t->removeReference();
159 }
160};
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
165template<class T>
167{
168 public:
169 static ARCCORE_EXPORT void addReference(T* t);
170 static ARCCORE_EXPORT void removeReference(T* t);
171};
172
173/*---------------------------------------------------------------------------*/
174/*---------------------------------------------------------------------------*/
175/*!
176 * \brief Macro pour déclarer les méthodes virtuelles gérant les compteurs
177 * de référence.
178 *
179 * Cette macro s'utilise de la même manière que les déclarations
180 * de méthodes d'une interface. Elle permet de définir des méthodes virtuelles
181 * pure pour accèder aux informations des compteurs de référence.
182 *
183 * La classe implémentant l'interface doit utiliser la macro
184 * ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS() pour définir les
185 * méthodes virtuelles utilisées.
186 *
187 * \code
188 * class IMyInterface
189 * {
190 * ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS();
191 * public:
192 * virtual ~IMyInterface() = default;
193 * public:
194 * virtual void myMethod1() = 0;
195 * };
196 * \endcode
197 */
198#define ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS() \
199 private:\
200 template<typename T> friend class Arccore::ExternalReferenceCounterAccessor; \
201 template<typename T> friend class Arccore::ReferenceCounterAccessor;\
202 public: \
203 using ReferenceCounterTagType = Arccore::ReferenceCounterTag ; \
204 virtual ::Arccore::ReferenceCounterImpl* _internalReferenceCounter() =0; \
205 virtual void _internalAddReference() =0;\
206 [[nodiscard]] virtual bool _internalRemoveReference() =0
207 // NOTE: les classes 'friend' sont nécessaires pour l'accès au destructeur.
208
209/*---------------------------------------------------------------------------*/
210/*---------------------------------------------------------------------------*/
211/*!
212 * \brief Macro pour déclarer qu'une classe utilise un compteur de
213 * référence.
214 *
215 * La macro doit être utilisée en dehors de tout namespace. Par exemple:
216 *
217 * \code
218 * namespace MyNamespace
219 * {
220 * class MyClass;
221 * }
222 *
223 * ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(MyNamespace::MyClass);
224 * \endcode
225 *
226 * Il faudra ensuite utiliser la macro
227 * ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS() dans le fichier source pour
228 * définir les méthodes et types nécessaires
229 */
230#define ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(class_name) \
231namespace Arccore {\
232template<> \
233struct RefTraits<class_name> \
234{\
235 static constexpr int TagId = Arccore::REF_TAG_REFERENCE_COUNTER;\
236};\
237template<>\
238class ReferenceCounterAccessor<class_name>\
239: public ExternalReferenceCounterAccessor<class_name>\
240{}; \
241}
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
246} // End namespace Arccore
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251#endif
252
Déclarations des types de la composante 'base' de Arccore.
Référence à une instance.
Accesseur des méthodes de gestion de compteurs de référence.
Espace de nom de Arccore.
Definition ArcaneTypes.h:29
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()