HDF5.jl icon indicating copy to clipboard operation
HDF5.jl copied to clipboard

WIP: Add ability to automatically box scalars in wrapped API with special case argument type

Open jmert opened this issue 4 years ago • 2 comments

This is the follow-up to discussions in #759 on how to automatically allow passing scalars through to pointer arguments to make using the low-level API more ergonomic.

Rather than the Ref{Any} type discussed in the comments, though, I instead chose to special case Ref{Cvoid} since Ref{Any} already has a meaning in Julia:

help?> Ref
...
  As a special case, setting `T = Any` will instead cause the creation of a pointer
  to the reference itself when converted to a `Ptr{Any}` (a `jl_value_t const* const*`
  if `T` is immutable, else a `jl_value_t *const *`). When converted to a
  `Ptr{Cvoid}`, it will still return a pointer to the data region as for any other `T`.
...

It's possible that these types of arguments may be required in setting up callback functions which pass through an arbitrary data bundle. On the other hand, Ref{Cvoid} seems to be an error, so there shouldn't be any code that actually needs this data type:

julia> Base.cconvert(Ref{Cvoid}, Ref(1))
ERROR: MethodError: Cannot `convert` an object of type 
  Base.RefValue{Int64} to an object of type 
  Union{}

I've included "WIP:" in the title because there might be some existing cases which could be simplified with this new feature. For instance, it might make sense on the h5d_write and h5a_write methods, which would allow removing some write_(attribute|dataset) specializations if the wrapper can do the boxing automatically. (Just an idea at this point, though — haven't tried actually doing it yet, so there might be a corner case I'm not currently thinking of.)

jmert avatar Dec 06 '20 20:12 jmert

Oh, also with this PR:

julia> using HDF5

julia> b = create_datatype(HDF5.H5T_ENUM, sizeof(Bool))
       HDF5.h5t_enum_insert(b, "FALSE", false)
       HDF5.h5t_enum_insert(b, "TRUE", true)
       b
HDF5.Datatype: H5T_ENUM {
      H5T_STD_I8LE;
      "FALSE"            0;
      "TRUE"             1;
   }

and the explicitly-wrapped case continues to work as is now possible on master:

julia> b′ = create_datatype(HDF5.H5T_ENUM, sizeof(Bool))
       HDF5.h5t_enum_insert(b′, "FALSE", Ref(false))
       HDF5.h5t_enum_insert(b′, "TRUE", Ref(true))
       b′
HDF5.Datatype: H5T_ENUM {
      H5T_STD_I8LE;
      "FALSE"            0;
      "TRUE"             1;
   }

jmert avatar Dec 06 '20 20:12 jmert

LGTM

musm avatar Dec 06 '20 21:12 musm