Arcane  v3.14.10.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-2024 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
44{
45 public:
47 public:
48 Simple1(StatInfo* stat_info) : m_nb_ref(0), m_stat_info(stat_info){}
49 ~Simple1(){ m_stat_info->is_destroyed = true; }
50 public:
51 void addReference()
52 {
53 ++m_nb_ref;
54 ++m_stat_info->nb_add;
55 std::cout << "ADD REFERENCE r=" << m_nb_ref << "\n";
56 }
57 void removeReference()
58 {
59 --m_nb_ref;
60 ++m_stat_info->nb_remove;
61 std::cout << "REMOVE REFERENCE r=" << m_nb_ref << "\n";
62 if (m_nb_ref==0){
63 std::cout << "DESTROY!\n";
64 delete this;
65 }
66 }
67 Int32 m_nb_ref;
68 StatInfo* m_stat_info;
69};
70// Test sans compteur de référence (avec std::shared_ptr).
72{
73 public:
74 Simple2(StatInfo* stat_info) : m_stat_info(stat_info){}
75 ~Simple2(){ m_stat_info->is_destroyed = true; }
76 private:
77 StatInfo* m_stat_info;
78};
79
80/*---------------------------------------------------------------------------*/
81/*---------------------------------------------------------------------------*/
82
83template<typename RefType> void
84_doTest1(const RefType& ref_type)
85{
86 {
87 RefType s3;
88 {
89 RefType s1(ref_type);
90 RefType s2 = s1;
91 {
92 s3 = s2;
93 }
94 }
95 }
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101// Teste si le compteur de référence détruit bien l'instance.
102TEST(ReferenceCounter, Misc)
103{
104 typedef ReferenceCounter<Simple1> Simple1Reference;
105 {
106 StatInfo stat_info;
107 _doTest1(Simple1Reference(new Simple1(&stat_info)));
108 ASSERT_TRUE(stat_info.checkValid(4)) << "Bad destroy1";
109 }
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114// Teste si le compteur de référence détruit bien l'instance.
116{
117 {
118 StatInfo stat_info;
119 _doTest1(makeRef(new Simple1(&stat_info)));
120 ASSERT_TRUE(stat_info.checkValid(4)) << "Bad destroy2";
121 }
122 {
123 StatInfo stat_info;
124 _doTest1(createRef<Simple2>(&stat_info));
125 ASSERT_TRUE(stat_info.checkValid(0)) << "Bad destroy3";
126 }
127}
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
132namespace Test1
133{
135{
136 public:
137
138 ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS();
139 virtual ~ITestClassWithDeleter() = default;
140
141 public:
142
143 virtual bool func1() = 0;
144 virtual void func2() = 0;
145};
146
150{
151 public:
152
153 ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS();
154
155 public:
156
157 bool func1() override { return true; }
158 void func2() override {}
159
160 public:
161
162 Int32 m_padding4 = 0;
163 Int64 m_padding3 = 0;
164};
165} // namespace Test1
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
170// Teste si le compteur de référence détruit bien l'instance.
171TEST(ReferenceCounter, RefWithDeleter)
172{
173 try{
174 using namespace Test1;
176 {
177 Ref<ITestClassWithDeleter> myx1 = makeRef<TestClassWithDeleter>(new TestClassWithDeleter());
178 myx2 = myx1;
179 }
180 myx2.reset();
181 Internal::ExternalRef external_ref;
182 {
183 auto* ptr1 = new TestClassWithDeleter();
185 }
186 {
187 Ref<ITestClassWithDeleter> myx3 = createRef<TestClassWithDeleter>();
188 myx2 = myx3;
189 bool is_ok = false;
190 if (myx3)
191 is_ok = true;
192 ASSERT_TRUE(is_ok);
193 ASSERT_FALSE(!myx3);
194 }
195 {
197 bool is_null = true;
198 if (myx4)
199 is_null = false;
200 ASSERT_TRUE(is_null);
201 ASSERT_TRUE(!myx4);
202 }
203 }
204 catch(const std::exception& ex){
205 std::cerr << "Exception ex=" << ex.what() << "\n";
206 throw;
207 }
208}
209
210/*---------------------------------------------------------------------------*/
211/*---------------------------------------------------------------------------*/
#define ASSERT_FALSE(condition)
Vérifie que condition est faux.
Definition Assertion.h:138
#define ASSERT_TRUE(condition)
Vérifie que condition est vrai.
Definition Assertion.h:126
Gestion des références à une classe C++.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Gestion des références sur un objet externe.
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.
void reset()
Positionne l'instance au pointeur nul.
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.
Definition ArcaneTypes.h:24
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.
Structure servant à tagger les interfaces/classes qui utilisent un compteur de référence interne.