creating hdf5 datatypes at compile-time?

Hello all,

I am currently trying to implement a function in C++ that stores a multi-dimensional array to hdf5 whose C++- type is given by a template parameter at compile time. Ideally, I would determine the corresponding hdf5 datatype during compilation using a template meta-program. However, I haven't been able to get this to work using the predefined types (i.e. H5T_STD_U32LE) (I get the error "expected constant expression"), and after reading more about the hdf5 datatype concept, I am not sure if the compile time approach is at all possible. Is there an elegant generic solution to this problem?

Thanks!

Regards,

Patrick

···

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

Hi Patrick,

  the HDF5 predefined types like H5T_STD_U32LE are actually function calls,
not static #defines. You would need to build up your template metaprogramm
such that it at compile time builds a function that builds the required type
at runtime.

To avoid building a type that was alread build, you might need something
like a type registry, which maps C++ native type ID's to HDF5 ID's and
vice versa. If you also intend to store named types in a file, then you
might have multipe HDF5 ID's for one C++ typeid.

Cheers,

  Werner

···

On Mon, 18 May 2009 16:18:21 -0500, Patrick <jazzcat81@hotmail.com> wrote:

Hello all,

I am currently trying to implement a function in C++ that stores a multi-dimensional array to hdf5 whose C++- type is given by a template parameter at compile time. Ideally, I would determine the corresponding hdf5 datatype during compilation using a template meta-program. However, I haven't been able to get this to work using the predefined types (i.e. H5T_STD_U32LE) (I get the error "expected constant expression"), and after reading more about the hdf5 datatype concept, I am not sure if the compile time approach is at all possible. Is there an elegant generic solution to this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--
___________________________________________________________________________
Dr. Werner Benger <werner@cct.lsu.edu> Visualization Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University (CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

I'm not sure that this answers your need. I want to have templated code
that will handle storage of various types, so I don't have to have a
function for float, one for double, one for int, etc. This is my
solution.

I won't claim that it is elegant, but it works for me. The key is the
C++ typeid feature. It can give you a unique text name for any given
type.

std::map< std::string, H5::DataType> H5TypeMap;

H5TypeMap h5_type_map_;

h5_type_map_[ typeid(float).name() ] = PredType::NATIVE_FLOAT;
h5_type_map_[ typeid(double).name() ] = PredType::NATIVE_DOUBLE;
h5_type_map_[ typeid(int32_t).name() ] = PredType::NATIVE_INT32;
// ... etc.

template<typename T>
H5::DataType getH5Type( T parameter )const
{
  const char * type_name = typeid( parameter ).name();
  H5TypeMap::const_iterator i = h5_type_map_.find( type_name );
  if ( i == h5_type_map_.end() )
  {
    // throw exception
  }
  else
  {
        return i->second;
  }
}

George Lewandowski
(314)777-7890
Mail Code S270-2204
Building 270-E Level 2E Room 20E
P-8A

···

-----Original Message-----
From: Patrick [mailto:jazzcat81@hotmail.com]
Sent: Monday, May 18, 2009 4:18 PM
To: hdf-forum
Subject: [hdf-forum] Re: creating hdf5 datatypes at compile-time?

Hello all,

I am currently trying to implement a function in C++ that stores a
multi-dimensional array to hdf5 whose C++- type is given by a template
parameter at compile time. Ideally, I would determine the corresponding
hdf5 datatype during compilation using a template meta-program. However,
I haven't been able to get this to work using the predefined types (i.e.

H5T_STD_U32LE) (I get the error "expected constant expression"), and
after reading more about the hdf5 datatype concept, I am not sure if the
compile time approach is at all possible. Is there an elegant generic
solution to this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

Cool enough, you found pretty much the same solution as I'm using...

As one more small optimization - you don't need to go via strings, because the
native C++ typeid already supports a comparision between typeid's via its before()
member function. All what is required is a some proxy class, and you can directly
map typeid's to arbitrary data types (I tend to call this a "typemap").

Cheers,
  Werner

class TypeInfo
{
         const type_info&TypeID;

public:
         /// Constructor
         TypeInfo(const type_info&Id)
         : TypeID(Id)
         {}

         /// The comparision operator
         bool operator<(const TypeInfo&T) const
         {
                 return TypeID.before( T.TypeID ) != 0;
         }
};

template <class T>
class typemap : public std::map<TypeInfo, T>
{
public:

};

···

On Mon, 18 May 2009 16:34:55 -0500, Lewandowski, George <george.lewandowski@boeing.com> wrote:

I'm not sure that this answers your need. I want to have templated code
that will handle storage of various types, so I don't have to have a
function for float, one for double, one for int, etc. This is my
solution.

I won't claim that it is elegant, but it works for me. The key is the
C++ typeid feature. It can give you a unique text name for any given
type.

std::map< std::string, H5::DataType> H5TypeMap;

H5TypeMap h5_type_map_;

h5_type_map_[ typeid(float).name() ] = PredType::NATIVE_FLOAT;
h5_type_map_[ typeid(double).name() ] = PredType::NATIVE_DOUBLE;
h5_type_map_[ typeid(int32_t).name() ] = PredType::NATIVE_INT32;
// ... etc.

template<typename T>
H5::DataType getH5Type( T parameter )const
{
  const char * type_name = typeid( parameter ).name();
  H5TypeMap::const_iterator i = h5_type_map_.find( type_name );
  if ( i == h5_type_map_.end() )
  {
    // throw exception
  }
  else
  {
        return i->second;
  }
}

George Lewandowski
(314)777-7890
Mail Code S270-2204
Building 270-E Level 2E Room 20E
P-8A

-----Original Message-----
From: Patrick [mailto:jazzcat81@hotmail.com]
Sent: Monday, May 18, 2009 4:18 PM
To: hdf-forum
Subject: [hdf-forum] Re: creating hdf5 datatypes at compile-time?

Hello all,

I am currently trying to implement a function in C++ that stores a
multi-dimensional array to hdf5 whose C++- type is given by a template
parameter at compile time. Ideally, I would determine the corresponding
hdf5 datatype during compilation using a template meta-program. However,
I haven't been able to get this to work using the predefined types (i.e.

