Skip to content

Commit 19eb086

Browse files
authored
Merge pull request InsightSoftwareConsortium#5995 from hjmjohnson/cpp-cg-fem-unique-ptr
COMP: Use std::unique_ptr in FEMLinearSystemWrapperDenseVNL
2 parents 2fdcea2 + 7d94b93 commit 19eb086

File tree

3 files changed

+42
-67
lines changed

3 files changed

+42
-67
lines changed

Documentation/docs/migration_guides/itk_6_migration_guide.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ enabled. Similarly, `InputCoordinateType`, `OutputCoordinateType`, and
117117
and `ImagePointCoordRepType`, respectively.
118118

119119

120+
FEM LinearSystemWrapperDenseVNL public type aliases removed
121+
-------------------------------------------------------------
122+
123+
These two nested type aliases are removed from the public interface of
124+
`fem::LinearSystemWrapperDenseVNL`:
125+
126+
```cpp
127+
using MatrixRepresentation = vnl_matrix<Float>;
128+
using MatrixHolder = std::vector<MatrixRepresentation *>;
129+
```
130+
131+
120132
ITKVNLInstantiation library is removed
121133
--------------------------------------
122134

Modules/Numerics/FEM/include/itkFEMLinearSystemWrapperDenseVNL.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "vnl/vnl_vector.h"
2525
#include "vnl/algo/vnl_svd.h"
2626
#include "ITKFEMExport.h"
27+
#include <memory>
2728
#include <vector>
2829

2930
namespace itk::fem
@@ -44,12 +45,6 @@ class ITKFEM_EXPORT LinearSystemWrapperDenseVNL : public LinearSystemWrapper
4445
/* superclass */
4546
using Superclass = LinearSystemWrapper;
4647

47-
/* matrix type alias */
48-
using MatrixRepresentation = vnl_matrix<Float>;
49-
50-
/* matrix holder type alias */
51-
using MatrixHolder = std::vector<MatrixRepresentation *>;
52-
5348
/* constructor & destructor */
5449
LinearSystemWrapperDenseVNL()
5550
: LinearSystemWrapper()
@@ -169,15 +164,16 @@ class ITKFEM_EXPORT LinearSystemWrapperDenseVNL : public LinearSystemWrapper
169164
MultiplyMatrixVector(unsigned int resultVectorIndex, unsigned int matrixIndex, unsigned int vectorIndex) override;
170165

171166
private:
172-
/** vector of pointers to VNL sparse matrices */
173-
// std::vector< vnl_sparse_matrix<Float>* > *m_Matrices;
174-
MatrixHolder * m_Matrices{ nullptr };
167+
/* internal type aliases — not part of the public API */
168+
using MatrixRepresentation = vnl_matrix<Float>;
169+
using MatrixHolder = std::vector<std::unique_ptr<MatrixRepresentation>>;
170+
using VectorHolder = std::vector<std::unique_ptr<vnl_vector<Float>>>;
171+
172+
std::unique_ptr<MatrixHolder> m_Matrices;
175173

176-
/** vector of pointers to VNL vectors */
177-
std::vector<vnl_vector<Float> *> * m_Vectors{ nullptr };
174+
std::unique_ptr<VectorHolder> m_Vectors;
178175

179-
/** vector of pointers to VNL vectors */
180-
std::vector<vnl_vector<Float> *> * m_Solutions{ nullptr };
176+
std::unique_ptr<VectorHolder> m_Solutions;
181177
};
182178
} // namespace itk::fem
183179

Modules/Numerics/FEM/src/itkFEMLinearSystemWrapperDenseVNL.cxx

Lines changed: 21 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,23 @@
2020

