1 /*=========================================================================
2 *
3 * Copyright Insight Software Consortium
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 * http://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 *
20 * Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21 *
22 * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23 *
24 * For complete copyright, license and disclaimer of warranty information
25 * please refer to the NOTICE file at the top of the ITK source tree.
26 *
27 *=========================================================================*/
28 #ifndef itkMetaDataObject_h
29 #define itkMetaDataObject_h
30
31 #include "itkMetaDataDictionary.h"
32 #include "itkMacro.h"
33 #include "itkArray.h"
34 #include "itkMatrix.h"
35
36 #include <cstring>
37
38 namespace itk
39 {
40 /**
41 * \class MetaDataObject
42 * \brief Allows arbitrary data types to be stored as MetaDataObjectBase types,
43 * and to be stored in a MetaDataDictionary.
44 *
45 * \author Hans J. Johnson
46 *
47 * The MetaDataObject class is a templated class that
48 * is a specialization of the MetaDataObjectBase type.
49 * This class allows arbitrary data types to be
50 * stored as MetaDataObjectBase types, and to be stored in
51 * a MetaDataDictionary.
52 *
53 * Any class or built in type that has valid copy constructor and operator=
54 * can be wrapped directly with this simple template type.
55 *
56 * Classes or built in types that do not have valid copy constructors or operator=
57 * implemented will have to implement those functions by deriving from MetaDataObject<MetaDataObjectType>
58 * and redefining the copy constructor and initializing constructor and the Get/Set functions
59 * to work around those deficiencies.
60 *
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, ITK_IMAGE_TYPE_METADATAPRINT }
69 * are provided to facilitate a very simple implementation, and as an example.
70 * \ingroup ITKCommon
71 */
72 template< typename MetaDataObjectType >
73 class ITK_TEMPLATE_EXPORT MetaDataObject:public MetaDataObjectBase
74 {
75 public:
76 ITK_DISALLOW_COPY_AND_ASSIGN(MetaDataObject);
77
78 /** Smart pointer type alias support */
79 using Self = MetaDataObject;
80 using Superclass = MetaDataObjectBase;
81 using Pointer = SmartPointer< Self >;
82 using ConstPointer = SmartPointer< const Self >;
83
84 /** Method for creation through the object factory. */
85 itkFactorylessNewMacro(Self);
86
87 /** Run-time type information (and related methods). */
88 itkTypeMacro(MetaDataObject, MetaDataObjectBase);
89
90 /**
91 * The definition of this function is necessary to fulfill
92 * the interface of the MetaDataObjectBase
93 * \author Hans J. Johnson
94 * \return A pointer to a const char array containing the unique type name.
95 */
96 const char * GetMetaDataObjectTypeName() const override;
97
98 /**
99 * The definition of this function is necessary to fulfill
100 * the interface of the MetaDataObjectBase
101 * \author Hans J. Johnson
102 * \return A constant reference to a std::type_info object
103 */
104 const std::type_info & GetMetaDataObjectTypeInfo() const override;
105
106 /**
107 * Function to return the stored value of type MetaDataObjectType.
108 * \author Hans J. Johnson
109 * \return a constant reference to a MetaDataObjectType
110 */
111 const MetaDataObjectType & GetMetaDataObjectValue() const;
112
113 /**
114 * Function to set the stored value of type MetaDataObjectType.
115 * \author Hans J. Johnson
116 * \param newValue A constant reference to at MetaDataObjectType.
117 */
118 void SetMetaDataObjectValue(const MetaDataObjectType & newValue);
119
120 /**
121 * Defines the default behavior for printing out this element
122 * \param os An output stream
123 */
124 void Print(std::ostream & os) const override;
125
126 protected:
127 MetaDataObject() = default;
128 ~MetaDataObject() override = default;
129
130 private:
131 /**
132 * A variable to store this derived type.
133 * \author Hans J. Johnson
134 */
135 MetaDataObjectType m_MetaDataObjectValue;
136 };
137
138 /**
139 * EncapsulateMetaData is a convenience function that encapsulates raw MetaData into a
140 * MetaDataObject that can be put into the MetaDataDictionary.
141 * \param Dictionary TODO
142 * \param key TODO
143 * \param invalue the value of type T that is to be encapsulated.
144 * \return A smartpointer ot a MetaDataObject that is suitable for
145 * insertion into a MetaDataDictionary.
146 */
147 template< typename T >
EncapsulateMetaData(MetaDataDictionary & Dictionary,const std::string & key,const T & invalue)148 inline void EncapsulateMetaData(MetaDataDictionary & Dictionary, const std::string & key, const T & invalue)
149 {
150 typename MetaDataObject< T >::Pointer temp = MetaDataObject< T >::New();
151 temp->SetMetaDataObjectValue(invalue);
152 Dictionary[key] = temp;
153 }
154
155 template< typename T >
EncapsulateMetaData(MetaDataDictionary & Dictionary,const char * key,const T & invalue)156 inline void EncapsulateMetaData(MetaDataDictionary & Dictionary, const char *key, const T & invalue)
157 {
158 EncapsulateMetaData(Dictionary, std::string(key), invalue);
159 }
160
161 /**
162 * ExposeMetaData provides a shortcut for pulling a value of type
163 * T out of a MetaDataDictionary.
164 * If Dictionary[key] isn't set, return false, otherwise copy into
165 * outval reference and return true.
166 * \param Dictionary -- reference to a dictionary
167 * \param key -- string identifier for this object
168 * \param outval -- where to store value found in table.
169 */
170 template< typename T >
ExposeMetaData(const MetaDataDictionary & Dictionary,const std::string key,T & outval)171 inline bool ExposeMetaData(const MetaDataDictionary & Dictionary, const std::string key, T & outval)
172 {
173 auto keyIter = Dictionary.Find(key);
174 if ( keyIter == Dictionary.End() )
175 {
176 return false;
177 }
178
179 auto const * const TempMetaDataObject = dynamic_cast< MetaDataObject< T > const * >( keyIter->second.GetPointer() );
180 if ( TempMetaDataObject == nullptr )
181 {
182 return false;
183 }
184
185 outval = TempMetaDataObject->GetMetaDataObjectValue();
186 return true;
187 }
188
189 } // end namespace itk
190
191 /**
192 * \def ITK_NATIVE_TYPE_METADATAPRINT( TYPE_NAME )
193 * \brief An ugly macro to facilitate creating a simple implementation of
194 * the MetaDataObject<Type>::Print() function for types that
195 * have operator<< defined.
196 * \param TYPE_NAME the native type parameter type
197 */
198 #define ITK_NATIVE_TYPE_METADATAPRINT(TYPE_NAME) \
199 template< > \
200 void \
201 ::itk::MetaDataObject< TYPE_NAME > \
202 ::Print(std::ostream & os) const \
203 { \
204 os << this->m_MetaDataObjectValue << std::endl; \
205 } \
206
207 /**
208 * \def ITK_OBJECT_TYPE_METADATAPRINT_1COMMA( TYPE_NAME_PART1, TYPE_NAME_PART2 )
209 * \brief An ugly macro to facilitate creating a simple implementation of
210 * the MetaDataObject< Type >::Print() function for
211 * itk::Objects that have 1 comma in their type definition
212 * \param TYPE_NAME_PART1
213 * \param TYPE_NAME_PART2
214 */
215 #define ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(TYPE_NAME_PART1, TYPE_NAME_PART2) \
216 template< > \
217 void \
218 itk::MetaDataObject< TYPE_NAME_PART1, TYPE_NAME_PART2 > \
219 ::Print(std::ostream & os) const \
220 { \
221 this->m_MetaDataObjectValue->Print(os); \
222 } \
223
224 /**
225 * \def ITK_IMAGE_TYPE_METADATAPRINT( STORAGE_TYPE )
226 * An ugly macro to facilitate creating a simple implementation of
227 * the MetaDataObject<Type>::Print() function for
228 * itk::Image\<STORAGE_TYPE,[1-8]\>\::Pointer
229 * \param STORAGE_TYPE The storage type of the image type to print.
230 */
231 #define ITK_IMAGE_TYPE_METADATAPRINT(STORAGE_TYPE) \
232 ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 1 >::Pointer) \
233 ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 2 >::Pointer) \
234 ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 3 >::Pointer) \
235 ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 4 >::Pointer) \
236 ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 5 >::Pointer) \
237 ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 6 >::Pointer) \
238 ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 7 >::Pointer) \
239 ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 8 >::Pointer) \
240
241 #ifndef ITK_MANUAL_INSTANTIATION
242 #include "itkMetaDataObject.hxx"
243 #endif
244
245 #endif //itkMetaDataObject_h
246
247 /** Explicit instantiations */
248 #ifndef ITK_TEMPLATE_EXPLICIT_MetaDataObject
249 // Explicit instantiation is required to ensure correct dynamic_cast
250 // behavior across shared libraries.
251 //
252 // IMPORTANT: Since within the same compilation unit,
253 // ITK_TEMPLATE_EXPLICIT_<classname> defined and undefined states
254 // need to be considered. This code *MUST* be *OUTSIDE* the header
255 // guards.
256 //
257 # if defined( ITKCommon_EXPORTS )
258 // We are building this library
259 # define ITKCommon_EXPORT_EXPLICIT ITK_TEMPLATE_EXPORT
260 # else
261 // We are using this library
262 # define ITKCommon_EXPORT_EXPLICIT ITKCommon_EXPORT
263 # endif
264 namespace itk
265 {
266
267 ITK_GCC_PRAGMA_DIAG_PUSH()
268 ITK_GCC_PRAGMA_DIAG(ignored "-Wattributes")
269
270 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< bool >;
271 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< unsigned char >;
272 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< char >;
273 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< signed char >;
274 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< unsigned short >;
275 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< short >;
276 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< unsigned int >;
277 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< int >;
278 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< unsigned long >;
279 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< long >;
280 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< unsigned long long >;
281 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< long long >;
282 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< float >;
283 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< double >;
284 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< std::string >;
285 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< std::vector<float> >;
286 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< std::vector<double> >;
287 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< std::vector<std::vector<float> > >;
288 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< std::vector<std::vector<double> > >;
289 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< Array<char> >;
290 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< Array<int> >;
291 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< Array<float> >;
292 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< Array<double> >;
293 extern template class ITKCommon_EXPORT_EXPLICIT MetaDataObject< Matrix<double> >;
294
295 ITK_GCC_PRAGMA_DIAG_POP()
296
297 } // end namespace itk
298 # undef ITKCommon_EXPORT_EXPLICIT
299 #endif
300