Data Access Library (DAL)
|
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