2121
namespace itk::fem
2222
{
23+
// Destructor is defined out-of-line so that the vtable and typeinfo are
24+
// emitted as exported symbols in shared library builds. Moving it to
25+
// inline = default in the header would make them hidden under
26+
// -fvisibility-inlines-hidden, breaking dynamic_cast across DSO boundaries.
27+
// See: https://github.com/InsightSoftwareConsortium/ITK/issues/6000
28+
LinearSystemWrapperDenseVNL::~LinearSystemWrapperDenseVNL() = default;
29+
2330
void
2431
LinearSystemWrapperDenseVNL::InitializeMatrix(unsigned int matrixIndex)
2532
{
2633
// allocate if necessary
2734
if (m_Matrices == nullptr)
2835
{
29-
m_Matrices = new MatrixHolder(m_NumberOfMatrices);
36+
m_Matrices = std::make_unique<MatrixHolder>(m_NumberOfMatrices);
3037
}
3138

32-
// out with old, in with new
33-
delete (*m_Matrices)[matrixIndex];
34-
35-
(*m_Matrices)[matrixIndex] = new MatrixRepresentation(this->GetSystemOrder(), this->GetSystemOrder());
39+
(*m_Matrices)[matrixIndex] = std::make_unique<MatrixRepresentation>(this->GetSystemOrder(), this->GetSystemOrder());
3640
(*m_Matrices)[matrixIndex]->fill(0.0);
3741
}
3842

@@ -56,8 +60,7 @@ LinearSystemWrapperDenseVNL::DestroyMatrix(unsigned int matrixIndex)
5660
{
5761
if (m_Matrices)
5862
{
59-
delete (*m_Matrices)[matrixIndex];
60-
(*m_Matrices)[matrixIndex] = nullptr;
63+
(*m_Matrices)[matrixIndex].reset();
6164
}
6265
}
6366

@@ -67,13 +70,10 @@ LinearSystemWrapperDenseVNL::InitializeVector(unsigned int vectorIndex)
6770
// allocate if necessary
6871
if (m_Vectors == nullptr)
6972
{
70-
m_Vectors = new std::vector<vnl_vector<Float> *>(m_NumberOfVectors);
73+
m_Vectors = std::make_unique<std::vector<std::unique_ptr<vnl_vector<Float>>>>(m_NumberOfVectors);
7174
}
7275

73-
// out with old, in with new
74-
delete (*m_Vectors)[vectorIndex];
75-
76-
(*m_Vectors)[vectorIndex] = new vnl_vector<Float>(this->GetSystemOrder());
76+
(*m_Vectors)[vectorIndex] = std::make_unique<vnl_vector<Float>>(this->GetSystemOrder());
7777
(*m_Vectors)[vectorIndex]->fill(0.0);
7878
}
7979

@@ -97,8 +97,7 @@ LinearSystemWrapperDenseVNL::DestroyVector(unsigned int vectorIndex)
9797
{
9898
if (m_Vectors)
9999
{
100-
delete (*m_Vectors)[vectorIndex];
101-
(*m_Vectors)[vectorIndex] = nullptr;
100+
(*m_Vectors)[vectorIndex].reset();
102101
}
103102
}
104103

@@ -108,13 +107,10 @@ LinearSystemWrapperDenseVNL::InitializeSolution(unsigned int solutionIndex)
108107
// allocate if necessary
109108
if (m_Solutions == nullptr)
110109
{
111-
m_Solutions = new std::vector<vnl_vector<Float> *>(m_NumberOfSolutions);
110+
m_Solutions = std::make_unique<std::vector<std::unique_ptr<vnl_vector<Float>>>>(m_NumberOfSolutions);
112111
}
113112

114-
// out with old, in with new
115-
delete (*m_Solutions)[solutionIndex];
116-
117-
(*m_Solutions)[solutionIndex] = new vnl_vector<Float>(this->GetSystemOrder());
113+
(*m_Solutions)[solutionIndex] = std::make_unique<vnl_vector<Float>>(this->GetSystemOrder());
118114
(*m_Solutions)[solutionIndex]->fill(0.0);
119115
}
120116

@@ -138,8 +134,7 @@ LinearSystemWrapperDenseVNL::DestroySolution(unsigned int solutionIndex)
138134
{
139135
if (m_Solutions)
140136
{
141-
delete (*m_Solutions)[solutionIndex];
142-
(*m_Solutions)[solutionIndex] = nullptr;
137+
(*m_Solutions)[solutionIndex].reset();
143138
}
144139
}
145140

