Arcane  4.1.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
TestReferenceCounter.cc
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#include <gtest/gtest.h>
8
9#include "arccore/base/ReferenceCounter.h"
10#include "arccore/base/Ref.h"
12
13#include <iostream>
14
15using namespace Arccore;
16
17namespace
18{
19struct StatInfo
20{
21 bool is_destroyed = false;
22 int nb_add = 0;
23 int nb_remove = 0;
24 // Vérifie que 'is_destroyed' est vrai et qu'on a fait
25 // le bon nombre d'appel à 'nb_add' et 'nb_remove'.
26 bool checkValid(int nb_call)
27 {
28 if (nb_add!=nb_call){
29 std::cout << "Bad nb_add n=" << nb_add << " expected=" << nb_call << "\n";
30 return false;
31 }
32 if (nb_remove!=nb_call){
33 std::cout << "Bad nb_remove n=" << nb_remove << " expected=" << nb_call << "\n";
34 return false;
35 }
36 return is_destroyed;
37 }
38};
39}
40
41struct tag_ref_value {};
42
43
44class Simple1;
45
47
48class Simple1
49{
50 public:
51 typedef ReferenceCounterTag ReferenceCounterTagType;
52 public:
53 Simple1(StatInfo* stat_info) : m_nb_ref(0), m_stat_info(stat_info){}
54 ~Simple1(){ m_stat_info->is_destroyed = true; }
55 public:
56 void addReference()
57 {
58 ++m_nb_ref;
59 ++m_stat_info->nb_add;
60 std::cout << "ADD REFERENCE r=" << m_nb_ref << "\n";
61 }
62 void removeReference()
63 {
64 --m_nb_ref;
65 ++m_stat_info->nb_remove;
66 std::cout << "REMOVE REFERENCE r=" << m_nb_ref << "\n";
67 if (m_nb_ref==0){
68 std::cout << "DESTROY!\n";
69 delete this;
70 }
71 }
72 Int32 m_nb_ref;
73 StatInfo* m_stat_info;
74};
75// Test sans compteur de référence (avec std::shared_ptr).
76class Simple2
77{
78 public:
79 Simple2(StatInfo* stat_info) : m_stat_info(stat_info){}
80 ~Simple2(){ m_stat_info->is_destroyed = true; }
81 private:
82 StatInfo* m_stat_info;
83};
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88template<typename RefType> void
89_doTest1(const RefType& ref_type)
90{
91 {
92 RefType s3;
93 {
94 RefType s1(ref_type);
95 RefType s2 = s1;
96 {
97 s3 = s2;
98 }
99 }
100 }
101}
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
106// Teste si le compteur de référence détruit bien l'instance.
107TEST(ReferenceCounter, Misc)
108{
109 typedef ReferenceCounter<Simple1> Simple1Reference;
110 {
111 StatInfo stat_info;
112 _doTest1(Simple1Reference(new Simple1(&stat_info)));
113 ASSERT_TRUE(stat_info.checkValid(4)) << "Bad destroy1";
114 }
115}
116
117/*---------------------------------------------------------------------------*/
118/*---------------------------------------------------------------------------*/
119// Teste si le compteur de référence détruit bien l'instance.
121{
122 {
123 StatInfo stat_info;
124 _doTest1(makeRef(new Simple1(&stat_info)));
125 ASSERT_TRUE(stat_info.checkValid(4)) << "Bad destroy2";
126 }
127 {
128 StatInfo stat_info;
129 _doTest1(createRef<Simple2>(&stat_info));
130 ASSERT_TRUE(stat_info.checkValid(0)) << "Bad destroy3";
131 }
132}
133
134/*---------------------------------------------------------------------------*/
135/*---------------------------------------------------------------------------*/
136
137namespace Test1
138{
140{
141 public:
142
143 ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS();
144 virtual ~ITestClassWithDeleter() = default;
145
146 public:
147
148 virtual bool func1() = 0;
149 virtual void func2() = 0;
150};
151
155{
156 public:
157
158 ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS();
159
160 public:
161
162 bool func1() override { return true; }
163 void func2() override {}
164
165 public:
166
167 Int32 m_padding4 = 0;
168 Int64 m_padding3 = 0;
169};
170} // namespace Test1
171
172/*---------------------------------------------------------------------------*/
173/*---------------------------------------------------------------------------*/
174
175// Teste si le compteur de référence détruit bien l'instance.
176TEST(ReferenceCounter, RefWithDeleter)
177{
178 try{
179 using namespace Test1;
181 {
183 myx2 = myx1;
184 }
185 myx2.reset();
187 {
188 auto* ptr1 = new TestClassWithDeleter();
190 }
191 {
193 myx2 = myx3;
194 bool is_ok = false;
195 if (myx3)
196 is_ok = true;
197 ASSERT_TRUE(is_ok);
198 ASSERT_FALSE(!myx3);
199 }
200 {
202 bool is_null = true;
203 if (myx4)
204 is_null = false;
205 ASSERT_TRUE(is_null);
206 ASSERT_TRUE(!myx4);
207 }
208 }
209 catch(const std::exception& ex){
210 std::cerr << "Exception ex=" << ex.what() << "\n";
211 throw;
212 }
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
#define ASSERT_FALSE(condition)
Vérifie que condition est faux.
Definition Assertion.h:137
#define ASSERT_TRUE(condition)
Vérifie que condition est vrai.
Definition Assertion.h:125
#define ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(class_name)
Macro pour déclarer qu'une classe utilise un compteur de référence.
Gestion des références à une classe C++.
Gestion des références sur un objet externe.
void reset()
Positionne l'instance au pointeur nul.
Référence à une instance.
static ThatClass createWithHandle(InstanceType *t, Internal::ExternalRef handle)
Créé une référence à partir d'une instance ayant une référence externe.
Implémentation thread-safe d'un compteur de référence.
Encapsulation d'un pointeur avec compteur de référence.
Espace de nom de Arccore.
Ref< TrueType > createRef(Args &&... args)
Créé une instance de type TrueType avec les arguments Args et retourne une référence dessus.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
Structure servant à tagger les interfaces/classes qui utilisent un compteur de référence interne.