1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    TestSmartPointer.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 // .NAME Test of vtkNew.
16 // .SECTION Description
17 // Tests instantiations of the vtkNew class template.
18 
19 #include "vtkDebugLeaks.h"
20 #include "vtkFloatArray.h"
21 #include "vtkIntArray.h"
22 #include "vtkNew.h"
23 #include "vtkSmartPointer.h"
24 #include "vtkWeakPointer.h"
25 
26 #include "vtkTestNewVar.h"
27 
TestNew(int,char * [])28 int TestNew(int, char*[])
29 {
30   bool error = false;
31   // This one should be cleaned up when the main function ends.
32   vtkNew<vtkIntArray> a;
33   if (a->GetReferenceCount() != 1)
34   {
35     error = true;
36     cerr << "Error, reference count should be 1, was " << a->GetReferenceCount() << endl;
37   }
38   cout << "vtkNew streaming " << a << endl;
39 
40   vtkWeakPointer<vtkFloatArray> wf;
41   // Test scoping, and deletion.
42   if (wf == nullptr)
43   {
44     vtkNew<vtkFloatArray> f;
45     wf = f;
46   }
47   if (wf != nullptr)
48   {
49     error = true;
50     cerr << "Error, vtkNew failed to delete the object it contained." << endl;
51   }
52   // Test implicit conversion vtkNew::operator T* () const
53   if (wf == nullptr)
54   {
55     vtkNew<vtkFloatArray> f;
56     wf = f;
57   }
58   if (wf != nullptr)
59   {
60     error = true;
61     cerr << "Error, vtkNew failed to delete the object it contained (implicit cast to raw pointer)."
62          << endl;
63   }
64 
65   // Now test interaction with the smart pointer.
66   vtkSmartPointer<vtkIntArray> si;
67   if (si == nullptr)
68   {
69     vtkNew<vtkIntArray> i;
70     si = i;
71   }
72   if (si->GetReferenceCount() != 1)
73   {
74     error = true;
75     cerr << "Error, vtkNew failed to delete the object it contained, "
76          << "or the smart pointer failed to increment it. Reference count: "
77          << si->GetReferenceCount() << endl;
78   }
79 
80   // Test raw object reference
81   vtkObject& p = *si;
82   if (p.GetReferenceCount() != 1)
83   {
84     error = true;
85     cerr << "Error, vtkNew failed to keep the object it contained, "
86          << "or setting a raw reference incremented it. Reference count: " << p.GetReferenceCount()
87          << endl;
88   }
89 
90   vtkNew<vtkTestNewVar> newVarObj;
91   if (newVarObj->GetPointsRefCount() != 1)
92   {
93     error = true;
94     cerr << "The member pointer failed to set the correct reference count: "
95          << newVarObj->GetPointsRefCount() << endl;
96   }
97 
98   vtkSmartPointer<vtkObject> points = newVarObj->GetPoints();
99   if (points->GetReferenceCount() != 2)
100   {
101     error = true;
102     cerr << "Error, vtkNew failed to keep the object it contained, "
103          << "or the smart pointer failed to increment it. Reference count: "
104          << points->GetReferenceCount() << endl;
105   }
106   vtkSmartPointer<vtkObject> points2 = newVarObj->GetPoints2();
107   if (points2->GetReferenceCount() != 3)
108   {
109     error = true;
110     cerr << "Error, vtkNew failed to keep the object it contained, "
111          << "or the smart pointer failed to increment it. Reference count: "
112          << points->GetReferenceCount() << endl;
113   }
114 
115   vtkNew<vtkIntArray> intarray;
116   vtkIntArray* intarrayp = intarray.GetPointer();
117   if (intarrayp != intarray || intarray != intarrayp)
118   {
119     error = true;
120     cerr << "Error, comparison of vtkNew object to it's raw pointer fails\n";
121   }
122 
123   {
124     vtkNew<vtkIntArray> testArray1;
125     vtkNew<vtkIntArray> testArray2(std::move(testArray1));
126     // NOLINTNEXTLINE(bugprone-use-after-move)
127     if (testArray1 || !testArray2)
128     {
129       std::cerr << "Error, move construction of vtkNew failed.\n";
130       error = true;
131     }
132     vtkNew<vtkDataArray> testArray3(std::move(testArray2));
133     // NOLINTNEXTLINE(bugprone-use-after-move)
134     if (testArray2 || !testArray3)
135     {
136       std::cerr << "Error, move construction of vtkNew failed.\n";
137       error = true;
138     }
139   }
140 
141   return error ? 1 : 0;
142 }
143