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