Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
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 // Checks that 'is_destroyed' is true and that the correct number of
25 // calls to 'nb_add' and 'nb_remove' were made.
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} // namespace
40
42{};
43
44class Simple1;
45
47
48class Simple1
49{
50 public:
51
52 typedef ReferenceCounterTag ReferenceCounterTagType;
53
54 public:
55
56 Simple1(StatInfo* stat_info)
57 : m_nb_ref(0)
58 , m_stat_info(stat_info)
59 {}
60 ~Simple1() { m_stat_info->is_destroyed = true; }
61
62 public:
63
64 void addReference()
65 {
66 ++m_nb_ref;
67 ++m_stat_info->nb_add;
68 std::cout << "ADD REFERENCE r=" << m_nb_ref << "\n";
69 }
70 void removeReference()
71 {
72 --m_nb_ref;
73 ++m_stat_info->nb_remove;
74 std::cout << "REMOVE REFERENCE r=" << m_nb_ref << "\n";
75 if (m_nb_ref == 0) {
76 std::cout << "DESTROY!\n";
77 delete this;
78 }
79 }
80 Int32 m_nb_ref;
81 StatInfo* m_stat_info;
82};
83// Test without reference counter (using std::shared_ptr).
84class Simple2
85{
86 public:
87
88 Simple2(StatInfo* stat_info)
89 : m_stat_info(stat_info)
90 {}
91 ~Simple2() { m_stat_info->is_destroyed = true; }
92
93 private:
94
95 StatInfo* m_stat_info;
96};
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101template <typename RefType> void
102_doTest1(const RefType& ref_type)
103{
104 {
105 RefType s3;
106 {
107 RefType s1(ref_type);
108 RefType s2 = s1;
109 {
110 s3 = s2;
111 }
112 }
113 }
114}
115
116/*---------------------------------------------------------------------------*/
117/*---------------------------------------------------------------------------*/
118
119// Tests if the reference counter correctly destroys the instance.
120TEST(ReferenceCounter, Misc)
121{
122 typedef ReferenceCounter<Simple1> Simple1Reference;
123 {
124 StatInfo stat_info;
125 _doTest1(Simple1Reference(new Simple1(&stat_info)));
126 ASSERT_TRUE(stat_info.checkValid(4)) << "Bad destroy1";
127 }
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
133// Tests if the reference counter correctly destroys the instance.
135{
136 {
137 StatInfo stat_info;
138 _doTest1(makeRef(new Simple1(&stat_info)));
139 ASSERT_TRUE(stat_info.checkValid(4)) << "Bad destroy2";
140 }
141 {
142 StatInfo stat_info;
143 _doTest1(createRef<Simple2>(&stat_info));
144 ASSERT_TRUE(stat_info.checkValid(0)) << "Bad destroy3";
145 }
146}
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150
151namespace Test1
152{
154{
155 public:
156
158 virtual ~ITestClassWithDeleter() = default;
159
160 public:
161
162 virtual bool func1() = 0;
163 virtual void func2() = 0;
164};
165
169{
170 public:
171
173
174 public:
175
176 bool func1() override { return true; }
177 void func2() override {}
178
179 public:
180
181 Int32 m_padding4 = 0;
182 Int64 m_padding3 = 0;
183};
184} // namespace Test1
185
186/*---------------------------------------------------------------------------*/
187/*---------------------------------------------------------------------------*/
188
189// Tests if the reference counter correctly destroys the instance.
190TEST(ReferenceCounter, RefWithDeleter)
191{
192 try {
193 using namespace Test1;
195 {
197 myx2 = myx1;
198 }
199 myx2.reset();
201 {
202 auto* ptr1 = new TestClassWithDeleter();
204 }
205 {
207 myx2 = myx3;
208 bool is_ok = false;
209 if (myx3)
210 is_ok = true;
211 ASSERT_TRUE(is_ok);
212 ASSERT_FALSE(!myx3);
213 }
214 {
216 bool is_null = true;
217 if (myx4)
218 is_null = false;
219 ASSERT_TRUE(is_null);
220 ASSERT_TRUE(!myx4);
221 }
222 }
223 catch (const std::exception& ex) {
224 std::cerr << "Exception ex=" << ex.what() << "\n";
225 throw;
226 }
227}
228
229/*---------------------------------------------------------------------------*/
230/*---------------------------------------------------------------------------*/
#define ASSERT_FALSE(condition)
Checks that condition is false.
Definition Assertion.h:140
#define ASSERT_TRUE(condition)
Checks that condition is true.
Definition Assertion.h:128
#define ARCCORE_DECLARE_REFERENCE_COUNTED_INCLASS_METHODS()
Macro to declare the virtual methods managing reference counters.
#define ARCCORE_DECLARE_REFERENCE_COUNTED_CLASS(class_name)
Macro to declare that a class uses a reference counter.
#define ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS()
Macro to define methods managing counters of references.
Management of references to a C++ class.
Management of references to an external object.
void reset()
Positions the instance to the null pointer.
Reference to an instance.
static ThatClass createWithHandle(InstanceType *t, Internal::ExternalRef handle)
Creates a reference from an instance having an external reference.
Thread-safe implementation of a reference counter.
Encapsulation of a pointer with a reference counter.
Namespace of Arccore.
Ref< TrueType > createRef(Args &&... args)
Creates an instance of type TrueType with arguments Args and returns a reference to it.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
Structure used to tag interfaces/classes that use an internal reference counter.