Skip to content

Commit ce3babd

Browse files
Copilothjmjohnson
authored andcommitted
ENH: Add stream insertion operators to print_helper
std::list and C-style arrays to print_helper
1 parent 1cb6591 commit ce3babd

File tree

7 files changed

+145
-44
lines changed

7 files changed

+145
-44
lines changed

Modules/Core/Common/include/itkNeighborhood.hxx

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define itkNeighborhood_hxx
2020

2121
#include "itkNumericTraits.h"
22+
#include "itkPrintHelper.h"
2223

2324
namespace itk
2425
{
@@ -115,22 +116,11 @@ template <typename TPixel, unsigned int VDimension, typename TContainer>
115116
void
116117
Neighborhood<TPixel, VDimension, TContainer>::PrintSelf(std::ostream & os, Indent indent) const
117118
{
119+
using namespace itk::print_helper;
118120
os << indent << "Size: " << static_cast<typename NumericTraits<SizeType>::PrintType>(m_Size) << std::endl;
119121
os << indent << "Radius: " << static_cast<typename NumericTraits<SizeType>::PrintType>(m_Radius) << std::endl;
120-
121-
os << indent << "StrideTable: [ ";
122-
for (DimensionValueType i = 0; i < VDimension; ++i)
123-
{
124-
os << indent.GetNextIndent() << m_StrideTable[i] << ' ';
125-
}
126-
os << ']' << std::endl;
127-
128-
os << indent << "OffsetTable: [ ";
129-
for (DimensionValueType i = 0; i < m_OffsetTable.size(); ++i)
130-
{
131-
os << indent.GetNextIndent() << m_OffsetTable[i] << ' ';
132-
}
133-
os << ']' << std::endl;
122+
os << indent << "StrideTable: " << m_StrideTable << std::endl;
123+
os << indent << "OffsetTable: " << m_OffsetTable << std::endl;
134124
}
135125
} // namespace itk
136126

Modules/Core/Common/include/itkPrintHelper.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#include <iostream>
2323
#include <iterator>
24+
#include <list>
25+
#include <type_traits>
2426

2527
// Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112467
2628
#if defined(ITK_WRAPPING_PARSER) && defined(__GNUC__) && !defined(__clang__)
@@ -50,6 +52,43 @@ operator<<(std::ostream & os, const std::vector<T> & v)
5052
return os << v.back() << ')';
5153
}
5254

55+
template <typename T>
56+
std::ostream &
57+
operator<<(std::ostream & os, const std::list<T> & l)
58+
{
59+
if (l.empty())
60+
{
61+
return os << "()";
62+
}
63+
64+
os << '(';
65+
auto it = l.begin();
66+
auto last = std::prev(l.end());
67+
for (; it != last; ++it)
68+
{
69+
os << *it << ", ";
70+
}
71+
return os << *it << ')';
72+
}
73+
74+
// Stream insertion operator for C-style arrays, excluding character arrays (strings)
75+
template <typename T, size_t N, typename = std::enable_if_t<!std::is_same_v<T, char>>>
76+
std::ostream &
77+
operator<<(std::ostream & os, const T (&arr)[N])
78+
{
79+
if constexpr (N == 0)
80+
{
81+
return os << "()";
82+
}
83+
84+
os << '(';
85+
for (size_t i = 0; i < N - 1; ++i)
86+
{
87+
os << arr[i] << ", ";
88+
}
89+
return os << arr[N - 1] << ')';
90+
}
91+
5392
} // namespace itk::print_helper
5493

5594
#endif // itkPrintHelper_h