H5T_STD_U32LE) (I get the error "expected constant expression"), and
after reading more about the hdf5 datatype concept, I am not sure if the
compile time approach is at all possible. Is there an elegant generic
solution to this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--
___________________________________________________________________________
Dr. Werner Benger <werner@cct.lsu.edu> Visualization Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University (CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

/**
* @brief Given one of the HDF Types as a string, this will return the HDF Type
* as an hid_t value.
* @param value The HDF_Type as a string
* @return the hid_t value for the given type. -1 if the string does
not match a type.
*/
static hid_t HDFTypeFromString(const std::string &value)
{
  if (value.compare("H5T_NATIVE_INT8") == 0) return H5T_NATIVE_INT8;
  if (value.compare("H5T_NATIVE_UINT8") == 0) return H5T_NATIVE_UINT8;

  if (value.compare("H5T_NATIVE_INT16") == 0) return H5T_NATIVE_INT16;
  if (value.compare("H5T_NATIVE_UINT16") == 0) return H5T_NATIVE_UINT16;

  if (value.compare("H5T_NATIVE_INT32") == 0) return H5T_NATIVE_INT32;
  if (value.compare("H5T_NATIVE_UINT32") == 0) return H5T_NATIVE_UINT32;

  if (value.compare("H5T_NATIVE_INT64") == 0) return H5T_NATIVE_INT64;
  if (value.compare("H5T_NATIVE_UINT64") == 0) return H5T_NATIVE_UINT64;

  if (value.compare("H5T_NATIVE_FLOAT") == 0) return H5T_NATIVE_FLOAT;
  if (value.compare("H5T_NATIVE_DOUBLE") == 0) return H5T_NATIVE_DOUBLE;

  if (value.compare("H5T_STRING") == 0) return H5T_STRING;

  std::cout << DEBUG_OUT(logTime) << "Error: HDFTypeFromString -
Unknown Type: " << value << std::endl;
  return -1;
}

/**
* @brief Returns a string version of the HDF Type
* @param type The HDF5 Type to query
* @return
*/
static std::string StringForHDFType(hid_t type)
{
  if (H5Tequal(type ,H5T_NATIVE_INT8) ) return "H5T_NATIVE_INT8";
  if (H5Tequal(type ,H5T_NATIVE_UINT8) ) return "H5T_NATIVE_UINT8";

  if (H5Tequal(type ,H5T_NATIVE_INT16) ) return "H5T_NATIVE_INT16";
  if (H5Tequal(type ,H5T_NATIVE_UINT16) ) return "H5T_NATIVE_UINT16";

  if (H5Tequal(type ,H5T_NATIVE_INT32) ) return "H5T_NATIVE_INT32";
  if (H5Tequal(type ,H5T_NATIVE_UINT32) ) return "H5T_NATIVE_UINT32";

  if (H5Tequal(type ,H5T_NATIVE_INT64) ) return "H5T_NATIVE_INT64";
  if (H5Tequal(type ,H5T_NATIVE_UINT64) ) return "H5T_NATIVE_UINT64";

  if (H5Tequal(type ,H5T_NATIVE_FLOAT) ) return "H5T_NATIVE_FLOAT";
  if (H5Tequal(type ,H5T_NATIVE_DOUBLE) ) return "H5T_NATIVE_DOUBLE";

  if ( type == H5T_STRING) return "H5T_STRING";

  std::cout << DEBUG_OUT(logTime) << "Error: HDFTypeForPrimitiveAsStr
- Unknown Type: " << std::endl;
  return "Unknown";
}

/**
* @brief Returns the HDF Type for a given primitive value.
* @param value A value to use. Can be anything. Just used to get the type info
* from
* @return A std::string representing the HDF5 Type
*/
template<typename T>
static std::string HDFTypeForPrimitiveAsStr(T value)
{
  if (typeid(value) == typeid(int8)) return "H5T_NATIVE_INT8";
  if (typeid(value) == typeid(uint8)) return "H5T_NATIVE_UINT8";

  if (typeid(value) == typeid(int16)) return "H5T_NATIVE_INT16";
  if (typeid(value) == typeid(uint16)) return "H5T_NATIVE_UINT16";

  if (typeid(value) == typeid(int32)) return "H5T_NATIVE_INT32";
  if (typeid(value) == typeid(uint32)) return "H5T_NATIVE_UINT32";

  if (typeid(value) == typeid(int64)) return "H5T_NATIVE_INT64";
  if (typeid(value) == typeid(uint64)) return "H5T_NATIVE_UINT64";

  if (typeid(value) == typeid(float32)) return "H5T_NATIVE_FLOAT";
  if (typeid(value) == typeid(float64)) return "H5T_NATIVE_DOUBLE";

  //if (typeid(value) == typeid(bool)) return "H5T_NATIVE_UINT8";

  std::cout << DEBUG_OUT(logTime) << "Error: HDFTypeForPrimitiveAsStr
- Unknown Type: " << typeid(value).name() << std::endl;
  return "";
}

/**
* @brief Returns the HDF Type for a given primitive value.
* @param value A value to use. Can be anything. Just used to get the type info
* from
* @return The HDF5 native type for the value
*/
template<typename T>
static hid_t HDFTypeForPrimitive(T value)
{

  if (typeid(value) == typeid(float32)) return H5T_NATIVE_FLOAT;
  if (typeid(value) == typeid(float64)) return H5T_NATIVE_DOUBLE;

  if (typeid(value) == typeid(int8)) return H5T_NATIVE_INT8;
  if (typeid(value) == typeid(uint8)) return H5T_NATIVE_UINT8;

  if (typeid(value) == typeid(int16)) return H5T_NATIVE_INT16;
  if (typeid(value) == typeid(uint16)) return H5T_NATIVE_UINT16;

  if (typeid(value) == typeid(int32)) return H5T_NATIVE_INT32;
  if (typeid(value) == typeid(uint32)) return H5T_NATIVE_UINT32;

  if (typeid(value) == typeid(int64)) return H5T_NATIVE_INT64;
  if (typeid(value) == typeid(uint64)) return H5T_NATIVE_UINT64;

  if (typeid(value) == typeid(bool)) return H5T_NATIVE_UINT8;

  std::cout << DEBUG_OUT(logTime) << "Error: HDFTypeForPrimitive -
Unknown Type: " << (typeid(value).name()) << std::endl;
  const char* name = typeid(value).name();
  if (NULL != name && name[0] == 'l' ) {
    std::cout << "You are using 'long int' as a type which is not
32/64 bit safe. Suggest you use one of the MXATypes defined in
<Common/MXATypes.h> such as int32 or uint32." << std::endl;
  }
  return -1;
}

···

On Mon, May 18, 2009 at 5:43 PM, Werner Benger <werner@cct.lsu.edu> wrote:

Cool enough, you found pretty much the same solution as I'm using...

As one more small optimization - you don't need to go via strings, because
the
native C++ typeid already supports a comparision between typeid's via its
before()
member function. All what is required is a some proxy class, and you can
directly
map typeid's to arbitrary data types (I tend to call this a "typemap").

Cheers,
Werner

class TypeInfo
{
const type_info&TypeID;

public:
/// Constructor
TypeInfo(const type_info&Id)
: TypeID(Id)
{}

   /// The comparision operator
   bool operator&lt;\(const TypeInfo&amp;T\) const
   \{
           return TypeID\.before\( T\.TypeID \) \!= 0;
   \}

};

template <class T>
class typemap : public std::map<TypeInfo, T>
{
public:

};

On Mon, 18 May 2009 16:34:55 -0500, Lewandowski, George > <george.lewandowski@boeing.com> wrote:

I'm not sure that this answers your need. I want to have templated code
that will handle storage of various types, so I don't have to have a
function for float, one for double, one for int, etc. This is my
solution.

I won't claim that it is elegant, but it works for me. The key is the
C++ typeid feature. It can give you a unique text name for any given
type.

std::map< std::string, H5::DataType> H5TypeMap;

H5TypeMap h5_type_map_;

h5_type_map_[ typeid(float).name() ] = PredType::NATIVE_FLOAT;
h5_type_map_[ typeid(double).name() ] = PredType::NATIVE_DOUBLE;
h5_type_map_[ typeid(int32_t).name() ] = PredType::NATIVE_INT32;
// ... etc.

template<typename T>
H5::DataType getH5Type( T parameter )const
{
const char * type_name = typeid( parameter ).name();
H5TypeMap::const_iterator i = h5_type_map_.find( type_name );
if ( i == h5_type_map_.end() )
{
// throw exception
}
else
{
return i->second;
}
}

George Lewandowski
(314)777-7890
Mail Code S270-2204
Building 270-E Level 2E Room 20E
P-8A

-----Original Message-----
From: Patrick [mailto:jazzcat81@hotmail.com]
Sent: Monday, May 18, 2009 4:18 PM
To: hdf-forum
Subject: [hdf-forum] Re: creating hdf5 datatypes at compile-time?

Hello all,

I am currently trying to implement a function in C++ that stores a
multi-dimensional array to hdf5 whose C++- type is given by a template
parameter at compile time. Ideally, I would determine the corresponding
hdf5 datatype during compilation using a template meta-program. However,
I haven't been able to get this to work using the predefined types (i.e.

H5T_STD_U32LE) (I get the error "expected constant expression"), and
after reading more about the hdf5 datatype concept, I am not sure if the
compile time approach is at all possible. Is there an elegant generic
solution to this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--
___________________________________________________________________________
Dr. Werner Benger <werner@cct.lsu.edu> Visualization Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University (CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

http://www.bluequartz.net/cgi-bin/gitweb/gitweb.cgi?p=MXADataModel.git;a=blob;f=Source/MXA/HDF5/H5Lite.h;h=1e36d91ef7b13b3f02232d99e25cd6be64a759de;hb=HEAD

Cool enough, you found pretty much the same solution as I'm using...

As one more small optimization - you don't need to go via strings, because
the
native C++ typeid already supports a comparision between typeid's via its
before()
member function. All what is required is a some proxy class, and you can
directly
map typeid's to arbitrary data types (I tend to call this a "typemap").

Cheers,
Werner

class TypeInfo
{
const type_info&TypeID;

public:
/// Constructor
TypeInfo(const type_info&Id)
: TypeID(Id)
{}

   /// The comparision operator
   bool operator&lt;\(const TypeInfo&amp;T\) const
   \{
           return TypeID\.before\( T\.TypeID \) \!= 0;
   \}

};

template <class T>
class typemap : public std::map<TypeInfo, T>
{
public:

};

I'm not sure that this answers your need. I want to have templated code
that will handle storage of various types, so I don't have to have a
function for float, one for double, one for int, etc. This is my
solution.

I won't claim that it is elegant, but it works for me. The key is the
C++ typeid feature. It can give you a unique text name for any given
type.

std::map< std::string, H5::DataType> H5TypeMap;

H5TypeMap h5_type_map_;

h5_type_map_[ typeid(float).name() ] = PredType::NATIVE_FLOAT;
h5_type_map_[ typeid(double).name() ] = PredType::NATIVE_DOUBLE;
h5_type_map_[ typeid(int32_t).name() ] = PredType::NATIVE_INT32;
// ... etc.

template<typename T>
H5::DataType getH5Type( T parameter )const
{
const char * type_name = typeid( parameter ).name();
H5TypeMap::const_iterator i = h5_type_map_.find( type_name );
if ( i == h5_type_map_.end() )
{
// throw exception
}
else
{
return i->second;
}
}

George Lewandowski
(314)777-7890
Mail Code S270-2204
Building 270-E Level 2E Room 20E
P-8A

From: Patrick [mailto:jazzcat81@hotmail.com]
Sent: Monday, May 18, 2009 4:18 PM
To: hdf-forum
Subject: [hdf-forum] Re: creating hdf5 datatypes at compile-time?

Hello all,

I am currently trying to implement a function in C++ that stores a
multi-dimensional array to hdf5 whose C++- type is given by a template
parameter at compile time. Ideally, I would determine the corresponding
hdf5 datatype during compilation using a template meta-program. However,
I haven't been able to get this to work using the predefined types (i.e.

H5T_STD_U32LE) (I get the error "expected constant expression"), and
after reading more about the hdf5 datatype concept, I am not sure if the
compile time approach is at all possible. Is there an elegant generic
solution to this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--
___________________________________________________________________________
Dr. Werner Benger <werner@cct.lsu.edu> Visualization Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University (CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

/**
* @brief Given one of the HDF Types as a string, this will return the HDF Type
* as an hid_t value.
* @param value The HDF_Type as a string
* @return the hid_t value for the given type. -1 if the string does
not match a type.
*/
static hid_t HDFTypeFromString(const std::string &value)
{
if (value.compare("H5T_NATIVE_INT8") == 0) return H5T_NATIVE_INT8;
if (value.compare("H5T_NATIVE_UINT8") == 0) return H5T_NATIVE_UINT8;

if (value.compare("H5T_NATIVE_INT16") == 0) return H5T_NATIVE_INT16;
if (value.compare("H5T_NATIVE_UINT16") == 0) return H5T_NATIVE_UINT16;

if (value.compare("H5T_NATIVE_INT32") == 0) return H5T_NATIVE_INT32;
if (value.compare("H5T_NATIVE_UINT32") == 0) return H5T_NATIVE_UINT32;

if (value.compare("H5T_NATIVE_INT64") == 0) return H5T_NATIVE_INT64;
if (value.compare("H5T_NATIVE_UINT64") == 0) return H5T_NATIVE_UINT64;

if (value.compare("H5T_NATIVE_FLOAT") == 0) return H5T_NATIVE_FLOAT;
if (value.compare("H5T_NATIVE_DOUBLE") == 0) return H5T_NATIVE_DOUBLE;

if (value.compare("H5T_STRING") == 0) return H5T_STRING;

std::cout << DEBUG_OUT(logTime) << "Error: HDFTypeFromString -
Unknown Type: " << value << std::endl;
return -1;
}

/**
* @brief Returns a string version of the HDF Type
* @param type The HDF5 Type to query
* @return
*/
static std::string StringForHDFType(hid_t type)
{
if (H5Tequal(type ,H5T_NATIVE_INT8) ) return "H5T_NATIVE_INT8";
if (H5Tequal(type ,H5T_NATIVE_UINT8) ) return "H5T_NATIVE_UINT8";

if (H5Tequal(type ,H5T_NATIVE_INT16) ) return "H5T_NATIVE_INT16";
if (H5Tequal(type ,H5T_NATIVE_UINT16) ) return "H5T_NATIVE_UINT16";

if (H5Tequal(type ,H5T_NATIVE_INT32) ) return "H5T_NATIVE_INT32";
if (H5Tequal(type ,H5T_NATIVE_UINT32) ) return "H5T_NATIVE_UINT32";

if (H5Tequal(type ,H5T_NATIVE_INT64) ) return "H5T_NATIVE_INT64";
if (H5Tequal(type ,H5T_NATIVE_UINT64) ) return "H5T_NATIVE_UINT64";

if (H5Tequal(type ,H5T_NATIVE_FLOAT) ) return "H5T_NATIVE_FLOAT";
if (H5Tequal(type ,H5T_NATIVE_DOUBLE) ) return "H5T_NATIVE_DOUBLE";

if ( type == H5T_STRING) return "H5T_STRING";

std::cout << DEBUG_OUT(logTime) << "Error: HDFTypeForPrimitiveAsStr
- Unknown Type: " << std::endl;
return "Unknown";
}

/**
* @brief Returns the HDF Type for a given primitive value.
* @param value A value to use. Can be anything. Just used to get the type info
* from
* @return A std::string representing the HDF5 Type
*/
template<typename T>
static std::string HDFTypeForPrimitiveAsStr(T value)
{
if (typeid(value) == typeid(int8)) return "H5T_NATIVE_INT8";
if (typeid(value) == typeid(uint8)) return "H5T_NATIVE_UINT8";

if (typeid(value) == typeid(int16)) return "H5T_NATIVE_INT16";
if (typeid(value) == typeid(uint16)) return "H5T_NATIVE_UINT16";

if (typeid(value) == typeid(int32)) return "H5T_NATIVE_INT32";
if (typeid(value) == typeid(uint32)) return "H5T_NATIVE_UINT32";

if (typeid(value) == typeid(int64)) return "H5T_NATIVE_INT64";
if (typeid(value) == typeid(uint64)) return "H5T_NATIVE_UINT64";

if (typeid(value) == typeid(float32)) return "H5T_NATIVE_FLOAT";
if (typeid(value) == typeid(float64)) return "H5T_NATIVE_DOUBLE";

//if (typeid(value) == typeid(bool)) return "H5T_NATIVE_UINT8";

std::cout << DEBUG_OUT(logTime) << "Error: HDFTypeForPrimitiveAsStr
- Unknown Type: " << typeid(value).name() << std::endl;
return "";
}

/**
* @brief Returns the HDF Type for a given primitive value.
* @param value A value to use. Can be anything. Just used to get the type info
* from
* @return The HDF5 native type for the value
*/
template<typename T>
static hid_t HDFTypeForPrimitive(T value)
{

if (typeid(value) == typeid(float32)) return H5T_NATIVE_FLOAT;
if (typeid(value) == typeid(float64)) return H5T_NATIVE_DOUBLE;

if (typeid(value) == typeid(int8)) return H5T_NATIVE_INT8;
if (typeid(value) == typeid(uint8)) return H5T_NATIVE_UINT8;

if (typeid(value) == typeid(int16)) return H5T_NATIVE_INT16;
if (typeid(value) == typeid(uint16)) return H5T_NATIVE_UINT16;

if (typeid(value) == typeid(int32)) return H5T_NATIVE_INT32;
if (typeid(value) == typeid(uint32)) return H5T_NATIVE_UINT32;

if (typeid(value) == typeid(int64)) return H5T_NATIVE_INT64;
if (typeid(value) == typeid(uint64)) return H5T_NATIVE_UINT64;

if (typeid(value) == typeid(bool)) return H5T_NATIVE_UINT8;

std::cout << DEBUG_OUT(logTime) << "Error: HDFTypeForPrimitive -
Unknown Type: " << (typeid(value).name()) << std::endl;
const char* name = typeid(value).name();
if (NULL != name && name[0] == 'l' ) {
std::cout << "You are using 'long int' as a type which is not
32/64 bit safe. Suggest you use one of the MXATypes defined in
<Common/MXATypes.h> such as int32 or uint32." << std::endl;
}
return -1;
}

Also see <http://www.bluequartz.net/cgi-bin/gitweb/gitweb.cgi?p=MXADataModel.git;a=blob;f=Source/MXA/HDF5/H5Lite.h;h=1e36d91ef7b13b3f02232d99e25cd6be64a759de;hb=HEAD>
and the implementation file
<http://www.bluequartz.net/cgi-bin/gitweb/gitweb.cgi?p=MXADataModel.git;a=blob_plain;f=Source/MXA/HDF5/H5Lite.cpp;hb=HEAD>

I ended up doing the same thing as every one else and creating
template functions. Some of the code is used from the normal HDF5
source codes, others I came up with. It is all open source so use any
of it that you would like.

mike jackson

···

On Mon, May 18, 2009 at 7:26 PM, Mike Jackson <mike.jackson@bluequartz.net> wrote:

On Mon, May 18, 2009 at 5:43 PM, Werner Benger <werner@cct.lsu.edu> wrote:

On Mon, 18 May 2009 16:34:55 -0500, Lewandowski, George >> <george.lewandowski@boeing.com> wrote:

-----Original Message-----

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

Hi all,

Hi Patrick,

the HDF5 predefined types like H5T_STD_U32LE are actually function calls,
not static #defines.

  Hmm, they are probably closer to singleton's - initialized to a value via a function call the first time they are executed and then on subsequent executions the function call occurs, but is a no-op and just the value is used.

You would need to build up your template metaprogram
such that it at compile time builds a function that builds the required type
at runtime.

  I've read the later message with template suggestions, which look nice. In case it's useful, it's possible to serialize a more complex datatype with the H5Tencode() routine (and deserialize it with H5Tdecode()).

  Quincey

···

On May 18, 2009, at 4:32 PM, Werner Benger wrote:

To avoid building a type that was alread build, you might need something
like a type registry, which maps C++ native type ID's to HDF5 ID's and
vice versa. If you also intend to store named types in a file, then you
might have multipe HDF5 ID's for one C++ typeid.

Cheers,

  Werner

On Mon, 18 May 2009 16:18:21 -0500, Patrick <jazzcat81@hotmail.com> > wrote:

Hello all,

I am currently trying to implement a function in C++ that stores a multi-dimensional array to hdf5 whose C++- type is given by a template parameter at compile time. Ideally, I would determine the corresponding hdf5 datatype during compilation using a template meta-program. However, I haven't been able to get this to work using the predefined types (i.e. H5T_STD_U32LE) (I get the error "expected constant expression"), and after reading more about the hdf5 datatype concept, I am not sure if the compile time approach is at all possible. Is there an elegant generic solution to this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--
___________________________________________________________________________
Dr. Werner Benger <werner@cct.lsu.edu> Visualization Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University (CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

Hi George,

Lewandowski, George wrote:

I won't claim that it is elegant, but it works for me. The key is the
C++ typeid feature. It can give you a unique text name for any given
type.

std::map< std::string, H5::DataType> H5TypeMap;

H5TypeMap h5_type_map_;

h5_type_map_[ typeid(float).name() ] = PredType::NATIVE_FLOAT;
h5_type_map_[ typeid(double).name() ] = PredType::NATIVE_DOUBLE;
h5_type_map_[ typeid(int32_t).name() ] = PredType::NATIVE_INT32;
// ... etc.
  

[...]

It's not necessary to use the map for the builtin type case:

    template <typename T>
    struct H5TypeMap {
      static hid_t h5_type;
    };

    // add explicit specialization for all required types:
    template <> hid_t H5TypeMap<float>::h5_type = H5T_NATIVE_FLOAT;
    template <> hid_t H5TypeMap<double>::h5_type = H5T_NATIVE_DOUBLE;
    // ...

    template<typename T>
    hid_t getH5Type( T )
    {
      return H5TypeMap<T>::h5_type;
    }

One possible advantage with this approach is that if "getH5Type" is called for a type that does not have a corresponding specialization then there will be a link error because there is no definition for "H5TypeMap<T>::h5_type". In other cases removing the map lookup/chained ifs may result in a performance benefit but it won't affect the above case since this call is probably very rare.

Regards,

Richard

Hi all,

I think the OP' question is related to static typing rather than using RTTI
to select an appropriate type. However the run-time approaches offered here
are maybe more elegant. I guess what would be a solution for the OP is to
create explicit specializations that map atomic or compound types to HDF5
types. To address the OP question, I guess something like the following
would do:

template<class AtomicType> class GenericTable
{
public:
    GenericTable(){}
    ~GenericTable(){}
    virtual void create(){};

    hid_t parent;
    hid_t dataspace;
    std::string name;
};

template<> void GenericTable<int>::create()
{

H5Dcreate(parent,name.c_str(),H5T_NATIVE_INT,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
}

template<> void GenericTable<double>::create()
{

H5Dcreate(parent,name.c_str(),H5T_NATIVE_DOUBLE,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
}

void test()
{
    GenericTable<int> a;
    a.create();
    GenericTable<double> b;
    b.create();
}

But one has to write the specializations. Another way is to create special
wrapper types:

template<class AtomicType> struct HDF5type
{
    static hid_t getType;
};

template<> hid_t HDF5type<int>::getType=H5T_NATIVE_INT;
template<> hid_t HDF5type<double>::getType=H5T_NATIVE_DOUBLE;

template<class AtomicType> class GenericTable2
{
public:
    GenericTable2(){}
    ~GenericTable2(){}
    virtual void create()
    {

H5Dcreate(parent,name.c_str(),HDF5type<AtomicType>::getType,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
    };

    hid_t parent;
    hid_t dataspace;
    std::string name;
};

void test2()
{
    GenericTable2<int> c;
    c.create();
    GenericTable2<double> d;
    d.create();
}

In all cases, macros can be used to assist the definition of the
specializations. I hope that answers the OP's question, however, RTTI
solutions already offered are maybe better. I also had written somewhere a
small HDF5 serialization class for atomic types with reflection but cannot
seem to find it... I was planning to put it in the public domain but then
THG said they'll have a SF project for that, which I do not recall if it
ever came...

HTH

-- ds

···

2009/5/19 Quincey Koziol <koziol@hdfgroup.org>

Hi all,

On May 18, 2009, at 4:32 PM, Werner Benger wrote:

Hi Patrick,

the HDF5 predefined types like H5T_STD_U32LE are actually function calls,
not static #defines.

       Hmm, they are probably closer to singleton's - initialized to a
value via a function call the first time they are executed and then on
subsequent executions the function call occurs, but is a no-op and just the
value is used.

You would need to build up your template metaprogram

such that it at compile time builds a function that builds the required
type
at runtime.

       I've read the later message with template suggestions, which look
nice. In case it's useful, it's possible to serialize a more complex
datatype with the H5Tencode() routine (and deserialize it with H5Tdecode()).

       Quincey

To avoid building a type that was alread build, you might need something

like a type registry, which maps C++ native type ID's to HDF5 ID's and
vice versa. If you also intend to store named types in a file, then you
might have multipe HDF5 ID's for one C++ typeid.

Cheers,

       Werner

On Mon, 18 May 2009 16:18:21 -0500, Patrick <jazzcat81@hotmail.com> >> wrote:

Hello all,

I am currently trying to implement a function in C++ that stores a
multi-dimensional array to hdf5 whose C++- type is given by a template
parameter at compile time. Ideally, I would determine the corresponding hdf5
datatype during compilation using a template meta-program. However, I
haven't been able to get this to work using the predefined types (i.e.
H5T_STD_U32LE) (I get the error "expected constant expression"), and after
reading more about the hdf5 datatype concept, I am not sure if the compile
time approach is at all possible. Is there an elegant generic solution to
this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--

___________________________________________________________________________
Dr. Werner Benger <werner@cct.lsu.edu> Visualization
Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University
(CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

In all cases, macros can be used to assist the definition of the specializations.

Just to round off the contributions here's one I use - a macro followed by a code snippet which calls the macro for each data type. The case statement selects from the relevant VTK data type and the macro instantiates the HDF data type. I never found a really elegant template solution which did it all in go, but I'll be looking at the earlier posts to get ideas.

JB

//----------------------------------------------------------------------------
// A Convenience Macro which does what we want for any dataset type
// note that we use a dummy null parameter and the ## macro operator to delay expansion
// of the T2 parameter (which causes problems if we don't)
#define H5PartWriteDataArray(null, T2, f, name, dataarray) \
  sprintf(typestring, "%s", #T2); \
  dataset = H5Dcreate(f->timegroup, name.c_str(), null##T2, f->shape, H5P_DEFAULT); \
  if (dataset<0) { \
    vtkErrorMacro(<<"Dataset create failed for " << name.c_str() \
    << " Timestep " << f->timestep \
    << " Shape " << f->shape \
    << " Data Type " << #T2); \
    r = -1; \
  } else { \
    void *dataptr = dataarray->GetVoidPointer(0); \
    dataptr = dataptr ? dataptr : &buffer[0]; \
    r = H5Dwrite(dataset, T2, memshape, diskshape, H5P_DEFAULT, dataptr); \
  } \
  H5Dclose(dataset); //----------------------------------------------------------------------------

    switch (finalData->GetDataType()) {
      case VTK_FLOAT:
        H5PartWriteDataArray(,H5T_NATIVE_FLOAT, this->H5FileId, name, finalData);
        break;
      case VTK_DOUBLE:
        H5PartWriteDataArray(,H5T_NATIVE_DOUBLE, this->H5FileId, name, finalData);
        break;
      case VTK_CHAR:
        if (VTK_TYPE_CHAR_IS_SIGNED) {
          H5PartWriteDataArray(,H5T_NATIVE_SCHAR, this->H5FileId, name, finalData);
        }
        else {
          H5PartWriteDataArray(,H5T_NATIVE_UCHAR, this->H5FileId, name, finalData);
        }
        break;
      case VTK_SIGNED_CHAR:
        H5PartWriteDataArray(,H5T_NATIVE_SCHAR, this->H5FileId, name, finalData);
        break;
      case VTK_UNSIGNED_CHAR:
        H5PartWriteDataArray(,H5T_NATIVE_UCHAR, this->H5FileId, name, finalData);
        break;
      case VTK_SHORT:
        H5PartWriteDataArray(,H5T_NATIVE_SHORT, this->H5FileId, name, finalData);
        break;
      case VTK_UNSIGNED_SHORT:
        H5PartWriteDataArray(,H5T_NATIVE_USHORT, this->H5FileId, name, finalData);
        break;
      case VTK_INT:
        H5PartWriteDataArray(,H5T_NATIVE_INT, this->H5FileId, name, finalData);
        break;
      case VTK_UNSIGNED_INT:
        H5PartWriteDataArray(,H5T_NATIVE_UINT, this->H5FileId, name, finalData);
        break;
      case VTK_LONG:
        H5PartWriteDataArray(,H5T_NATIVE_LONG, this->H5FileId, name, finalData);
        break;
      case VTK_UNSIGNED_LONG:
        H5PartWriteDataArray(,H5T_NATIVE_ULONG, this->H5FileId, name, finalData);
        break;
      case VTK_LONG_LONG:
        H5PartWriteDataArray(,H5T_NATIVE_LLONG, this->H5FileId, name, finalData);
        break;
      case VTK_UNSIGNED_LONG_LONG:
        H5PartWriteDataArray(,H5T_NATIVE_ULLONG, this->H5FileId, name, finalData);
        break;
      case VTK_ID_TYPE:
        if (VTK_SIZEOF_ID_TYPE==8) {
          H5PartWriteDataArray(,H5T_NATIVE_LLONG, this->H5FileId, name, finalData);
        }
        else if (VTK_SIZEOF_ID_TYPE==4) {
          H5PartWriteDataArray(,H5T_NATIVE_LONG, this->H5FileId, name, finalData);
        }
        break;
      default:
        vtkErrorMacro(<<"Unexpected data type");
    }

···

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

I think this was meant for the list

···

---------- Forwarded message ----------
From: Ger van Diepen <diepen@astron.nl>
Date: 2009/5/19
Subject: Re: [hdf-forum] Re: creating hdf5 datatypes at compile-time?
To: Dimitris Servis <servisster@gmail.com>

I have the feeling that some solutions do not pay enough attention to
portability.

1. typeid is compiler dependent and should not be used in persistency like
Dimitris seems to suggest.

2. I think using H5T_NATIVE_INT as such is not portable between systems
where an int is 32 bits and systems where an int is 64 bits. IMHO a length
(say 4) should always be set with H5Tset_size.

Talking about solutions.
I've made a class HDF5DataType that generates the correct HDF5 data type for
file and memory for all of the basic types (including std::complex and
variable length string) and use it in a templated class to create and access
a data set. It is also used when reading and writing attributes.

Cheers,
Ger

Dimitris Servis <servisster@gmail.com> 05/19/09 2:39 PM >>>

Hi all,

I think the OP' question is related to static typing rather than using RTTI
to select an appropriate type. However the run-time approaches offered here
are maybe more elegant. I guess what would be a solution for the OP is to
create explicit specializations that map atomic or compound types to HDF5
types. To address the OP question, I guess something like the following
would do:

template<class AtomicType> class GenericTable
{
public:
   GenericTable(){}
   ~GenericTable(){}
   virtual void create(){};

   hid_t parent;
   hid_t dataspace;
   std::string name;
};

template<> void GenericTable<int>::create()
{

H5Dcreate(parent,name.c_str(),H5T_NATIVE_INT,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
}

template<> void GenericTable<double>::create()
{

H5Dcreate(parent,name.c_str(),H5T_NATIVE_DOUBLE,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
}

void test()
{
   GenericTable<int> a;
   a.create();
   GenericTable<double> b;
   b.create();
}

But one has to write the specializations. Another way is to create special
wrapper types:

template<class AtomicType> struct HDF5type
{
   static hid_t getType;
};

template<> hid_t HDF5type<int>::getType=H5T_NATIVE_INT;
template<> hid_t HDF5type<double>::getType=H5T_NATIVE_DOUBLE;

template<class AtomicType> class GenericTable2
{
public:
   GenericTable2(){}
   ~GenericTable2(){}
   virtual void create()
   {

H5Dcreate(parent,name.c_str(),HDF5type<AtomicType>::getType,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
   };

   hid_t parent;
   hid_t dataspace;
   std::string name;
};

void test2()
{
   GenericTable2<int> c;
   c.create();
   GenericTable2<double> d;
   d.create();
}

In all cases, macros can be used to assist the definition of the
specializations. I hope that answers the OP's question, however, RTTI
solutions already offered are maybe better. I also had written somewhere a
small HDF5 serialization class for atomic types with reflection but cannot
seem to find it... I was planning to put it in the public domain but then
THG said they'll have a SF project for that, which I do not recall if it
ever came...

HTH

-- ds

2009/5/19 Quincey Koziol <koziol@hdfgroup.org>

Hi all,

On May 18, 2009, at 4:32 PM, Werner Benger wrote:

Hi Patrick,

the HDF5 predefined types like H5T_STD_U32LE are actually function calls,
not static #defines.

       Hmm, they are probably closer to singleton's - initialized to a
value via a function call the first time they are executed and then on
subsequent executions the function call occurs, but is a no-op and just

the

value is used.

You would need to build up your template metaprogram

such that it at compile time builds a function that builds the required
type
at runtime.

       I've read the later message with template suggestions, which look
nice. In case it's useful, it's possible to serialize a more complex
datatype with the H5Tencode() routine (and deserialize it with

H5Tdecode()).

       Quincey

To avoid building a type that was alread build, you might need something

like a type registry, which maps C++ native type ID's to HDF5 ID's and
vice versa. If you also intend to store named types in a file, then you
might have multipe HDF5 ID's for one C++ typeid.

Cheers,

       Werner

On Mon, 18 May 2009 16:18:21 -0500, Patrick <jazzcat81@hotmail.com> >> wrote:

Hello all,

I am currently trying to implement a function in C++ that stores a
multi-dimensional array to hdf5 whose C++- type is given by a template
parameter at compile time. Ideally, I would determine the corresponding

hdf5

datatype during compilation using a template meta-program. However, I
haven't been able to get this to work using the predefined types (i.e.
H5T_STD_U32LE) (I get the error "expected constant expression"), and

after

reading more about the hdf5 datatype concept, I am not sure if the

compile

time approach is at all possible. Is there an elegant generic solution

to

this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--

___________________________________________________________________________

Dr. Werner Benger <werner@cct.lsu.edu> Visualization
Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University
(CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

From: Ger van Diepen <diepen@astron.nl>
Date: 2009/5/19
Subject: Re: [hdf-forum] Re: creating hdf5 datatypes at compile-time?
To: Dimitris Servis <servisster@gmail.com>

I have the feeling that some solutions do not pay enough attention to
portability.

1. typeid is compiler dependent and should not be used in persistency like Dimitris seems to suggest.

For the implementation that I sent before, compiler dependent details of
typeid are not relevant. Only requirement are the uniqueness of typeid's
for C++ types, and the existence of the before() relationships that
allows to order typeid's. The exact ordering othe typeid's is not of
relevance, neither is the - compiler-dependent - mapping of typeid's
to strings.

2. I think using H5T_NATIVE_INT as such is not portable between systems
where an int is 32 bits and systems where an int is 64 bits. IMHO a length
(say 4) should always be set with H5Tset_size.

I might consider H5T_NATIVE_INT to be as portable as using int's.
It's a "native int", and therefore not supposed to be portable, but
native. There are other exact data types that will be exactly the
same everywhere; however, I would rather not want H5T_NATIVE_INT
correspond to be the same binary layout on each platform.

  Werner

···

---------- Forwarded message ----------

Talking about solutions.
I've made a class HDF5DataType that generates the correct HDF5 data type for
file and memory for all of the basic types (including std::complex and
variable length string) and use it in a templated class to create and access
a data set. It is also used when reading and writing attributes.

Cheers,
Ger

Dimitris Servis <servisster@gmail.com> 05/19/09 2:39 PM >>>

Hi all,

I think the OP' question is related to static typing rather than using RTTI
to select an appropriate type. However the run-time approaches offered here
are maybe more elegant. I guess what would be a solution for the OP is to
create explicit specializations that map atomic or compound types to HDF5
types. To address the OP question, I guess something like the following
would do:

template<class AtomicType> class GenericTable
{
public:
   GenericTable(){}
   ~GenericTable(){}
   virtual void create(){};

   hid_t parent;
   hid_t dataspace;
   std::string name;
};

template<> void GenericTable<int>::create()
{

H5Dcreate(parent,name.c_str(),H5T_NATIVE_INT,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
}

template<> void GenericTable<double>::create()
{

H5Dcreate(parent,name.c_str(),H5T_NATIVE_DOUBLE,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
}

void test()
{
   GenericTable<int> a;
   a.create();
   GenericTable<double> b;
   b.create();
}

But one has to write the specializations. Another way is to create special
wrapper types:

template<class AtomicType> struct HDF5type
{
   static hid_t getType;
};

template<> hid_t HDF5type<int>::getType=H5T_NATIVE_INT;
template<> hid_t HDF5type<double>::getType=H5T_NATIVE_DOUBLE;

template<class AtomicType> class GenericTable2
{
public:
   GenericTable2(){}
   ~GenericTable2(){}
   virtual void create()
   {

H5Dcreate(parent,name.c_str(),HDF5type<AtomicType>::getType,dataspace,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
   };

   hid_t parent;
   hid_t dataspace;
   std::string name;
};

void test2()
{
   GenericTable2<int> c;
   c.create();
   GenericTable2<double> d;
   d.create();
}

In all cases, macros can be used to assist the definition of the
specializations. I hope that answers the OP's question, however, RTTI
solutions already offered are maybe better. I also had written somewhere a
small HDF5 serialization class for atomic types with reflection but cannot
seem to find it... I was planning to put it in the public domain but then
THG said they'll have a SF project for that, which I do not recall if it
ever came...

HTH

-- ds

2009/5/19 Quincey Koziol <koziol@hdfgroup.org>

Hi all,

On May 18, 2009, at 4:32 PM, Werner Benger wrote:

Hi Patrick,

the HDF5 predefined types like H5T_STD_U32LE are actually function calls,
not static #defines.

       Hmm, they are probably closer to singleton's - initialized to a
value via a function call the first time they are executed and then on
subsequent executions the function call occurs, but is a no-op and just

the

value is used.

You would need to build up your template metaprogram

such that it at compile time builds a function that builds the required
type
at runtime.

       I've read the later message with template suggestions, which look
nice. In case it's useful, it's possible to serialize a more complex
datatype with the H5Tencode() routine (and deserialize it with

H5Tdecode()).

       Quincey

To avoid building a type that was alread build, you might need something

like a type registry, which maps C++ native type ID's to HDF5 ID's and
vice versa. If you also intend to store named types in a file, then you
might have multipe HDF5 ID's for one C++ typeid.

Cheers,

       Werner

On Mon, 18 May 2009 16:18:21 -0500, Patrick <jazzcat81@hotmail.com> >>> wrote:

Hello all,

I am currently trying to implement a function in C++ that stores a
multi-dimensional array to hdf5 whose C++- type is given by a template
parameter at compile time. Ideally, I would determine the corresponding

hdf5

datatype during compilation using a template meta-program. However, I
haven't been able to get this to work using the predefined types (i.e.
H5T_STD_U32LE) (I get the error "expected constant expression"), and

after

reading more about the hdf5 datatype concept, I am not sure if the

compile

time approach is at all possible. Is there an elegant generic solution

to

this problem?

Thanks!

Regards,

Patrick

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--

___________________________________________________________________________

Dr. Werner Benger <werner@cct.lsu.edu> Visualization
Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University
(CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to
hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--
___________________________________________________________________________
Dr. Werner Benger <werner@cct.lsu.edu> Visualization Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University (CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809 Fax.: +1 225 578-5362

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

H5T_NATIVE_INT is Bad and we all know why. You should rather prefer the following:

H5T_NATIVE_INT8
H5T_NATIVE_UINT8 and the rest of them that have specifically list the size in the name. That way there is NO confusion about what the value is and it is guaranteed to be the same _size_ on all platforms.

···

---
Mike Jackson www.bluequartz.net

On May 19, 2009, at 2:58 PM, Werner Benger wrote:

2. I think using H5T_NATIVE_INT as such is not portable between systems
where an int is 32 bits and systems where an int is 64 bits. IMHO a length
(say 4) should always be set with H5Tset_size.

I might consider H5T_NATIVE_INT to be as portable as using int's.
It's a "native int", and therefore not supposed to be portable, but
native. There are other exact data types that will be exactly the
same everywhere; however, I would rather not want H5T_NATIVE_INT
correspond to be the same binary layout on each platform.

  Werner

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

Mike,

H5T_NATIVE_INT is Bad and we all know why.

Hmm... I don't :slight_smile:

You should rather prefer the following:

H5T_NATIVE_INT8
H5T_NATIVE_UINT8 and the rest of them that have specifically list the size in the name. That way there is NO confusion about what the value is and it is guaranteed to be the same _size_ on all platforms.

It is true that the size is the same if the type is available, but in general, C99 doesn't guarantee availability, does it? Then the source code that uses H5T_NATIVE_INT8 will not be portable. Or am I missing something? (C is not my native language).

Elena

···

On May 19, 2009, at 2:05 PM, Michael Jackson wrote:

---
Mike Jackson www.bluequartz.net

On May 19, 2009, at 2:58 PM, Werner Benger wrote:

2. I think using H5T_NATIVE_INT as such is not portable between systems
where an int is 32 bits and systems where an int is 64 bits. IMHO a length
(say 4) should always be set with H5Tset_size.

I might consider H5T_NATIVE_INT to be as portable as using int's.
It's a "native int", and therefore not supposed to be portable, but
native. There are other exact data types that will be exactly the
same everywhere; however, I would rather not want H5T_NATIVE_INT
correspond to be the same binary layout on each platform.

  Werner

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.