30inline bool checkDimensions(
const std::vector<size_t>& dims, 
size_t n_dim_requested) {
 
   31    size_t n_dim_actual = dims.size();
 
   34    if (n_dim_requested == 0) {
 
   35        if (n_dim_actual == 0ul) {
 
   39        return size_t(std::count(dims.begin(), dims.end(), 1ul)) == n_dim_actual;
 
   44    if (n_dim_actual < n_dim_requested) {
 
   50    if (n_dim_requested == 1ul) {
 
   51        return n_dim_actual >= 1ul &&
 
   52               size_t(std::count(dims.begin(), dims.end(), 1ul)) >= n_dim_actual - 1ul;
 
   57    size_t n_dim_excess = n_dim_actual - n_dim_requested;
 
   59    bool squeeze_back = 
true;
 
   60    for (
size_t i = 1; i <= n_dim_excess; ++i) {
 
   61        if (dims[n_dim_actual - i] != 1) {
 
   71inline std::vector<size_t> squeezeDimensions(
const std::vector<size_t>& dims,
 
   72                                             size_t n_dim_requested) {
 
   73    auto format_error_message = [&]() -> std::string {
 
   74        return "Can't interpret dims = " + format_vector(dims) + 
" as " +
 
   75               std::to_string(n_dim_requested) + 
"-dimensional.";
 
   78    if (n_dim_requested == 0) {
 
   79        if (!checkDimensions(dims, n_dim_requested)) {
 
   80            throw std::invalid_argument(
"Failed dimensions check: " + format_error_message());
 
   86    auto n_dim = dims.size();
 
   87    if (n_dim < n_dim_requested) {
 
   88        throw std::invalid_argument(
"Failed 'n_dim < n_dim_requested: " + format_error_message());
 
   91    if (n_dim_requested == 1ul) {
 
   92        size_t non_singleton_dim = size_t(-1);
 
   93        for (
size_t i = 0; i < n_dim; ++i) {
 
   95                if (non_singleton_dim == 
size_t(-1)) {
 
   96                    non_singleton_dim = i;
 
   98                    throw std::invalid_argument(
"Failed one-dimensional: " +
 
   99                                                format_error_message());
 
  104        return {dims[std::min(non_singleton_dim, n_dim - 1)]};
 
  107    size_t n_dim_excess = dims.size() - n_dim_requested;
 
  108    for (
size_t i = 1; i <= n_dim_excess; ++i) {
 
  109        if (dims[n_dim - i] != 1) {
 
  110            throw std::invalid_argument(
"Failed stripping from back:" + format_error_message());
 
  114    return std::vector<size_t>(dims.begin(),
 
  115                               dims.end() - 
static_cast<std::ptrdiff_t
>(n_dim_excess));
 
  162    using type = unqualified_t<T>;
 
  163    using base_type = unqualified_t<T>;
 
  164    using hdf5_type = base_type;
 
  166    static constexpr size_t ndim = 0;
 
  167    static constexpr size_t recursive_ndim = ndim;
 
  168    static constexpr bool is_trivially_copyable = std::is_trivially_copyable<type>::value;
 
  170    static std::vector<size_t> getDimensions(
const type& ) {
 
  174    static size_t getSizeVal(
const type& val) {
 
  178    static size_t getSize(
const std::vector<size_t>& dims) {
 
  182    static void prepare(type& , 
const std::vector<size_t>& ) {}
 
  184    static hdf5_type* data(type& val) {
 
  185        static_assert(is_trivially_copyable, 
"The type is not trivially copyable");
 
  189    static const hdf5_type* data(
const type& val) {
 
  190        static_assert(is_trivially_copyable, 
"The type is not trivially copyable");
 
  194    static void serialize(
const type& val, hdf5_type* m) {
 
  195        static_assert(is_trivially_copyable, 
"The type is not trivially copyable");
 
  199    static void unserialize(
const hdf5_type* vec,
 
  200                            const std::vector<size_t>& ,
 
  202        static_assert(is_trivially_copyable, 
"The type is not trivially copyable");
 
  208struct inspector: type_helper<T> {};
 
  210enum class Boolean : int8_t {
 
  216struct inspector<bool>: type_helper<bool> {
 
  217    using base_type = Boolean;
 
  218    using hdf5_type = int8_t;
 
  220    static constexpr bool is_trivially_copyable = 
false;
 
  222    static hdf5_type* data(type& ) {
 
  223        throw DataSpaceException(
"A boolean cannot be read directly.");
 
  226    static const hdf5_type* data(
const type& ) {
 
  227        throw DataSpaceException(
"A boolean cannot be written directly.");
 
  230    static void unserialize(
const hdf5_type* vec,
 
  231                            const std::vector<size_t>& ,
 
  233        val = vec[0] != 0 ? true : 
false;
 
  236    static void serialize(
const type& val, hdf5_type* m) {
 
  242struct inspector<std::string>: type_helper<std::string> {
 
  243    using hdf5_type = 
const char*;
 
  245    static hdf5_type* data(type& ) {
 
  246        throw DataSpaceException(
"A std::string cannot be read directly.");
 
  249    static const hdf5_type* data(
const type& ) {
 
  250        throw DataSpaceException(
"A std::string cannot be written directly.");
 
  254    static void serialize(
const type& val, It m) {
 
  259    static void unserialize(
const It& vec, 
const std::vector<size_t>& , type& val) {
 
  260        const auto& view = *vec;
 
  261        val.assign(view.data(), view.length());
 
  266struct inspector<
Reference>: type_helper<Reference> {
 
  267    using hdf5_type = hobj_ref_t;
 
  269    static constexpr bool is_trivially_copyable = 
false;
 
  271    static hdf5_type* data(type& ) {
 
  272        throw DataSpaceException(
"A Reference cannot be read directly.");
 
  275    static const hdf5_type* data(
const type& ) {
 
  276        throw DataSpaceException(
"A Reference cannot be written directly.");
 
  279    static void serialize(
const type& val, hdf5_type* m) {
 
  281        val.create_ref(&ref);
 
  285    static void unserialize(
const hdf5_type* vec,
 
  286                            const std::vector<size_t>& ,
 
  293struct inspector<deprecated::FixedLenStringArray<N>> {
 
  294    using type = deprecated::FixedLenStringArray<N>;
 
  295    using value_type = 
char*;
 
  296    using base_type = deprecated::FixedLenStringArray<N>;
 
  297    using hdf5_type = char;
 
  299    static constexpr size_t ndim = 1;
 
  300    static constexpr size_t recursive_ndim = ndim;
 
  301    static constexpr bool is_trivially_copyable = 
false;
 
  303    static std::vector<size_t> getDimensions(
const type& val) {
 
  304        return std::vector<size_t>{val.size()};
 
  307    static size_t getSizeVal(
const type& val) {
 
  311    static size_t getSize(
const std::vector<size_t>& dims) {
 
  315    static void prepare(type& , 
const std::vector<size_t>& dims) {
 
  317            std::ostringstream os;
 
  318            os << 
"Size of FixedlenStringArray (" << N << 
") is too small for dims (" << dims[0]
 
  320            throw DataSpaceException(os.str());
 
  324    static hdf5_type* data(type& val) {
 
  328    static const hdf5_type* data(
const type& val) {
 
  332    static void serialize(
const type& val, hdf5_type* m) {
 
  333        for (
size_t i = 0; i < val.size(); ++i) {
 
  334            std::memcpy(m + i * N, val[i], N);
 
  338    static void unserialize(
const hdf5_type* vec, 
const std::vector<size_t>& dims, type& val) {
 
  339        for (
size_t i = 0; i < dims[0]; ++i) {
 
  340            std::array<char, N> s;
 
  341            std::memcpy(s.data(), vec + (i * N), N);
 
  348struct inspector<std::vector<T>> {
 
  349    using type = std::vector<T>;
 
  350    using value_type = unqualified_t<T>;
 
  351    using base_type = 
typename inspector<value_type>::base_type;
 
  352    using hdf5_type = 
typename inspector<value_type>::hdf5_type;
 
  354    static constexpr size_t ndim = 1;
 
  355    static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
 
  356    static constexpr bool is_trivially_copyable = std::is_trivially_copyable<value_type>::value &&
 
  357                                                  inspector<value_type>::is_trivially_copyable;
 
  359    static std::vector<size_t> getDimensions(
const type& val) {
 
  360        std::vector<size_t> sizes(recursive_ndim, 1ul);
 
  361        sizes[0] = val.size();
 
  363            auto s = inspector<value_type>::getDimensions(val[0]);
 
  364            assert(s.size() + ndim == sizes.size());
 
  365            for (
size_t i = 0; i < s.size(); ++i) {
 
  366                sizes[i + ndim] = s[i];
 
  372    static size_t getSizeVal(
const type& val) {
 
  376    static size_t getSize(
const std::vector<size_t>& dims) {
 
  380    static void prepare(type& val, 
const std::vector<size_t>& dims) {
 
  382        std::vector<size_t> next_dims(dims.begin() + 1, dims.end());
 
  383        for (
auto&& e: val) {
 
  384            inspector<value_type>::prepare(e, next_dims);
 
  388    static hdf5_type* data(type& val) {
 
  389        return val.empty() ? nullptr : inspector<value_type>::data(val[0]);
 
  392    static const hdf5_type* data(
const type& val) {
 
  393        return val.empty() ? nullptr : inspector<value_type>::data(val[0]);
 
  397    static void serialize(
const type& val, It m) {
 
  399            size_t subsize = inspector<value_type>::getSizeVal(val[0]);
 
  400            for (
auto&& e: val) {
 
  401                inspector<value_type>::serialize(e, m);
 
  408    static void unserialize(
const It& vec_align, 
const std::vector<size_t>& dims, type& val) {
 
  409        std::vector<size_t> next_dims(dims.begin() + 1, dims.end());
 
  411        for (
size_t i = 0; i < dims[0]; ++i) {
 
  412            inspector<value_type>::unserialize(vec_align + i * next_size, next_dims, val[i]);
 
  418struct inspector<std::vector<bool>> {
 
  419    using type = std::vector<bool>;
 
  420    using value_type = bool;
 
  421    using base_type = Boolean;
 
  422    using hdf5_type = uint8_t;
 
  424    static constexpr size_t ndim = 1;
 
  425    static constexpr size_t recursive_ndim = ndim;
 
  426    static constexpr bool is_trivially_copyable = 
false;
 
  428    static std::vector<size_t> getDimensions(
const type& val) {
 
  429        std::vector<size_t> sizes{val.size()};
 
  433    static size_t getSizeVal(
const type& val) {
 
  437    static size_t getSize(
const std::vector<size_t>& dims) {
 
  438        if (dims.size() > 1) {
 
  439            throw DataSpaceException(
"std::vector<bool> is only 1 dimension.");
 
  444    static void prepare(type& val, 
const std::vector<size_t>& dims) {
 
  445        if (dims.size() > 1) {
 
  446            throw DataSpaceException(
"std::vector<bool> is only 1 dimension.");
 
  451    static hdf5_type* data(type& ) {
 
  452        throw DataSpaceException(
"A std::vector<bool> cannot be read directly.");
 
  455    static const hdf5_type* data(
const type& ) {
 
  456        throw DataSpaceException(
"A std::vector<bool> cannot be written directly.");
 
  459    static void serialize(
const type& val, hdf5_type* m) {
 
  460        for (
size_t i = 0; i < val.size(); ++i) {
 
  461            m[i] = val[i] ? 1 : 0;
 
  465    static void unserialize(
const hdf5_type* vec_align,
 
  466                            const std::vector<size_t>& dims,
 
  468        for (
size_t i = 0; i < dims[0]; ++i) {
 
  469            val[i] = vec_align[i] != 0 ? true : 
false;
 
  474template <
typename T, 
size_t N>
 
  475struct inspector<std::array<T, N>> {
 
  476    using type = std::array<T, N>;
 
  477    using value_type = unqualified_t<T>;
 
  478    using base_type = 
typename inspector<value_type>::base_type;
 
  479    using hdf5_type = 
typename inspector<value_type>::hdf5_type;
 
  481    static constexpr size_t ndim = 1;
 
  482    static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
 
  483    static constexpr bool is_trivially_copyable = std::is_trivially_copyable<value_type>::value &&
 
  484                                                  sizeof(type) == N * 
sizeof(T) &&
 
  485                                                  inspector<value_type>::is_trivially_copyable;
 
  487    static std::vector<size_t> getDimensions(
const type& val) {
 
  488        std::vector<size_t> sizes{N};
 
  490            auto s = inspector<value_type>::getDimensions(val[0]);
 
  491            sizes.insert(sizes.end(), s.begin(), s.end());
 
  496    static size_t getSizeVal(
const type& val) {
 
  500    static size_t getSize(
const std::vector<size_t>& dims) {
 
  504    static void prepare(type& val, 
const std::vector<size_t>& dims) {
 
  506            std::ostringstream os;
 
  507            os << 
"Size of std::array (" << N << 
") is too small for dims (" << dims[0] << 
").";
 
  508            throw DataSpaceException(os.str());
 
  511        std::vector<size_t> next_dims(dims.begin() + 1, dims.end());
 
  512        for (
auto&& e: val) {
 
  513            inspector<value_type>::prepare(e, next_dims);
 
  517    static hdf5_type* data(type& val) {
 
  518        return inspector<value_type>::data(val[0]);
 
  521    static const hdf5_type* data(
const type& val) {
 
  522        return inspector<value_type>::data(val[0]);
 
  526    static void serialize(
const type& val, It m) {
 
  527        size_t subsize = inspector<value_type>::getSizeVal(val[0]);
 
  529            inspector<value_type>::serialize(e, m);
 
  535    static void unserialize(
const It& vec_align, 
const std::vector<size_t>& dims, type& val) {
 
  537            std::ostringstream os;
 
  538            os << 
"Impossible to pair DataSet with " << dims[0] << 
" elements into an array with " 
  539               << N << 
" elements.";
 
  540            throw DataSpaceException(os.str());
 
  542        std::vector<size_t> next_dims(dims.begin() + 1, dims.end());
 
  544        for (
size_t i = 0; i < dims[0]; ++i) {
 
  545            inspector<value_type>::unserialize(vec_align + i * next_size, next_dims, val[i]);
 
  552struct inspector<T*> {
 
  554    using value_type = unqualified_t<T>;
 
  555    using base_type = 
typename inspector<value_type>::base_type;
 
  556    using hdf5_type = 
typename inspector<value_type>::hdf5_type;
 
  558    static constexpr size_t ndim = 1;
 
  559    static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
 
  560    static constexpr bool is_trivially_copyable = std::is_trivially_copyable<value_type>::value &&
 
  561                                                  inspector<value_type>::is_trivially_copyable;
 
  563    static size_t getSizeVal(
const type& ) {
 
  564        throw DataSpaceException(
"Not possible to have size of a T*");
 
  567    static std::vector<size_t> getDimensions(
const type& ) {
 
  568        throw DataSpaceException(
"Not possible to have size of a T*");
 
  571    static const hdf5_type* data(
const type& val) {
 
  572        return reinterpret_cast<const hdf5_type*
>(val);
 
  577    static void serialize(
const type& , hdf5_type* ) {
 
  578        throw DataSpaceException(
"Not possible to serialize a T*");
 
  583template <
typename T, 
size_t N>
 
  584struct inspector<T[N]> {
 
  586    using value_type = unqualified_t<T>;
 
  587    using base_type = 
typename inspector<value_type>::base_type;
 
  588    using hdf5_type = 
typename inspector<value_type>::hdf5_type;
 
  590    static constexpr size_t ndim = 1;
 
  591    static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
 
  592    static constexpr bool is_trivially_copyable = std::is_trivially_copyable<value_type>::value &&
 
  593                                                  inspector<value_type>::is_trivially_copyable;
 
  595    static void prepare(type& val, 
const std::vector<size_t>& dims) {
 
  596        if (dims.size() < 1) {
 
  597            throw DataSpaceException(
"Invalid 'dims', must be at least 1 dimensional.");
 
  601            throw DataSpaceException(
"Dimensions mismatch.");
 
  604        std::vector<size_t> next_dims(dims.begin() + 1, dims.end());
 
  605        for (
size_t i = 0; i < dims[0]; ++i) {
 
  606            inspector<value_type>::prepare(val[i], next_dims);
 
  610    static size_t getSizeVal(
const type& val) {
 
  614    static std::vector<size_t> getDimensions(
const type& val) {
 
  615        std::vector<size_t> sizes{N};
 
  617            auto s = inspector<value_type>::getDimensions(val[0]);
 
  618            sizes.insert(sizes.end(), s.begin(), s.end());
 
  623    static const hdf5_type* data(
const type& val) {
 
  624        return inspector<value_type>::data(val[0]);
 
  627    static hdf5_type* data(type& val) {
 
  628        return inspector<value_type>::data(val[0]);
 
  633    static void serialize(
const type& val, hdf5_type* m) {
 
  634        size_t subsize = inspector<value_type>::getSizeVal(val[0]);
 
  635        for (
size_t i = 0; i < N; ++i) {
 
  636            inspector<value_type>::serialize(val[i], m + i * subsize);
 
size_t getSize(const File &file, const std::string &path)
Definition H5Easy_public.hpp:82
Definition H5_definitions.hpp:22
size_t compute_total_size(const std::vector< size_t > &dims)
Definition H5Inspector_decl.hpp:10