Skip to content

Commit 37fca10

Browse files
blowekampdzenanz
authored andcommitted
BUG: Fix printing of values in MetaDataObject
Also removes dead code related to METADATAPRINT Fix #1454 Co-Author: Pablo Hernandez-Cerdan <[email protected]>
1 parent 8c797f2 commit 37fca10

File tree

3 files changed

+43
-57
lines changed

3 files changed

+43
-57
lines changed

Modules/Core/Common/include/itkMetaDataObject.h

Lines changed: 2 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,8 @@ namespace itk
5858
* and redefining the copy constructor and initializing constructor and the Get/Set functions
5959
* to work around those deficiencies.
6060
*
61-
* The behavior of the MetaDataObject<Type>::Print() function has many plausible
62-
* application dependent implementations. The default implementation prints the
63-
* string "[UNKNOWN PRINT CHARACTERISTICS]" that works for all possible
64-
* MetaDataObject types.
65-
*
66-
* The application developer may overload the default implementation to provide
67-
* a specialized Print() characteristics to produce results desirable for their application.
68-
* A set of very crude Macros {NATIVE_TYPE_METADATAPRINT, ITK_OBJECT_TYPE_METADATAPRINT_1COMMA,
69-
* ITK_IMAGE_TYPE_METADATAPRINT } are provided to facilitate a very simple implementation, and as an example.
61+
* The default implementation prints uses the MetaDataObjectType's Print or operator<< if available. Otherwise, it
62+
* prints string "[UNKNOWN PRINT CHARACTERISTICS]".
7063
*
7164
* \ingroup ITKCommon
7265
*
@@ -264,52 +257,6 @@ ExposeMetaData(const MetaDataDictionary & Dictionary, const std::string key, T &
264257

265258
} // end namespace itk
266259

267-
/**
268-
* \def ITK_NATIVE_TYPE_METADATAPRINT( TYPE_NAME )
269-
* \brief An ugly macro to facilitate creating a simple implementation of
270-
* the MetaDataObject<Type>::Print() function for types that
271-
* have operator<< defined.
272-
* \param TYPE_NAME the native type parameter type
273-
*/
274-
#define ITK_NATIVE_TYPE_METADATAPRINT(TYPE_NAME) \
275-
template <> \
276-
void itk::MetaDataObject<TYPE_NAME>::Print(std::ostream & os) const \
277-
{ \
278-
os << this->m_MetaDataObjectValue << std::endl; \
279-
}
280-
281-
/**
282-
* \def ITK_OBJECT_TYPE_METADATAPRINT_1COMMA( TYPE_NAME_PART1, TYPE_NAME_PART2 )
283-
* \brief An ugly macro to facilitate creating a simple implementation of
284-
* the MetaDataObject< Type >::Print() function for
285-
* itk::Objects that have 1 comma in their type definition
286-
* \param TYPE_NAME_PART1
287-
* \param TYPE_NAME_PART2
288-
*/
289-
#define ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(TYPE_NAME_PART1, TYPE_NAME_PART2) \
290-
template <> \
291-
void itk::MetaDataObject<TYPE_NAME_PART1, TYPE_NAME_PART2>::Print(std::ostream & os) const \
292-
{ \
293-
this->m_MetaDataObjectValue->Print(os); \
294-
}
295-
296-
/**
297-
* \def ITK_IMAGE_TYPE_METADATAPRINT( STORAGE_TYPE )
298-
* An ugly macro to facilitate creating a simple implementation of
299-
* the MetaDataObject<Type>::Print() function for
300-
* itk::Image\<STORAGE_TYPE,[1-8]\>\::Pointer
301-
* \param STORAGE_TYPE The storage type of the image type to print.
302-
*/
303-
#define ITK_IMAGE_TYPE_METADATAPRINT(STORAGE_TYPE) \
304-
ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image<STORAGE_TYPE, 1>::Pointer) \
305-
ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image<STORAGE_TYPE, 2>::Pointer) \
306-
ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image<STORAGE_TYPE, 3>::Pointer) \
307-
ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image<STORAGE_TYPE, 4>::Pointer) \
308-
ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image<STORAGE_TYPE, 5>::Pointer) \
309-
ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image<STORAGE_TYPE, 6>::Pointer) \
310-
ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image<STORAGE_TYPE, 7>::Pointer) \
311-
ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image<STORAGE_TYPE, 8>::Pointer)
312-
313260
#ifndef ITK_MANUAL_INSTANTIATION
314261
# include "itkMetaDataObject.hxx"
315262
#endif

Modules/Core/Common/include/itkMetaDataObject.hxx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,45 @@ MetaDataObject<MetaDataObjectType>::SetMetaDataObjectValue(const MetaDataObjectT
5959
Self::Assign(m_MetaDataObjectValue, newValue);
6060
}
6161

62+
namespace
63+
{
64+
template <class T, class = void>
65+
struct has_Print : std::false_type
66+
{};
67+
68+
template <class T>
69+
struct has_Print<T, std::void_t<decltype(std::declval<T>().Print(std::declval<std::ostream &>()))>> : std::true_type
70+
{};
71+
72+
template <class T, class = void>
73+
struct has_output_operator : std::false_type
74+
{};
75+
76+
template <class T>
77+
struct has_output_operator<T, std::void_t<decltype(std::declval<std::ostream &>() << std::declval<T>())>>
78+
: std::true_type
79+
{};
80+
} // namespace
81+
6282
template <typename MetaDataObjectType>
6383
void
6484
MetaDataObject<MetaDataObjectType>::Print(std::ostream & os) const
6585
{
66-
Superclass::Print(os);
86+
// future c++20 feature
87+
// constexpr bool hasPrint = false; requires( const &MetaDataObjectType obj ) { obj.Print(os); };
88+
89+
if constexpr (has_Print<MetaDataObjectType>::value)
90+
{
91+
m_MetaDataObjectValue.Print(os);
92+
}
93+
else if constexpr (has_output_operator<MetaDataObjectType>::value)
94+
{
95+
os << m_MetaDataObjectValue;
96+
}
97+
else
98+
{
99+
Superclass::Print(os);
100+
}
67101
}
68102

69103
} // end namespace itk

Modules/Core/Common/test/itkMetaDataObjectTest.cxx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,12 @@ itkMetaDataObjectTest(int, char *[])
6868
result += testMetaData<float>(-24);
6969
result += testMetaData<double>(-24);
7070
result += testMetaData<std::string>("I T K");
71-
71+
result += testMetaData<std::vector<double>>({ 1.0, 2.0, 3.0 });
72+
result += testMetaData<std::vector<std::vector<double>>>({ { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 } });
73+
result += testMetaData(itk::Array<char>(3, 'I'));
74+
result += testMetaData<itk::Array<double>>(itk::Array<double>(3, 3.0));
75+
result += testMetaData(itk::Matrix<float, 4, 4>());
76+
result += testMetaData<itk::Matrix<double, 3, 3>>(itk::Matrix<double, 3, 3>::GetIdentity());
7277
using ImageType = itk::Image<unsigned short, 3>;
7378
ImageType::Pointer image = nullptr;
7479
result += testMetaData<ImageType::Pointer>(image);

0 commit comments

Comments
 (0)