JuliaInterop / CxxWrap.jl

Package to make C++ libraries available in Julia
Other
418 stars 67 forks source link

jlcxx::ArrayRef<abstractType> #122

Open kalmarek opened 5 years ago

kalmarek commented 5 years ago

Suppose that I have a CxxWrapped type myType, it produces myTypeAllocated and myTypeRef concrete types on the julia side; I'd like to construct a CxxWrapped type parametrized by myType (in the example below: an array of myTypes)

  module.add_type<jlcxx::Parametric<jlcxx::TypeVar<1>>>("my_Array", jlcxx::julia_type("AbstractVector", "Base"))
    .apply<
      my::Array<int64_t>,
      my::Array<myType>
    >([](auto wrapped){
      typedef typename decltype(wrapped)::type WrappedT;
      typedef typename decltype(wrapped)::type::value_type elemType;

      wrapped.template constructor<int64_t>();

      wrapped.method("_new_array", [](jlcxx::ArrayRef<elemType> A){
        my::Array<elemType> a{(int32_t) A.size(), A.begin()};
        return a;
      });
  );

This works fine for integers: module._new_array([1,2,3]) produces a pm_ArrayAllocated{Int64}; however I can not call module._new_array([myType()]) since the argument is of type Vector{myTypeAllocated} and not Vector{myType} as _new_array expects. I could of course do m = MyType(); module._new_array(myType[m]) to force the abstract type on the arguments elements.

Question: is it possible to make the declaration

wrapped.method("_new_array", [](jlcxx::ArrayRef<elemType> A){...});

register _new_array(::Array{T}) where T<:jl_elemType method (where jl_elemType is the appropriate CxxWrapped type?)

barche commented 5 years ago

Hi,

Sorry for the very late reply, completely missed this somehow. You could try to add an argument overload, using something like this before wrapping the functions:

@readmodule(libfoo, :register_foo)
@wraptypes

CxxWrap.argument_overloads(t::Type{Vector{T}}) where {T <: jl_elemType} = [Vector{jl_elemType}]

@wrapfunctions