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 UtcDaliIntrusivePtrOperatorBooleanTypeP(void)
368 tet_infoline("Positive Test for Dali::IntrusivePtr::operator Booleantype()");
370 IntrusivePtr<Counted> counted(new Counted);
371 DALI_TEST_CHECK(counted.operator BooleanType() != 0);
372 DALI_TEST_CHECK(counted);
374 typedef void (IntrusivePtr<Counted>::*BoolIdiomFunc)() const;
375 BoolIdiomFunc func = static_cast<BoolIdiomFunc>(counted.operator BooleanType());
376 ((counted).*func)(); // purely for test coverage
379 DALI_TEST_CHECK(counted.operator BooleanType() == 0);
384 int UtcDaliIntrusivePtrOperatorBooleanTypeN(void)
386 tet_infoline("Negative Test for Dali::IntrusivePtr::operator Booleantype()");
388 IntrusivePtr<Counted> counted;
389 DALI_TEST_CHECK(counted.operator BooleanType() == 0);
390 DALI_TEST_CHECK(!counted);
394 /** Equality of two different types*/
395 int UtcDaliIntrusivePtrOperatorEqualTU(void)
397 tet_infoline("Test for Dali::IntrusivePtr::operator ==(T, U)");
399 IntrusivePtr<Counted> counted1(new Counted);
400 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
401 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
402 IntrusivePtr<Counted> counted2(countedSubclass2);
404 DALI_TEST_EQUALS(operator==(counted1, countedSubclass1), false, TEST_LOCATION);
405 DALI_TEST_EQUALS(operator==(counted2, countedSubclass2), true, TEST_LOCATION);
409 /** Inequality of two different types*/
410 int UtcDaliIntrusivePtrOperatorNotEqualTU(void)
412 tet_infoline("Test for Dali::IntrusivePtr::operator !=(T, U)");
414 IntrusivePtr<Counted> counted1(new Counted);
415 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
416 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
417 IntrusivePtr<Counted> counted2(countedSubclass2);
419 DALI_TEST_EQUALS(operator!=(counted1, countedSubclass1), true, TEST_LOCATION);
420 DALI_TEST_EQUALS(operator!=(counted2, countedSubclass2), false, TEST_LOCATION);
424 /** Equality of two different types where right hand side is a raw pointer */
425 int UtcDaliIntrusivePtrOperatorEqualRightPointerTU(void)
427 tet_infoline("Test for Dali::IntrusivePtr::operator ==(T, U*)");
429 IntrusivePtr<Counted> counted1(new Counted);
430 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
431 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
432 IntrusivePtr<Counted> counted2(countedSubclass2);
434 DALI_TEST_EQUALS(operator==(counted1, countedSubclass1.Get()), false, TEST_LOCATION);
435 DALI_TEST_EQUALS(operator==(counted2, countedSubclass2.Get()), true, TEST_LOCATION);
439 /** Inequality of two different types where the right hand side is a raw pointer */
440 int UtcDaliIntrusivePtrOperatorNotEqualRightPointerTU(void)
442 tet_infoline("Test for Dali::IntrusivePtr::operator !=(T, U*)");
444 IntrusivePtr<Counted> counted1(new Counted);
445 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
446 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
447 IntrusivePtr<Counted> counted2(countedSubclass2);
449 DALI_TEST_EQUALS(operator!=(counted1, countedSubclass1.Get()), true, TEST_LOCATION);
450 DALI_TEST_EQUALS(operator!=(counted2, countedSubclass2.Get()), false, TEST_LOCATION);
454 /** Equality of two different types where left hand side is a raw pointer */
455 int UtcDaliIntrusivePtrOperatorEqualLeftPointerTU(void)
457 tet_infoline("Test for Dali::IntrusivePtr::operator ==(T*, U)");
459 IntrusivePtr<Counted> counted1(new Counted);
460 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
461 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
462 IntrusivePtr<Counted> counted2(countedSubclass2);
464 DALI_TEST_EQUALS(operator==(counted1.Get(), countedSubclass1), false, TEST_LOCATION);
465 DALI_TEST_EQUALS(operator==(counted2.Get(), countedSubclass2), true, TEST_LOCATION);
469 /** Inequality of two different types where the left hand side is a raw pointer */
470 int UtcDaliIntrusivePtrOperatorNotEqualLeftPointerTU(void)
472 tet_infoline("Test for Dali::IntrusivePtr::operator !=(T*, U)");
474 IntrusivePtr<Counted> counted1(new Counted);
475 IntrusivePtr<CountedSubclass> countedSubclass1(new CountedSubclass);
476 IntrusivePtr<CountedSubclass> countedSubclass2(new CountedSubclass);
477 IntrusivePtr<Counted> counted2(countedSubclass2);
479 DALI_TEST_EQUALS(operator!=(counted1.Get(), countedSubclass1), true, TEST_LOCATION);
480 DALI_TEST_EQUALS(operator!=(counted2.Get(), countedSubclass2), false, TEST_LOCATION);
484 int UtcDaliRefObjectCopyConstructor(void)
486 tet_infoline("Test for Dali::RefObject(const RefObject&)");
489 IntrusivePtr<TestObject> testPtr(new TestObject);
490 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
492 const TestObject& testObject = *testPtr.Get();
494 IntrusivePtr<TestObject> testPtr2(new TestObject(testObject));
495 DALI_TEST_EQUALS(testPtr2->ReferenceCount(), 1, TEST_LOCATION);
497 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
502 int UtcDaliRefObjectAssignmentOperator(void)
504 tet_infoline("Test for Dali::RefObject::operator=(const RefObject&)");
507 IntrusivePtr<TestObject> testPtr(new TestObject);
508 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
510 const TestObject& testObject = *testPtr.Get();
512 IntrusivePtr<TestObject> testPtr2(new TestObject());
514 IntrusivePtr<TestObject> testPtr3 = testPtr2;
515 DALI_TEST_EQUALS(testPtr2->ReferenceCount(), 2, TEST_LOCATION);
516 DALI_TEST_EQUALS(testPtr2->data, 201, TEST_LOCATION);
518 TestObject& testObject2 = *testPtr2.Get();
519 testObject2 = testObject;
521 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
522 DALI_TEST_EQUALS(testPtr2->ReferenceCount(), 2, TEST_LOCATION);
524 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
530 int UtcDaliRefObjectAssignmentOperatorToNull(void)
532 tet_infoline("Testing Dali::IntrusivePtr = nullptr");
534 g_creationCount = g_destructionCount = 0;
536 IntrusivePtr<Counted> counted(new Counted);
538 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
539 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
541 IntrusivePtr<Counted> counted2 = counted;
542 DALI_TEST_EQUALS(g_creationCount, 1u, TEST_LOCATION);
543 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
545 DALI_TEST_EQUALS(counted->ReferenceCount(), 2, TEST_LOCATION);
548 DALI_TEST_EQUALS(g_destructionCount, 0u, TEST_LOCATION);
549 DALI_TEST_EQUALS(counted->ReferenceCount(), 1, TEST_LOCATION);
552 DALI_TEST_EQUALS(g_destructionCount, 1u, TEST_LOCATION);
557 int UtcDaliIntrusivePtrMoveConstructor(void)
559 IntrusivePtr<TestObject> testPtr(new TestObject);
560 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
561 DALI_TEST_EQUALS(testPtr->data, 201, TEST_LOCATION);
563 IntrusivePtr<TestObject> movePtr = std::move(testPtr);
564 DALI_TEST_EQUALS(movePtr->ReferenceCount(), 1, TEST_LOCATION);
565 DALI_TEST_EQUALS(movePtr->data, 201, TEST_LOCATION);
566 DALI_TEST_CHECK(!testPtr);
568 IntrusivePtr<TestObject> anotherTestPtr(new TestObject);
569 DALI_TEST_EQUALS(anotherTestPtr->ReferenceCount(), 1, TEST_LOCATION);
570 DALI_TEST_EQUALS(anotherTestPtr->data, 201, TEST_LOCATION);
571 IntrusivePtr<TestObject> anotherMovePtr = std::move(anotherTestPtr);
572 DALI_TEST_EQUALS(anotherMovePtr->ReferenceCount(), 1, TEST_LOCATION);
573 DALI_TEST_EQUALS(anotherMovePtr->data, 201, TEST_LOCATION);
574 DALI_TEST_CHECK(!anotherTestPtr.Get());
576 IntrusivePtr<CountedSubclass> countedSubclass(new CountedSubclass);
577 DALI_TEST_EQUALS(countedSubclass->ReferenceCount(), 1, TEST_LOCATION);
579 IntrusivePtr<Counted> countedMovePtr = std::move(countedSubclass);
580 DALI_TEST_EQUALS(countedMovePtr->ReferenceCount(), 1, TEST_LOCATION);
581 DALI_TEST_CHECK(!countedSubclass);
586 int UtcDaliIntrusivePtrMoveAssignment(void)
588 IntrusivePtr<TestObject> testPtr(new TestObject);
589 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 1, TEST_LOCATION);
590 DALI_TEST_EQUALS(testPtr->data, 201, TEST_LOCATION);
592 IntrusivePtr<TestObject> secondPtr(testPtr);
593 DALI_TEST_EQUALS(testPtr->ReferenceCount(), 2, TEST_LOCATION);
595 IntrusivePtr<TestObject> thirdPtr;
596 testPtr = std::move(thirdPtr);
597 DALI_TEST_EQUALS(secondPtr->ReferenceCount(), 1, TEST_LOCATION);
598 DALI_TEST_EQUALS(secondPtr->data, 201, TEST_LOCATION);
599 DALI_TEST_CHECK(!testPtr.Get());
601 IntrusivePtr<TestObject> fourthPtr(new TestObject);
602 testPtr = std::move(fourthPtr);
603 DALI_TEST_CHECK(!fourthPtr.Get());
605 IntrusivePtr<CountedSubclass> countedSubclassPtr(new CountedSubclass);
606 DALI_TEST_EQUALS(countedSubclassPtr->ReferenceCount(), 1, TEST_LOCATION);
608 IntrusivePtr<Counted> countedMovePtr;
609 countedMovePtr = std::move(countedSubclassPtr);
610 DALI_TEST_EQUALS(countedMovePtr->ReferenceCount(), 1, TEST_LOCATION);
611 DALI_TEST_CHECK(!countedSubclassPtr);