Data Access Library (DAL)
/home/amesfoort/DAL/dal/hdf5/types/h5typemap.h
00001 /* Copyright 2011-2012  ASTRON, Netherlands Institute for Radio Astronomy
00002  * This file is part of the Data Access Library (DAL).
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either 
00007  * version 3 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public 
00015  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #ifndef DAL_H5TYPEMAP_H
00018 #define DAL_H5TYPEMAP_H
00019 
00020 #include <hdf5.h>
00021 #include "hid_gc.h"
00022 #include "h5complex.h"
00023 #include "h5tuple.h"
00024 #include "isderivedfrom.h"
00025 
00026 namespace dal {
00027 
00034 /* As C++ does not allow us to specialise T as a class in general, that
00035  * implementation will actually be the default one, specified further down.
00036  * 
00037  * We only define its existence here.
00038  */
00039 template<typename T> struct h5typemap;
00040 
00041 /*
00042  * Specialisations for specific types.
00043  */
00044 
00045 template<> struct h5typemap<float> {
00046   static inline hid_t memoryType()               { return H5T_NATIVE_FLOAT; }
00047   static inline hid_t attributeType()            { return H5T_IEEE_F32LE;   }
00048   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_IEEE_F32BE : H5T_IEEE_F32LE; }
00049 };
00050 
00051 template<> struct h5typemap<double> {
00052   static inline hid_t memoryType()               { return H5T_NATIVE_DOUBLE; }
00053   static inline hid_t attributeType()            { return H5T_IEEE_F64LE;    }
00054   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_IEEE_F64BE : H5T_IEEE_F64LE; }
00055 };
00056 
00057 template<> struct h5typemap<unsigned> {
00058   static inline hid_t memoryType()               { return H5T_NATIVE_UINT; }
00059   static inline hid_t attributeType()            { return H5T_STD_U32LE;   }
00060   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_U32BE : H5T_STD_U32LE; }
00061 };
00062 
00063 template<> struct h5typemap<int> {
00064   static inline hid_t memoryType()               { return H5T_NATIVE_INT; }
00065   static inline hid_t attributeType()            { return H5T_STD_I32LE;   }
00066   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_I32BE : H5T_STD_I32LE; }
00067 };
00068 
00069 template<> struct h5typemap<unsigned long> {
00070   static inline hid_t memoryType()               { return H5T_NATIVE_ULONG; }
00071   static inline hid_t attributeType()            { return H5T_STD_U64LE;   }
00072   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_U64BE : H5T_STD_U64LE; }
00073 };
00074 
00075 template<> struct h5typemap<long> {
00076   static inline hid_t memoryType()               { return H5T_NATIVE_LONG; }
00077   static inline hid_t attributeType()            { return H5T_STD_I64LE;   }
00078   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_I64BE : H5T_STD_I64LE; }
00079 };
00080 
00081 template<> struct h5typemap<unsigned long long> {
00082   static inline hid_t memoryType()               { return H5T_NATIVE_ULLONG; }
00083   static inline hid_t attributeType()            { return H5T_STD_U64LE;   }
00084   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_U64BE : H5T_STD_U64LE; }
00085 };
00086 
00087 template<> struct h5typemap<long long> {
00088   static inline hid_t memoryType()               { return H5T_NATIVE_LLONG; }
00089   static inline hid_t attributeType()            { return H5T_STD_I64LE;   }
00090   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_I64BE : H5T_STD_I64LE; }
00091 };
00092 
00093 template<> struct h5typemap<short> {
00094   static inline hid_t memoryType()               { return H5T_NATIVE_SHORT; }
00095   static inline hid_t attributeType()            { return H5T_STD_I16LE;   }
00096   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_I16BE : H5T_STD_I16LE; }
00097 };
00098 
00099 template<> struct h5typemap<unsigned short> {
00100   static inline hid_t memoryType()               { return H5T_NATIVE_USHORT; }
00101   static inline hid_t attributeType()            { return H5T_STD_U16LE;   }
00102   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_U16BE : H5T_STD_U16LE; }
00103 };
00104 
00105 // Not sure what's up with the little/big endian for char.
00106 template<> struct h5typemap<signed char> {
00107   static inline hid_t memoryType()               { return H5T_NATIVE_SCHAR; }
00108   static inline hid_t attributeType()            { return H5T_STD_I8LE;   }
00109   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_I8BE : H5T_STD_I8LE; }
00110 };
00111 
00112 template<> struct h5typemap<unsigned char> {
00113   static inline hid_t memoryType()               { return H5T_NATIVE_UCHAR; }
00114   static inline hid_t attributeType()            { return H5T_STD_U8LE;   }
00115   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_U8BE : H5T_STD_U8LE; }
00116 };
00117 
00118 template<> struct h5typemap<bool> {
00119   static inline hid_t memoryType()               { return sizeof (bool) == 1 ? H5T_NATIVE_CHAR : H5T_NATIVE_INT; } // assumes bool is either a char or an int
00120   static inline hid_t attributeType()            { return H5T_STD_I32LE;   } // emulate a bool as a 32-bit signed integer
00121   static inline hid_t dataType( bool bigEndian ) { return bigEndian ? H5T_STD_I32BE : H5T_STD_I32LE; }
00122 };
00123 
00124 template<typename T> struct h5typemap< std::complex<T> > {
00125   static inline hid_gc memoryType()               { return h5complexType( h5typemap<T>::memoryType() );        }
00126   static inline hid_gc attributeType()            { return h5complexType( h5typemap<T>::attributeType() );     }
00127   static inline hid_gc dataType( bool bigEndian ) { return h5complexType( h5typemap<T>::dataType(bigEndian) ); }
00128 };
00129 
00130 /*
00131  * A proxy class is required to allow switching based on class hierarchy, as direct specialization
00132  * covering subclasses is not possible in C++.
00133  *
00134  * The template parameters are, in order:
00135  *
00136  * T:   The class type for which an h5typemap is derived
00137  * int: 1 if T is (derived from) TupleUntemplated, 0 otherwise
00138  */
00139 
00140 template<typename T, int> struct h5typemap_proxy {
00141   // The default implementation -- empty to trigger compile errors for unsupported types
00142 };
00143 
00144 template<typename T> struct h5typemap_proxy<T,1> {
00145   // The specialisation for TupleUntemplated and subclasses thereof
00146 
00147   static inline hid_gc memoryType()               { return h5tupleType( h5typemap<typename T::type>::memoryType(), T::size() );        }
00148   static inline hid_gc attributeType()            { return h5tupleType( h5typemap<typename T::type>::attributeType(), T::size() );     }
00149   static inline hid_gc dataType( bool bigEndian ) { return h5tupleType( h5typemap<typename T::type>::dataType(bigEndian), T::size() ); }
00150 };
00151 
00152 /*
00153  * The specialisation for classes (types) in general. This needs to be the default (non-specialised version),
00154  * as C++ does not allow us to provide a generic form of template<typename T> and a specialisation for template<class T>.
00155  */
00156 
00157 template<typename T> struct h5typemap {
00161   static inline hid_gc memoryType()               { return proxy::memoryType(); }
00162 
00166   static inline hid_gc attributeType()            { return proxy::attributeType(); }
00167 
00171   static inline hid_gc dataType( bool bigEndian ) { return proxy::dataType(bigEndian); }
00172 
00173 private:  
00174   // Defer calls to the proper specialisation
00175   typedef h5typemap_proxy<T, IsDerivedFrom<T, TupleUntemplated>::Is> proxy;
00176 };
00177 
00178 }
00179 
00180 #endif
00181 
 All Classes Functions Variables Typedefs Friends