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