2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-test-suite-utils.h>
19 #include <dali/public-api/dali-core.h>
28 const int REPEAT = 1000;
30 size_t g_creationCount = 0;
31 size_t g_destructionCount = 0;
32 size_t g_creationCountSubclass = 0;
33 size_t g_destructionCountSubclass = 0;
34 size_t g_creationCountUnrelated = 0;
35 size_t g_destructionCountUnrelated = 0;
37 class Counted : public RefObject
50 class CountedSubclass : public Counted
55 ++g_creationCountSubclass;
59 ++g_destructionCountSubclass;
63 class UnrelatedCounted : public RefObject
68 ++g_creationCountUnrelated;
72 ++g_destructionCountUnrelated;
76 class TestObject : public RefObject
84 TestObject(const TestObject& testObject)
85 : RefObject(testObject),
90 TestObject& Assign(const TestObject& testObject)
92 RefObject::operator=(testObject);
93 data = testObject.data;
100 } // Anonymous namespace
103 * Test that a default constructed pointer is null and harmless.
105 int UtcDaliIntrusivePtrIntrusivePtr(void)
107 tet_infoline("Testing Dali::IntrusivePtr::IntrusivePtr()");
109 g_creationCount = g_destructionCount = 0;
111 IntrusivePtr<Counted> counted;
112 DALI_TEST_EQUALS(g_creationCount, 0u, TEST_LOCATION);
113 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
114 // Test the pointer is null
115 DALI_TEST_EQUALS(counted.Get(), (Counted*)0, TEST_LOCATION);
116 DALI_TEST_EQUALS(&(*counted), (Counted*)0, TEST_LOCATION);
117 // Check destruction of the null smart pointer does nothing:
118 counted = IntrusivePtr<Counted>();
119 DALI_TEST_EQUALS(g_creationCount, 0u, TEST_LOCATION);
120 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
125 int UtcDaliIntrusivePtrIntrusivePtrTP(void)
127 tet_infoline("Testing Dali::IntrusivePtr::IntrusivePtr(T*)");
129 g_creationCount = g_destructionCount = 0;
131 IntrusivePtr<Counted> counted(new Counted);
132 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
133 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
135 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
136 DALI_TEST_EQUALS(g_destructionCount, 1u, TEST_LOCATION);
141 // Class is too simple for a negative case to be created: int UtcDaliIntrusiveIntrusivePtrTN(void)
143 int UtcDaliIntrusivePtrIntrusivePtrIntrusivePtrUP(void)
145 tet_infoline("Testing Dali::IntrusivePtr::IntrusivePtr(IntrusivePtr<U> const &)");
147 g_creationCount = g_destructionCount = g_creationCountSubclass = g_destructionCountSubclass = 0;
149 IntrusivePtr<CountedSubclass> countedSubclass(new CountedSubclass);
150 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
151 DALI_TEST_EQUALS(g_creationCountSubclass, 1u, TEST_LOCATION);
152 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
153 DALI_TEST_EQUALS(g_destructionCountSubclass, 0u, TEST_LOCATION);
155 IntrusivePtr<Counted> counted(countedSubclass);
156 DALI_TEST_EQUALS(counted->ReferenceCount(), 2, TEST_LOCATION);
158 // Make loads more references:
159 std::vector<IntrusivePtr<Counted> > intrusivePtrs;
160 for(int i = 0; i < REPEAT; ++i)
162 intrusivePtrs.push_back(IntrusivePtr<Counted>(countedSubclass));
164 DALI_TEST_EQUALS(counted->ReferenceCount(), 2 + REPEAT, TEST_LOCATION);
166 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
167 DALI_TEST_EQUALS(g_creationCountSubclass, 1u, TEST_LOCATION);
168 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
173 // The negative version of this test would fail at compile time:
174 // int UtcDaliIntrusivePtrIntrusivePtrIntrusivePtrUN(void)
176 int UtcDaliIntrusivePtrIntrusivePtrIntrusivePtrP(void)
178 tet_infoline("Testing Dali::IntrusivePtr::IntrusivePtr(IntrusivePtr const &)");
180 // Pass a pointer to a constructed second object:
181 // Pass a pointer to null:
183 g_creationCount = g_destructionCount = 0;
185 IntrusivePtr<Counted> counted(new Counted);
186 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
187 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
188 DALI_TEST_EQUALS(counted->ReferenceCount(), 1, TEST_LOCATION);
190 IntrusivePtr<Counted> counted2(counted);
191 DALI_TEST_EQUALS(counted->ReferenceCount(), 2, TEST_LOCATION);
192 DALI_TEST_EQUALS(counted.Get(), counted2.Get(), TEST_LOCATION);
194 // Make loads more references:
195 std::vector<IntrusivePtr<Counted> > intrusivePtrs;
196 for(int i = 0; i < REPEAT; ++i)
198 intrusivePtrs.push_back(IntrusivePtr<Counted>(counted));
200 DALI_TEST_EQUALS(counted->ReferenceCount(), 2 + REPEAT, TEST_LOCATION);
202 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
203 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
205 intrusivePtrs.clear();
207 DALI_TEST_EQUALS(counted->ReferenceCount(), 2, TEST_LOCATION);
209 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
210 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
213 DALI_TEST_EQUALS(counted2->ReferenceCount(), 1, TEST_LOCATION);
216 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
217 DALI_TEST_EQUALS(g_destructionCount, 1u, TEST_LOCATION);
222 int UtcDaliIntrusivePtrGetP(void)
224 tet_infoline("Testing Dali::IntrusivePtr::Get()");
226 IntrusivePtr<Counted> counted(new Counted);
227 DALI_TEST_CHECK(counted.Get() != 0);
228 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
229 DALI_TEST_EQUALS(counted->ReferenceCount(), 1, TEST_LOCATION);
234 int UtcDaliIntrusivePtrGetN(void)
236 tet_infoline("Testing Dali::IntrusivePtr::Get()");
240 IntrusivePtr<Counted> counted(0);
241 DALI_TEST_CHECK(counted.Get() == 0);
242 DALI_TEST_EQUALS(g_creationCount, 0u, TEST_LOCATION);
247 int UtcDaliIntrusivePtrArrowOperatorP(void)
249 tet_infoline("Positive Test for Dali::IntrusivePtr::operator->()");
251 IntrusivePtr<Counted> counted(new Counted);
252 DALI_TEST_CHECK((counted.operator->()) != 0);
253 DALI_TEST_EQUALS(counted->ReferenceCount(), 1, TEST_LOCATION);
258 int UtcDaliIntrusivePtrArrowOperatorN(void)
260 tet_infoline("Negative Test for Dali::IntrusivePtr::operator->()");
262 IntrusivePtr<Counted> counted;
263 DALI_TEST_CHECK((counted.operator->()) == 0);
268 int UtcDaliIntrusivePtrIndirectionOperatorP(void)
270 tet_infoline("Positive Test for Dali::IntrusivePtr::operator*()");
272 IntrusivePtr<Counted> counted(new Counted);
273 DALI_TEST_CHECK(&(counted.operator*()) != 0);
274 DALI_TEST_EQUALS((*counted).ReferenceCount(), 1, TEST_LOCATION);
279 int UtcDaliIntrusivePtrIndirectionOperatorN(void)
281 tet_infoline("Negative Test for Dali::IntrusivePtr::operator*()");
283 IntrusivePtr<Counted> counted;
284 DALI_TEST_CHECK(&(counted.operator*()) == 0);
289 int UtcDaliIntrusivePtrResetP(void)
291 tet_infoline("Positive Test for Dali::IntrusivePtr::Reset()");
293 IntrusivePtr<Counted> counted(new Counted);
294 DALI_TEST_CHECK(counted.Get() != 0);
296 DALI_TEST_CHECK(counted.Get() == 0);
301 int UtcDaliIntrusivePtrResetN(void)
303 tet_infoline("Negative Test for Dali::IntrusivePtr::Reset()");
305 IntrusivePtr<Counted> counted;
306 Counted* firstGet = counted.Get();
308 DALI_TEST_EQUALS(counted.Get(), firstGet, TEST_LOCATION);
313 int UtcDaliIntrusivePtrResetTP(void)
315 tet_infoline("Positive Test for Dali::IntrusivePtr::Reset(T*)");
317 g_creationCount = g_destructionCount = 0;
319 IntrusivePtr<Counted> counted(new Counted);
321 IntrusivePtr<Counted> counted2(new Counted);
323 DALI_TEST_EQUALS(counted->ReferenceCount(), 1, TEST_LOCATION);
324 DALI_TEST_EQUALS(counted2->ReferenceCount(), 1, TEST_LOCATION);
326 counted.Reset(counted2.Get());
328 DALI_TEST_EQUALS(counted->ReferenceCount(), 2, TEST_LOCATION);
329 DALI_TEST_EQUALS(counted2->ReferenceCount(), 2, TEST_LOCATION);
331 DALI_TEST_EQUALS(counted.Get(), counted2.Get(), TEST_LOCATION);
333 DALI_TEST_EQUALS(g_creationCount, 2u, TEST_LOCATION);
334 DALI_TEST_EQUALS(g_destructionCount, 1u, TEST_LOCATION);
336 counted2.Reset((Counted*)0);
337 counted.Reset(counted2.Get());
338 DALI_TEST_EQUALS(g_destructionCount, 2u, TEST_LOCATION);
340 // Check that reseting nulls is harmless:
341 counted2.Reset(counted.Get());
342 counted.Reset(counted2.Get());
344 DALI_TEST_EQUALS(g_destructionCount, 2u, TEST_LOCATION);
349 int UtcDaliIntrusivePtrResetTN(void)
351 tet_infoline("Negative Test for Dali::IntrusivePtr::Reset(T*)");
353 g_creationCount = g_destructionCount = 0;
355 IntrusivePtr<Counted> counted(new Counted);
357 counted.Reset((Counted*)0);
359 DALI_TEST_EQUALS(counted.Get(), (Counted*)0, TEST_LOCATION);
360 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
361 DALI_TEST_EQUALS(g_destructionCount, 1u, TEST_LOCATION);
366 int UtcDaliIntrusivePtrOperatorBoolP(void)
368 tet_infoline("Positive Test for Dali::IntrusivePtr::operator bool()");
370 IntrusivePtr<Counted> counted(new Counted);
371 DALI_TEST_CHECK(counted.operator bool() == true);
372 DALI_TEST_CHECK(counted);
375 DALI_TEST_CHECK(counted.operator bool() == false);
380 int UtcDaliIntrusivePtrOperatorBoolN(void)
382 tet_infoline("Negative Test for Dali::IntrusivePtr::operator bool()");
384 IntrusivePtr<Counted> counted;
385 DALI_TEST_CHECK(counted.operator bool() == false);
386 DALI_TEST_CHECK(!counted);
390 /** Equality of two different types*/
391 int UtcDaliIntrusivePtrOperatorEqualTU(void)
393 tet_infoline("Test for Dali::IntrusivePtr::operator ==(T, U)");
395 IntrusivePtr<Counted> counted1(new Counted);
396 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
397 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
398 IntrusivePtr<Counted> counted2(countedSubclass2);
400 DALI_TEST_EQUALS(operator==(counted1, countedSubclass1), false, TEST_LOCATION);
401 DALI_TEST_EQUALS(operator==(counted2, countedSubclass2), true, TEST_LOCATION);
405 /** Inequality of two different types*/
406 int UtcDaliIntrusivePtrOperatorNotEqualTU(void)
408 tet_infoline("Test for Dali::IntrusivePtr::operator !=(T, U)");
410 IntrusivePtr<Counted> counted1(new Counted);
411 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
412 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
413 IntrusivePtr<Counted> counted2(countedSubclass2);
415 DALI_TEST_EQUALS(operator!=(counted1, countedSubclass1), true, TEST_LOCATION);
416 DALI_TEST_EQUALS(operator!=(counted2, countedSubclass2), false, TEST_LOCATION);
420 /** Equality of two different types where right hand side is a raw pointer */
421 int UtcDaliIntrusivePtrOperatorEqualRightPointerTU(void)
423 tet_infoline("Test for Dali::IntrusivePtr::operator ==(T, U*)");
425 IntrusivePtr<Counted> counted1(new Counted);
426 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
427 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
428 IntrusivePtr<Counted> counted2(countedSubclass2);
430 DALI_TEST_EQUALS(operator==(counted1, countedSubclass1.Get()), false, TEST_LOCATION);
431 DALI_TEST_EQUALS(operator==(counted2, countedSubclass2.Get()), true, TEST_LOCATION);
435 /** Inequality of two different types where the right hand side is a raw pointer */
436 int UtcDaliIntrusivePtrOperatorNotEqualRightPointerTU(void)
438 tet_infoline("Test for Dali::IntrusivePtr::operator !=(T, U*)");
440 IntrusivePtr<Counted> counted1(new Counted);
441 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
442 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
443 IntrusivePtr<Counted> counted2(countedSubclass2);
445 DALI_TEST_EQUALS(operator!=(counted1, countedSubclass1.Get()), true, TEST_LOCATION);
446 DALI_TEST_EQUALS(operator!=(counted2, countedSubclass2.Get()), false, TEST_LOCATION);
450 /** Equality of two different types where left hand side is a raw pointer */
451 int UtcDaliIntrusivePtrOperatorEqualLeftPointerTU(void)
453 tet_infoline("Test for Dali::IntrusivePtr::operator ==(T*, U)");
455 IntrusivePtr<Counted> counted1(new Counted);
456 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
457 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
458 IntrusivePtr<Counted> counted2(countedSubclass2);
460 DALI_TEST_EQUALS(operator==(counted1.Get(), countedSubclass1), false, TEST_LOCATION);
461 DALI_TEST_EQUALS(operator==(counted2.Get(), countedSubclass2), true, TEST_LOCATION);
465 /** Inequality of two different types where the left hand side is a raw pointer */
466 int UtcDaliIntrusivePtrOperatorNotEqualLeftPointerTU(void)
468 tet_infoline("Test for Dali::IntrusivePtr::operator !=(T*, U)");
470 IntrusivePtr<Counted> counted1(new Counted);
471 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
472 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
473 IntrusivePtr<Counted> counted2(countedSubclass2);
475 DALI_TEST_EQUALS(operator!=(counted1.Get(), countedSubclass1), true, TEST_LOCATION);
476 DALI_TEST_EQUALS(operator!=(counted2.Get(), countedSubclass2), false, TEST_LOCATION);
480 int UtcDaliRefObjectCopyConstructor(void)
482 tet_infoline("Test for Dali::RefObject(const RefObject&)");
485 IntrusivePtr<TestObject> testPtr(new TestObject);
486 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
488 const TestObject& testObject = *testPtr.Get();
490 IntrusivePtr<TestObject> testPtr2(new TestObject(testObject));
491 DALI_TEST_EQUALS(testPtr2->ReferenceCount(), 1, TEST_LOCATION);
493 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
498 int UtcDaliRefObjectAssignmentOperator(void)
500 tet_infoline("Test for Dali::RefObject::operator=(const RefObject&)");
503 IntrusivePtr<TestObject> testPtr(new TestObject);
504 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
506 const TestObject& testObject = *testPtr.Get();
508 IntrusivePtr<TestObject> testPtr2(new TestObject());
510 IntrusivePtr<TestObject> testPtr3 = testPtr2;
511 DALI_TEST_EQUALS(testPtr2->ReferenceCount(), 2, TEST_LOCATION);
512 DALI_TEST_EQUALS(testPtr2->data, 201, TEST_LOCATION);
514 TestObject& testObject2 = *testPtr2.Get();
515 testObject2 = testObject;
517 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
518 DALI_TEST_EQUALS(testPtr2->ReferenceCount(), 2, TEST_LOCATION);
520 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
526 int UtcDaliRefObjectAssignmentOperatorToNull(void)
528 tet_infoline("Testing Dali::IntrusivePtr = nullptr");
530 g_creationCount = g_destructionCount = 0;
532 IntrusivePtr<Counted> counted(new Counted);
534 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
535 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
537 IntrusivePtr<Counted> counted2 = counted;
538 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
539 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
541 DALI_TEST_EQUALS(counted->ReferenceCount(), 2, TEST_LOCATION);
544 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
545 DALI_TEST_EQUALS(counted->ReferenceCount(), 1, TEST_LOCATION);
548 DALI_TEST_EQUALS(g_destructionCount, 1u, TEST_LOCATION);
553 int UtcDaliIntrusivePtrMoveConstructor(void)
555 IntrusivePtr<TestObject> testPtr(new TestObject);
556 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
557 DALI_TEST_EQUALS(testPtr->data, 201, TEST_LOCATION);
559 IntrusivePtr<TestObject> movePtr = std::move(testPtr);
560 DALI_TEST_EQUALS(movePtr->ReferenceCount(), 1, TEST_LOCATION);
561 DALI_TEST_EQUALS(movePtr->data, 201, TEST_LOCATION);
562 DALI_TEST_CHECK(!testPtr);
564 IntrusivePtr<TestObject> anotherTestPtr(new TestObject);
565 DALI_TEST_EQUALS(anotherTestPtr->ReferenceCount(), 1, TEST_LOCATION);
566 DALI_TEST_EQUALS(anotherTestPtr->data, 201, TEST_LOCATION);
567 IntrusivePtr<TestObject> anotherMovePtr = std::move(anotherTestPtr);
568 DALI_TEST_EQUALS(anotherMovePtr->ReferenceCount(), 1, TEST_LOCATION);
569 DALI_TEST_EQUALS(anotherMovePtr->data, 201, TEST_LOCATION);
570 DALI_TEST_CHECK(!anotherTestPtr.Get());
572 IntrusivePtr<CountedSubclass> countedSubclass(new CountedSubclass);
573 DALI_TEST_EQUALS(countedSubclass->ReferenceCount(), 1, TEST_LOCATION);
575 IntrusivePtr<Counted> countedMovePtr = std::move(countedSubclass);
576 DALI_TEST_EQUALS(countedMovePtr->ReferenceCount(), 1, TEST_LOCATION);
577 DALI_TEST_CHECK(!countedSubclass);
582 int UtcDaliIntrusivePtrMoveAssignment(void)
584 IntrusivePtr<TestObject> testPtr(new TestObject);
585 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
586 DALI_TEST_EQUALS(testPtr->data, 201, TEST_LOCATION);
588 IntrusivePtr<TestObject> secondPtr(testPtr);
589 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 2, TEST_LOCATION);
591 IntrusivePtr<TestObject> thirdPtr;
592 testPtr = std::move(thirdPtr);
593 DALI_TEST_EQUALS(secondPtr->ReferenceCount(), 1, TEST_LOCATION);
594 DALI_TEST_EQUALS(secondPtr->data, 201, TEST_LOCATION);
595 DALI_TEST_CHECK(!testPtr.Get());
597 IntrusivePtr<TestObject> fourthPtr(new TestObject);
598 testPtr = std::move(fourthPtr);
599 DALI_TEST_CHECK(!fourthPtr.Get());
601 IntrusivePtr<CountedSubclass> countedSubclassPtr(new CountedSubclass);
602 DALI_TEST_EQUALS(countedSubclassPtr->ReferenceCount(), 1, TEST_LOCATION);
604 IntrusivePtr<Counted> countedMovePtr;
605 countedMovePtr = std::move(countedSubclassPtr);
606 DALI_TEST_EQUALS(countedMovePtr->ReferenceCount(), 1, TEST_LOCATION);
607 DALI_TEST_CHECK(!countedSubclassPtr);