Arcane  4.2.1.0
User documentation
Loading...
Searching...
No Matches
RefDeclarations.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/* RefDeclarations.h (C) 2000-2026 */
9/* */
10/* Declarations related to reference management on an instance. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_BASE_REFDECLARATIONS_H
13#define ARCCORE_BASE_REFDECLARATIONS_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21
22/*!
23 * \file RefDeclarations.h
24 *
25 * This file contains the declarations and macros for managing classes
26 * using reference counters. For implementation, you must use
27 * the file 'ReferenceCounterImpl.h'
28 */
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33// The ExternalReferenceCounterAccessor class must remain in the
34// Arccore namespace for compatibility with existing code and the macro
35// ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS.
36namespace Arccore
37{
38template <class T>
40{
41 public:
42
43 static ARCCORE_EXPORT void addReference(T* t);
44 static ARCCORE_EXPORT void removeReference(T* t);
45};
46} // namespace Arccore
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51namespace Arcane
52{
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
58/*!
59 * \brief Structure used to tag interfaces/classes that use
60 * an internal reference counter.
61 *
62 * This tag is used via a typedef as follows:
63 *
64 * \code
65 * class MyClass
66 * {
67 * public:
68 * using ReferenceCounterTagType = ReferenceCounterTag;
69 * public:
70 * void addReference();
71 * void removeReference();
72 * };
73 * \endcode
74 */
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
81constexpr int REF_TAG_SHARED_PTR = 0;
82constexpr int REF_TAG_REFERENCE_COUNTER = 1;
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
87/*!
88 * \brief Function to determine what type of reference counter
89 * a class uses.
90 *
91 * By default, std::shared_ptr is used.
92 * To use an internal reference counter, this
93 * method must be overridden using the macro ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS().
94 */
95inline constexpr int arcaneImplGetRefTagId(void*)
96{
97 return REF_TAG_SHARED_PTR;
98}
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
103/*!
104 * \brief Characteristics for managing reference counters.
105 *
106 * By default, the std::shared_ptr class is used as the implementation.
107 */
108template <typename InstanceType>
110{
111 static constexpr int TagId = arcaneImplGetRefTagId(static_cast<InstanceType*>(nullptr));
112};
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
117template <typename InstanceType, int TagType>
119
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
122
123/*!
124 * \brief Accessor for reference counter management methods.
125 *
126 * The class T must define two methods addReference() and removeReference()
127 * to manage reference counters. removeReference() must destroy
128 * the instance if the counter reaches zero.
129 */
130template <class T>
132{
133 public:
134
135 static void addReference(T* t)
136 {
137 if constexpr (requires { t->_internalAddReference(); })
138 t->_internalAddReference();
139 else
140 t->addReference();
141 }
142 static void removeReference(T* t)
143 {
144 if constexpr (requires { t->_internalRemoveReference(); }) {
145 bool need_destroy = t->_internalRemoveReference();
146 if (need_destroy)
147 delete t;
148 }
149 else
150 t->removeReference();
151 }
152};
153
154/*---------------------------------------------------------------------------*/
155/*---------------------------------------------------------------------------*/
156
157/*!
158 * \brief Macro to declare the virtual methods managing reference
159 * counters.
160 *
161 * This macro is used in the same way as declarations
162 * of interface methods. It allows defining pure virtual methods
163 * to access reference counter information.
164 *
165 * The class implementing the interface must use the macro
166 * ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS() to define the
167 * virtual methods used.
168 *
169 * \code
170 * class IMyInterface
171 * {
172 * ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS();
173 * public:
174 * virtual ~IMyInterface() = default;
175 * public:
176 * virtual void myMethod1() = 0;
177 * };
178 * \endcode
179 */
180#define ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS() \
181 private: \
182\
183 template <typename T> friend class ::Arccore::ExternalReferenceCounterAccessor; \
184 template <typename T> friend class Arcane::ReferenceCounterAccessor; \
185\
186 public: \
187\
188 using ReferenceCounterTagType = ::Arcane::ReferenceCounterTag; \
189 virtual ::Arcane::ReferenceCounterImpl* _internalReferenceCounter() = 0; \
190 virtual void _internalAddReference() = 0; \
191 [[nodiscard]] virtual bool _internalRemoveReference() = 0
192// NOTE: The 'friend' classes are necessary for access to the destructor.
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
197/*!
198 * \brief Macro to declare that a class uses a
199 * reference counter.
200 *
201 * The macro must be used outside of any namespace. For example:
202 *
203 * \code
204 * namespace MyNamespace
205 * {
206 * class MyClass;
207 * }
208 *
209 * ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(MyNamespace::MyClass);
210 * \endcode
211 *
212 * You will then need to use the macro
213 * ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS() in the source file to
214 * define the necessary methods and types
215 */
216#define ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(class_name) \
217 namespace Arcane \
218 { \
219 template <> \
220 struct RefTraits<class_name> \
221 { \
222 static constexpr int TagId = ::Arcane::REF_TAG_REFERENCE_COUNTER; \
223 }; \
224 constexpr inline int arcaneImplGetRefTagId(class_name*) \
225 { \
226 return ::Arcane::REF_TAG_REFERENCE_COUNTER; \
227 } \
228 template <> \
229 class ReferenceCounterAccessor<class_name> \
230 : public ExternalReferenceCounterAccessor<class_name> \
231 {}; \
232 }
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
237} // End namespace Arcane
238
239/*---------------------------------------------------------------------------*/
240/*---------------------------------------------------------------------------*/
241
242namespace Arccore
243{
244using Arcane::ReferenceCounterTag;
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
250#endif
Declarations of types for the 'base' component of Arccore.
Accessor for reference counter management methods.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
constexpr int arcaneImplGetRefTagId(void *)
Function to determine what type of reference counter a class uses.
Namespace of Arccore.
Characteristics for managing reference counters.
Structure used to tag interfaces/classes that use an internal reference counter.