HighFive icon indicating copy to clipboard operation
HighFive copied to clipboard

support `std::variant` for read function

Open nitrogar opened this issue 2 years ago • 1 comments

I am writing a generic H5 viewer, therefore I need to fetch data from dataset and casting the result at the end.

I tried std::vector<std::vector<std::variant<int,float,double,std::string>>> but it gives me this compilation error.

my code:

std::vector<std::vector<std::variant<int,float,double,std::string>>> data;
dataset.select({0, 0}, {10, 10}).read(data);

error:

/home/username/githubs/HighFive/include/highfive/bits/../bits/H5DataType_misc.hpp: In instantiation of ‘HighFive::AtomicType<T>::AtomicType() [with T = std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >]’:
/home/username/githubs/HighFive/include/highfive/bits/../bits/H5DataType_misc.hpp:499:12:   required from ‘HighFive::DataType HighFive::create_datatype() [with T = std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >]’
/home/username/githubs/HighFive/include/highfive/bits/H5ReadWrite_misc.hpp:141:84:   required from ‘HighFive::details::BufferInfo<T>::BufferInfo(const HighFive::DataType&, F, Operation) [with F = HighFive::SliceTraits<HighFive::Selection>::read<std::vector<std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >(std::vector<std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, const HighFive::DataTransferProps&) const::<lambda()>; T = std::vector<std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
/home/username/githubs/HighFive/include/highfive/bits/H5Slice_traits_misc.hpp:175:34:   required from ‘void HighFive::SliceTraits<Derivate>::read(T&, const HighFive::DataTransferProps&) const [with T = std::vector<std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >; Derivate = HighFive::Selection; HighFive::DataTransferProps = HighFive::PropertyList<HighFive::PropertyType::DATASET_XFER>]’
/home/archiver/projects/omar_challeng/include/H5.hpp:45:81:   required from here
/home/username/githubs/HighFive/include/highfive/bits/../bits/H5DataType_misc.hpp:257:57: error: static assertion failed: Type not supported
  257 |     static_assert(details::inspector<T>::recursive_ndim > 0, "Type not supported");
      |                                          ~~~~~~~~~~~~~~~^~~
/home/username/githubs/HighFive/include/highfive/bits/../bits/H5DataType_misc.hpp:257:57: note: the comparison reduces to ‘(0 > 0)’
In file included from /home/username/githubs/HighFive/include/highfive/bits/H5Converter_misc.hpp:13:
/home/username/githubs/HighFive/include/highfive/bits/H5Inspector_misc.hpp: In instantiation of ‘static void HighFive::details::type_helper<T>::unserialize(const hdf5_type*, const std::vector<long unsigned int>&, type&) [with T = std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >; hdf5_type = std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >; type = std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >]’:
/home/username/githubs/HighFive/include/highfive/bits/H5Inspector_misc.hpp:425:47:   recursively required from ‘static void HighFive::details::inspector<std::vector<Size> >::unserialize(const It&, const std::vector<long unsigned int>&, type&) [with It = const std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*; T = std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >; type = std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >]’
/home/username/githubs/HighFive/include/highfive/bits/H5Inspector_misc.hpp:425:47:   required from ‘static void HighFive::details::inspector<std::vector<Size> >::unserialize(const It&, const std::vector<long unsigned int>&, type&) [with It = const std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*; T = std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >; type = std::vector<std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
/home/username/githubs/HighFive/include/highfive/bits/H5Converter_misc.hpp:92:37:   required from ‘void HighFive::details::DeepCopyBuffer<T>::unserialize(T&) const [with T = std::vector<std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
/home/username/githubs/HighFive/include/highfive/bits/H5Slice_traits_misc.hpp:199:18:   required from ‘void HighFive::SliceTraits<Derivate>::read(T&, const HighFive::DataTransferProps&) const [with T = std::vector<std::vector<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >; Derivate = HighFive::Selection; HighFive::DataTransferProps = HighFive::PropertyList<HighFive::PropertyType::DATASET_XFER>]’
/home/archiver/projects/omar_challeng/include/H5.hpp:45:81:   required from here
/home/username/githubs/HighFive/include/highfive/bits/H5Inspector_misc.hpp:217:23: error: static assertion failed: The type is not trivially copyable
  217 |         static_assert(is_trivially_copyable, "The type is not trivially copyable");
      |                       ^~~~~~~~~~~~~~~~~~~~~
/home/username/githubs/HighFive/include/highfive/bits/H5Inspector_misc.hpp:217:23: note: ‘HighFive::details::type_helper<std::variant<int, float, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::is_trivially_copyable’ evaluates to false

nitrogar avatar Dec 18 '23 21:12 nitrogar

HDF5 can't really read an unspecified DataType and then the user casts later and HighFive doesn't implement the feature you're looking for.

I suspect short term you might have to go for something like:

  1. Get the datatype.
  2. if statement with one branch per type.
  3. In each branch read an std::vector<std::vector<T>> with T = int, ..., or std::string.
  4. Copy everything into an std::vector<std::vector<std::variant<...>>>. Now that the return type is uniform across all branches of the if statement you could return it.

Longer term, supporting std::variant seems interesting since something similar has been requested before.

1uc avatar Dec 19 '23 07:12 1uc