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

Dealing with `std::shared_ptr<std::vector<std::shared_ptr<...>>>`

Open colinxs opened this issue 3 years ago • 1 comments

I have the following struct:

struct Contract {
   std::shared_ptr<std::vector<std::shared_ptr<ComboLeg>>> y comboLegs;
}

and the following wrapper:

mod.add_type<Contract>("Contract")
    .method("Contract_get_comboLegs", [](const Contract& x) -> auto { return x.comboLegs; })
jlcxx::stl::apply_stl<ComboLeg>(mod); // Note sure if this is needed?

What I would like to do in Julia:

x = Contract()
push!(x.comboLegs, Ref(ComboLeg()))

In C++ this looks like:

Contract contract;
std::shared_ptr<ComboLeg> leg1(new ComboLeg);
contract.comboLegs->push_back(leg1);

Unfortunately, trying the Julia example above yields:

MethodError: no method matching push!(::ConstCxxRef{CxxWrap.StdLib.SharedPtr{StdVector{CxxWrap.StdLib.SharedPtr{Emporos.IBKR.IBKRCore.ComboLeg}}}}, ::Base.RefValue{Emporos.IBKR.IBKRCore.ComboLegAllocated})
Closest candidates are:
  push!(::Any, ::Any, ::Any) at abstractarray.jl:2387
  push!(::Any, ::Any, ::Any, ::Any...) at abstractarray.jl:2388
  push!(::Union{CxxWrap.CxxWrapCore.CxxBaseRef{var"#s9"} where var"#s9"<:StdVector, CxxWrap.CxxWrapCore.SmartPointer{var"#s8"} where var"#s8"<:StdVector, StdVector}, ::Any) at /home/colinxs/.julia/packages/CxxWrap/OcN1Z/src/CxxWrap.jl:808

I've tried various combinations returning a reference, dereferencing etc. but no luck. Any suggestions?

colinxs avatar Jul 29 '21 07:07 colinxs

Ran into a similar error on CxxWrap 0.13.4:

ERROR: MethodError: no method matching push_back(::CxxWrap.StdLib.StdVectorDereferenced{CxxWrap.StdLib.SharedPtr{
ray_core_worker_julia_jll.LocalMemoryBuffer}}, ::CxxWrap.CxxWrapCore.CxxRef{ray_core_worker_julia_jll.LocalMemory
Buffer})

Closest candidates are:
  push_back(!Matched::Union{CxxWrap.StdLib.StdVector{Any}, CxxWrap.CxxWrapCore.CxxRef{<:CxxWrap.StdLib.StdVector{
Any}}}, ::Any)
   @ CxxWrap ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:624
  push_back(!Matched::Union{Ptr{Nothing}, CxxWrap.CxxWrapCore.CxxPtr{<:CxxWrap.StdLib.StdVector{Any}}}, ::Any)
   @ CxxWrap ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:624
  push_back(::Union{CxxWrap.StdLib.StdVector{CxxWrap.StdLib.SharedPtr{ray_core_worker_julia_jll.LocalMemoryBuffer
}}, CxxWrap.CxxWrapCore.CxxRef{<:CxxWrap.StdLib.StdVector{CxxWrap.StdLib.SharedPtr{ray_core_worker_julia_jll.LocalMemoryBuffer}}}}, !Matched::Union{CxxWrap.CxxWrapCore.ConstCxxRef{<:CxxWrap.StdLib.SharedPtr{ray_core_worker_julia_jll.LocalMemoryBuffer}}, CxxWrap.CxxWrapCore.CxxRef{<:CxxWrap.StdLib.SharedPtr{ray_core_worker_julia_jll.Local
MemoryBuffer}}, CxxWrap.CxxWrapCore.SmartPointer{T2} where T2<:ray_core_worker_julia_jll.LocalMemoryBuffer})
   @ ray_core_worker_julia_jll ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:624
...

We ended up working around this with:

function Base.push!(v::CxxPtr{StdVector{T}}, el::T) where T <: SharedPtr{LocalMemoryBuffer}
    return push!(v, CxxRef(el))
end

Note: we attempted to extend push_back but we seemingly couldn't add methods to that function.

omus avatar Aug 23 '23 15:08 omus