ITK  4.1.0
Insight Segmentation and Registration Toolkit
itkMetaDataObject.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 /*=========================================================================
00019  *
00020  *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
00021  *
00022  *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00023  *
00024  *  For complete copyright, license and disclaimer of warranty information
00025  *  please refer to the NOTICE file at the top of the ITK source tree.
00026  *
00027  *=========================================================================*/
00028 #ifndef __itkMetaDataObject_h
00029 #define __itkMetaDataObject_h
00030 
00031 #include "itkMetaDataDictionary.h"
00032 #include "itkMacro.h"
00033 #include "itkCommand.h"
00034 #include "itkFastMutexLock.h"
00035 
00036 #include <string.h>
00037 #include <cstring>
00038 
00039 namespace itk
00040 {
00073 template< class MetaDataObjectType >
00074 class ITK_EXPORT MetaDataObject:public MetaDataObjectBase
00075 {
00076 public:
00077 
00079   typedef MetaDataObject             Self;
00080   typedef MetaDataObjectBase         Superclass;
00081   typedef SmartPointer< Self >       Pointer;
00082   typedef SmartPointer< const Self > ConstPointer;
00083 
00085   itkFactorylessNewMacro(Self);
00086 
00088   itkTypeMacro(MetaDataObject, MetaDataObjectBase);
00089 
00094   MetaDataObject(void);
00095 
00099   virtual ~MetaDataObject(void);
00100 
00105   MetaDataObject(const MetaDataObjectType InitializerValue);
00106 
00111   MetaDataObject(const MetaDataObject< MetaDataObjectType > & TemplateObject);
00112 
00120   virtual const char * GetMetaDataObjectTypeName(void) const;
00121 
00129   virtual const std::type_info & GetMetaDataObjectTypeInfo(void) const;
00130 
00136   const MetaDataObjectType & GetMetaDataObjectValue(void) const;
00137 
00143   void SetMetaDataObjectValue(const MetaDataObjectType & NewValue);
00144 
00149   virtual void Print(std::ostream & os) const;
00150 
00151 private:
00152   //This is made private to force the use of the
00153   // MetaDataObject<MetaDataObjectType>::New() operator!
00154   //void * operator new(SizeValueType nothing) {};//purposefully not implemented
00159   MetaDataObjectType m_MetaDataObjectValue;
00160 };
00161 
00171 template< class T >
00172 inline void EncapsulateMetaData(MetaDataDictionary & Dictionary, const std::string & key, const T & invalue)
00173 {
00174   typename MetaDataObject< T >::Pointer temp = MetaDataObject< T >::New();
00175   temp->SetMetaDataObjectValue(invalue);
00176   Dictionary[key] = temp;
00177 }
00179 
00180 template< class T >
00181 inline void EncapsulateMetaData(MetaDataDictionary & Dictionary, const char *key, const T & invalue)
00182 {
00183   EncapsulateMetaData(Dictionary, std::string(key), invalue);
00184 }
00185 
00195 template< class T >
00196 inline bool ExposeMetaData(MetaDataDictionary & Dictionary, const std::string key, T & outval)
00197 {
00198   if ( !Dictionary.HasKey(key) )
00199     {
00200     return false;
00201     }
00202 
00203   MetaDataObjectBase::Pointer baseObjectSmartPointer = Dictionary[key];
00204 
00205   if ( strcmp( typeid( T ).name(), baseObjectSmartPointer->GetMetaDataObjectTypeName() ) != 0 )
00206     {
00207     return false;
00208     }
00209     {
00210     if ( MetaDataObject< T > *TempMetaDataObject = dynamic_cast< MetaDataObject< T > * >( Dictionary[key].GetPointer() ) )
00211       {
00212       outval = TempMetaDataObject->GetMetaDataObjectValue();
00213       }
00214     else
00215       {
00216       return false;
00217       }
00218     }
00219   return true;
00220 }
00221 
00222 // This should not change the behavior, it just adds an extra level of complexity
00223 // to using the ExposeMetaData with const char * keys.
00224 template< class T >
00225 inline bool ExposeMetaData(MetaDataDictionary & Dictionary, const char *const key, T & outval)
00226 {
00227   return ExposeMetaData(Dictionary, std::string(key), outval);
00228 }
00229 
00230 // const versions of ExposeMetaData just to make life easier for enduser
00231 // programmers, and to maintain backwards compatibility.
00232 // The other option is to cast away constness in the main function.
00233 template< class T >
00234 inline bool ExposeMetaData(const MetaDataDictionary & Dictionary, const std::string key, T & outval)
00235 {
00236   MetaDataDictionary NonConstVersion = Dictionary;
00237 
00238   return ExposeMetaData(NonConstVersion, key, outval);
00239 }
00240 
00241 template< class T >
00242 inline bool ExposeMetaData(const MetaDataDictionary & Dictionary, const char *const key, T & outval)
00243 {
00244   MetaDataDictionary NonConstVersion = Dictionary;
00245 
00246   return ExposeMetaData(Dictionary, std::string(key), outval);
00247 }
00248 } // end namespace itk
00249 
00257 #define NATIVE_TYPE_METADATAPRINT(TYPE_NAME)        \
00258   template< >                                       \
00259   void                                              \
00260   itk::MetaDataObject< TYPE_NAME >                  \
00261   ::Print(std::ostream & os) const                  \
00262     {                                               \
00263     os << this->m_MetaDataObjectValue << std::endl; \
00264     }                                               \
00265   template< >                                       \
00266   void                                              \
00267   itk::MetaDataObject< const TYPE_NAME >            \
00268   ::Print(std::ostream & os) const                  \
00269     {                                               \
00270     os << this->m_MetaDataObjectValue << std::endl; \
00271     }
00272 
00273 
00282 #define ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(TYPE_NAME_PART1, TYPE_NAME_PART2) \
00283   template< >                                                                  \
00284   void                                                                         \
00285   itk::MetaDataObject< TYPE_NAME_PART1, TYPE_NAME_PART2 >                      \
00286   ::Print(std::ostream & os) const                                             \
00287     {                                                                          \
00288     this->m_MetaDataObjectValue->Print(os);                                    \
00289     }                                                                          \
00290   template< >                                                                  \
00291   void                                                                         \
00292   itk::MetaDataObject< const TYPE_NAME_PART1, TYPE_NAME_PART2 >                \
00293   ::Print(std::ostream & os) const                                             \
00294     {                                                                          \
00295     this->m_MetaDataObjectValue->Print(os);                                    \
00296     }
00297 
00298 
00306 #define ITK_IMAGE_TYPE_METADATAPRINT(STORAGE_TYPE)                             \
00307   ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 1 >::Pointer) \
00308   ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 2 >::Pointer) \
00309   ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 3 >::Pointer) \
00310   ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 4 >::Pointer) \
00311   ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 5 >::Pointer) \
00312   ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 6 >::Pointer) \
00313   ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 7 >::Pointer) \
00314   ITK_OBJECT_TYPE_METADATAPRINT_1COMMA(itk::Image< STORAGE_TYPE, 8 >::Pointer) \
00315 
00316 #if 0
00317 // Define a specialization of the Print function
00318 // for some basic types. We don't use the initial
00319 // NATIVE_TYPE_METADATAPRINT macro because it lacks
00320 // the inline keyword and it tries to specialize
00321 // for const types which does not compile on MSVC
00322 #define NATIVE_TYPE_METADATAPRINT_NOCONST(TYPE_NAME) \
00323   template< >                                        \
00324   inline void itk::MetaDataObject< TYPE_NAME >       \
00325   ::Print(std::ostream & os) const                   \
00326     {                                                \
00327     os << this->m_MetaDataObjectValue << std::endl;  \
00328     }
00329 
00330 NATIVE_TYPE_METADATAPRINT_NOCONST(unsigned char)
00331 NATIVE_TYPE_METADATAPRINT_NOCONST(short)
00332 NATIVE_TYPE_METADATAPRINT_NOCONST(unsigned short)
00333 NATIVE_TYPE_METADATAPRINT_NOCONST(int)
00334 NATIVE_TYPE_METADATAPRINT_NOCONST(unsigned int)
00335 NATIVE_TYPE_METADATAPRINT_NOCONST(long)
00336 NATIVE_TYPE_METADATAPRINT_NOCONST(unsigned long)
00337 NATIVE_TYPE_METADATAPRINT_NOCONST(float)
00338 NATIVE_TYPE_METADATAPRINT_NOCONST(double)
00339 NATIVE_TYPE_METADATAPRINT_NOCONST(std::string)
00340 
00341 // undef the macro to clean up things
00342 #undef NATIVE_TYPE_METADATAPRINT_NOCONST
00343 #endif
00344 
00345 // Define instantiation macro for this template.
00346 #define ITK_TEMPLATE_MetaDataObject(_, EXPORT, TypeX, TypeY)     \
00347   namespace itk                                                  \
00348   {                                                              \
00349   _( 1 ( class EXPORT MetaDataObject< ITK_TEMPLATE_1 TypeX > ) ) \
00350   namespace Templates                                            \
00351   {                                                              \
00352   typedef MetaDataObject< ITK_TEMPLATE_1 TypeX >                 \
00353   MetaDataObject##TypeY;                                       \
00354   }                                                              \
00355   }
00356 
00357 #if ITK_TEMPLATE_EXPLICIT
00358 #include "Templates/itkMetaDataObject+-.h"
00359 #endif
00360 
00361 #if ITK_TEMPLATE_TXX
00362 #include "itkMetaDataObject.hxx"
00363 #endif
00364 
00365 #endif //itkMetaDataObject_h
00366