diff --git a/sample/testHDF5.cpp b/sample/testHDF5.cpp index d38eb01..f09147d 100644 --- a/sample/testHDF5.cpp +++ b/sample/testHDF5.cpp @@ -38,10 +38,24 @@ knowledge of the CeCILL license and that you accept its terms. using namespace std; +struct MyStruct +{ + int a; + double b; + char c; +}; + +CTOOL_STRUCT_TYPE(MyStruct, hdf5t_MyStruct, + ((int, a)) + ((double, b)) + ((char, c)) +) + int main() { typedef boost::multi_array array_type; typedef boost::multi_array array3_type; + typedef boost::multi_array array_mys_type; typedef boost::multi_array, 2> arrayc_type; typedef array_type::index index; @@ -53,13 +67,23 @@ int main() array_type B; array3_type C(boost::extents[2][3][4]); arrayc_type D, E; + array_mys_type F(boost::extents[10]), G; int values = 0; for (index i = 0; i != 2; i++) for (index j = 0; j != 3; j++) A[i][j] = values++; + for (index i = 0; i != 10; i++) + { + F[i].a = i; + F[i].b = double(i)/4.; + F[i].c = 'r'+i; + } + std::cout << " c = " << ((char *)&F[1])[offsetof(MyStruct, c)] << endl; + CosmoTool::hdf5_write_array(g, "test_data", A); + CosmoTool::hdf5_write_array(g, "test_struct", F); CosmoTool::hdf5_read_array(g, "test_data", B); @@ -95,5 +119,12 @@ int main() abort(); } + CosmoTool::hdf5_read_array(g, "test_struct", G); + for (index i = 0; i != 10; i++) + if (G[i].a != F[i].a || G[i].b != F[i].b || G[i].c != F[i].c) { + std::cout << "Invalid struct content" << endl; + abort(); + } + return 0; } diff --git a/src/hdf5_array.hpp b/src/hdf5_array.hpp index fc1a727..2dad3ad 100644 --- a/src/hdf5_array.hpp +++ b/src/hdf5_array.hpp @@ -210,31 +210,32 @@ namespace CosmoTool { #define CTOOL_HDF5_INSERT_ELEMENT(r, STRUCT, element) \ { \ CosmoTool::get_hdf5_data_type t; \ - position = offsetof(STRUCT, BOOST_PP_TUPLE_ELEM(2, 1, element)); \ - type.insertMember(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 1, element)), position, t.type()); \ + position = HOFFSET(STRUCT, BOOST_PP_TUPLE_ELEM(2, 1, element)); \ + const char *field_name = BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 1, element)); \ + std::cout << "Field " << field_name << " offset = " << position << endl; \ + type.insertMember(field_name, position, t.type()); \ } #define CTOOL_STRUCT_TYPE(STRUCT, TNAME, ATTRIBUTES) \ namespace CosmoTool { \ - class CTOOL_HDF5_NAME(STRUCT) { \ + class TNAME { \ public: \ H5::CompType type; \ \ - CTOOL_HDF5_NAME(STRUCT)() : type(sizeof(STRUCT)) \ + TNAME() : type(sizeof(STRUCT)) \ { \ long position; \ BOOST_PP_SEQ_FOR_EACH(CTOOL_HDF5_INSERT_ELEMENT, STRUCT, ATTRIBUTES) \ - type.pack(); \ } \ \ - static const CTOOL_HDF5_NAME(STRUCT) *ctype() \ + static const TNAME *ctype() \ { \ - static CTOOL_HDF5_NAME(STRUCT) singleton; \ + static TNAME singleton; \ return &singleton; \ } \ }; \ template<> struct get_hdf5_data_type { \ - static H5::DataType type() { return CTOOL_HDF5_NAME(STRUCT)::ctype()->type; }; \ + static H5::DataType type() { return TNAME::ctype()->type; }; \ }; \ };