Modules/Core/Common/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,6 +1895,7 @@ set(
18951895
itkOptimizerParametersGTest.cxx
18961896
itkPointGTest.cxx
18971897
itkPointSetGTest.cxx
1898+
itkPrintHelperGTest.cxx
18981899
itkRGBAPixelGTest.cxx
18991900
itkRGBPixelGTest.cxx
19001901
itkShapedImageNeighborhoodRangeGTest.cxx
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*=========================================================================
2+
*
3+
* Copyright NumFOCUS
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0.txt
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*=========================================================================*/
18+
19+
#include "itkPrintHelper.h"
20+
#include "itkOffset.h"
21+
#include "gtest/gtest.h"
22+
#include <sstream>
23+
#include <vector>
24+
#include <list>
25+
26+
TEST(PrintHelper, Vector)
27+
{
28+
using namespace itk::print_helper;
29+
std::vector<int> v{ 1, 2, 3, 4, 5 };
30+
std::ostringstream oss;
31+
oss << v;
32+
EXPECT_EQ(oss.str(), "(1, 2, 3, 4, 5)");
33+
}
34+
35+
TEST(PrintHelper, EmptyVector)
36+
{
37+
using namespace itk::print_helper;
38+
std::vector<int> v;
39+
std::ostringstream oss;
40+
oss << v;
41+
EXPECT_EQ(oss.str(), "()");
42+
}
43+
44+
TEST(PrintHelper, List)
45+
{
46+
using namespace itk::print_helper;
47+
std::list<int> l{ 1, 2, 3, 4, 5 };
48+
std::ostringstream oss;
49+
oss << l;
50+
EXPECT_EQ(oss.str(), "(1, 2, 3, 4, 5)");
51+
}
52+
53+
TEST(PrintHelper, EmptyList)
54+
{
55+
using namespace itk::print_helper;
56+
std::list<int> l;
57+
std::ostringstream oss;
58+
oss << l;
59+
EXPECT_EQ(oss.str(), "()");
60+
}
61+
62+
TEST(PrintHelper, CStyleArray)
63+
{
64+
using namespace itk::print_helper;
65+
int arr[5] = { 1, 2, 3, 4, 5 };
66+
std::ostringstream oss;
67+
oss << arr;
68+
EXPECT_EQ(oss.str(), "(1, 2, 3, 4, 5)");
69+
}
70+
71+
TEST(PrintHelper, CStyleArraySingleElement)
72+
{
73+
using namespace itk::print_helper;
74+
int arr[1] = { 42 };
75+
std::ostringstream oss;
76+
oss << arr;
77+
EXPECT_EQ(oss.str(), "(42)");
78+
}
79+
80+
TEST(PrintHelper, VectorOfOffsets)
81+
{
82+
using namespace itk::print_helper;
83+
std::vector<itk::Offset<2>> v;
84+
itk::Offset<2> o1{ { 1, 2 } };
85+
itk::Offset<2> o2{ { 3, 4 } };
86+
v.push_back(o1);
87+
v.push_back(o2);
88+
std::ostringstream oss;
89+
oss << v;
90+
EXPECT_EQ(oss.str(), "([1, 2], [3, 4])");
91+
}

Modules/Core/Transform/include/itkScalableAffineTransform.hxx

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "itkMath.h"
2222
#include "itkNumericTraits.h"
23+
#include "itkPrintHelper.h"
2324
#include "vnl/algo/vnl_matrix_inverse.h"
2425

2526
namespace itk
@@ -77,19 +78,10 @@ template <typename TParametersValueType, unsigned int VDimension>
7778
void
7879
ScalableAffineTransform<TParametersValueType, VDimension>::PrintSelf(std::ostream & os, Indent indent) const
7980
{
81+
using namespace itk::print_helper;
8082
Superclass::PrintSelf(os, indent);
81-
os << indent << "Scale : ";
82-
for (unsigned int i = 0; i < VDimension; ++i)
83-
{
84-
os << m_Scale[i] << ' ';
85-
}
86-
os << std::endl;
87-
os << indent << "MatrixScale : ";
88-
for (unsigned int i = 0; i < VDimension; ++i)
89-
{
90-
os << m_MatrixScale[i] << ' ';
91-
}
92-
os << std::endl;
83+
os << indent << "Scale: " << m_Scale << std::endl;
84+
os << indent << "MatrixScale: " << m_MatrixScale << std::endl;
9385
}
9486

9587
template <typename TParametersValueType, unsigned int VDimension>

Modules/Filtering/ImageFeature/include/itkHoughTransform2DCirclesImageFilter.hxx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "itkGaussianDerivativeImageFunction.h"
2424
#include "itkMinimumMaximumImageCalculator.h"
2525
#include "itkMath.h"
26+
#include "itkPrintHelper.h"
2627

2728
namespace itk
2829
{
@@ -282,6 +283,7 @@ void
282283
HoughTransform2DCirclesImageFilter<TInputPixelType, TOutputPixelType, TRadiusPixelType>::PrintSelf(std::ostream & os,
283284
Indent indent) const
284285
{
286+
using namespace itk::print_helper;
285287
Superclass::PrintSelf(os, indent);
286288

287289
os << indent << "Threshold: " << m_Threshold << std::endl;
@@ -297,15 +299,7 @@ HoughTransform2DCirclesImageFilter<TInputPixelType, TOutputPixelType, TRadiusPix
297299

298300
itkPrintSelfObjectMacro(RadiusImage);
299301

300-
os << indent << "CirclesList: " << std::endl;
301-
unsigned int i = 0;
302-
auto it = m_CirclesList.begin();
303-
while (it != m_CirclesList.end())
304-
{
305-
os << indent << '[' << i << "]: " << *it << std::endl;
306-
++it;
307-
++i;
308-
}
302+
os << indent << "CirclesList: " << m_CirclesList << std::endl;
309303

310304
os << indent << "OldModifiedTime: " << NumericTraits<ModifiedTimeType>::PrintType(m_OldModifiedTime) << std::endl;
311305
}

Modules/Filtering/ImageFeature/include/itkHoughTransform2DLinesImageFilter.hxx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "itkMinimumMaximumImageCalculator.h"
2424
#include "itkCastImageFilter.h"
2525
#include "itkMath.h"
26+
#include "itkPrintHelper.h"
2627

2728
namespace itk
2829
{
@@ -356,6 +357,7 @@ template <typename TInputPixelType, typename TOutputPixelType>
356357
void
357358
HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>::PrintSelf(std::ostream & os, Indent indent) const
358359
{
360+
using namespace itk::print_helper;
359361
Superclass::PrintSelf(os, indent);
360362

361363
os << indent << "Threshold: " << m_Threshold << std::endl;
@@ -365,15 +367,7 @@ HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>::PrintSelf(s
365367
os << indent << "Accumulator blur variance: " << m_Variance << std::endl;
366368
itkPrintSelfObjectMacro(SimplifyAccumulator);
367369

368-
os << indent << "LinesList: " << std::endl;
369-
unsigned int i = 0;
370-
auto it = m_LinesList.begin();
371-
while (it != m_LinesList.end())
372-
{
373-
os << indent << '[' << i << "]: " << *it << std::endl;
374-
++it;
375-
++i;
376-
}
370+
os << indent << "LinesList: " << m_LinesList << std::endl;
377371

378372
os << indent << "OldModifiedTime: " << NumericTraits<ModifiedTimeType>::PrintType(m_OldModifiedTime) << std::endl;
379373
}

0 commit comments

Comments
 (0)