@@ -189,39 +184,31 @@ LinearSystemWrapperDenseVNL::Solve()
189184
void
190185
LinearSystemWrapperDenseVNL::SwapMatrices(unsigned int MatrixIndex1, unsigned int MatrixIndex2)
191186
{
192-
vnl_matrix<Float> * tmp = (*m_Matrices)[MatrixIndex1];
193-
(*m_Matrices)[MatrixIndex1] = (*m_Matrices)[MatrixIndex2];
194-
(*m_Matrices)[MatrixIndex2] = tmp;
187+
std::swap((*m_Matrices)[MatrixIndex1], (*m_Matrices)[MatrixIndex2]);
195188
}
196189

197190
void
198191
LinearSystemWrapperDenseVNL::SwapVectors(unsigned int VectorIndex1, unsigned int VectorIndex2)
199192
{
200-
vnl_vector<Float> tmp = *(*m_Vectors)[VectorIndex1];
201-
*(*m_Vectors)[VectorIndex1] = *(*m_Vectors)[VectorIndex2];
202-
*(*m_Vectors)[VectorIndex2] = tmp;
193+
std::swap((*m_Vectors)[VectorIndex1], (*m_Vectors)[VectorIndex2]);
203194
}
204195

205196
void
206197
LinearSystemWrapperDenseVNL::SwapSolutions(unsigned int SolutionIndex1, unsigned int SolutionIndex2)
207198
{
208-
vnl_vector<Float> * tmp = (*m_Solutions)[SolutionIndex1];
209-
(*m_Solutions)[SolutionIndex1] = (*m_Solutions)[SolutionIndex2];
210-
(*m_Solutions)[SolutionIndex2] = tmp;
199+
std::swap((*m_Solutions)[SolutionIndex1], (*m_Solutions)[SolutionIndex2]);
211200
}
212201

213202
void
214203
LinearSystemWrapperDenseVNL::CopySolution2Vector(unsigned int SolutionIndex, unsigned int VectorIndex)
215204
{
216-
delete (*m_Vectors)[VectorIndex];
217-
(*m_Vectors)[VectorIndex] = new vnl_vector<Float>(*((*m_Solutions)[SolutionIndex]));
205+
(*m_Vectors)[VectorIndex] = std::make_unique<vnl_vector<Float>>(*((*m_Solutions)[SolutionIndex]));
218206
}
219207

220208
void
221209
LinearSystemWrapperDenseVNL::CopyVector2Solution(unsigned int VectorIndex, unsigned int SolutionIndex)
222210
{
223-
delete (*m_Solutions)[SolutionIndex];
224-
(*m_Solutions)[SolutionIndex] = new vnl_vector<Float>(*((*m_Vectors)[VectorIndex]));
211+
(*m_Solutions)[SolutionIndex] = std::make_unique<vnl_vector<Float>>(*((*m_Vectors)[VectorIndex]));
225212
}
226213

227214
void
@@ -266,24 +253,4 @@ LinearSystemWrapperDenseVNL::ScaleSolution(Float scale, unsigned int solutionInd
266253
(*(*m_Solutions)[solutionIndex]) = (*(*m_Solutions)[solutionIndex]) * scale;
267254
}
268255

269-
LinearSystemWrapperDenseVNL::~LinearSystemWrapperDenseVNL()
270-
{
271-
for (unsigned int i = 0; i < m_NumberOfMatrices; ++i)
272-
{
273-
this->DestroyMatrix(i);
274-
}
275-
for (unsigned int i = 0; i < m_NumberOfVectors; ++i)
276-
{
277-
this->DestroyVector(i);
278-
}
279-
for (unsigned int i = 0; i < m_NumberOfSolutions; ++i)
280-
{
281-
this->DestroySolution(i);
282-
}
283-
284-
delete m_Matrices;
285-
delete m_Vectors;
286-
delete m_Solutions;
287-
}
288-
289256
} // namespace itk::fem

0 commit comments

Comments
 (0)