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

Clean up the separation of a sized value and a C++ type

Open r9y9 opened this issue 8 years ago • 7 comments

I'm having a trouble with multiple dispatch with nested Cxx templated types (e.g. StdVector{StdVector{T}}). A minimum illustration of the problem is as follows:

julia> import CxxStd: StdVector
julia> f{T}(v::StdVector{StdVector{T}}) = println("vector of vectors")
julia> vv = icxx"std::vector<std::vector<double>>();";
julia> f(vv)
ERROR: MethodError: `f` has no method matching f(::Cxx.CppValue{Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::vector")},Tuple{Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::vector")},Tuple{Float64,Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::allocator")},Tuple{Float64}},(false,false,false)}}},(false,false,false)},Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::allocator")},Tuple{Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::vector")},Tuple{Float64,Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::allocator")},Tuple{Float64}},(false,false,false)}}},(false,false,false)}}},(false,false,false)}}},(false,false,false)},24})

Dispatching with non-nested types works as expected:

julia> f(v::StdVector) = println("vector")
julia> v = icxx"std::vector<double>();";
julia> f(v)
vector

Would it be possible to dispatch with nested Cxx templated types like StdVector{StdVector{T}}?

FYI:

julia> v = icxx"std::vector<double>();";
julia> isa(v, StdVector{Cdouble})
true
julia> vv = icxx"std::vector<std::vector<double>>();";
julia> isa(vv, StdVector{StdVector{Cdouble}})
false
julia> isa(vv, StdVector{StdVector})
false
julia> isa(vv, cxxt"std::vector<std::vector<double>>")
true

In julia arrays, it works as expected:

julia> x = Vector{Float64}();
julia> isa(x, Vector{Float64})
true
julia> xx = Vector{Vector{Float64}}();
julia> isa(xx, Vector{Vector{Float64}})
true

r9y9 avatar Jan 06 '16 06:01 r9y9

I think the following should work:

f{T}(v::StdVector{StdVector{T}}) = println("vector of vectors")

Keno avatar Jan 06 '16 12:01 Keno

oops, sorry I meant the one that you pointed out, but it didn't work to me. Updated issue description.

I haven't tried the latest Cxx.jl since I wasn't able to build it. I'm using a bit old Cxx.jl ff0bec6 (sorry if this doesn't happen on the latest Cxx.jl).

r9y9 avatar Jan 06 '16 12:01 r9y9

Hmm, I'll take a look later today.

Keno avatar Jan 06 '16 12:01 Keno

For the record, I built the latest Cxx.jl (https://github.com/Keno/Cxx.jl/commit/bce1fdf7b354f3984d9dd39ae83fd6f9e6ef9930) on top of Julia master (https://github.com/JuliaLang/julia/commit/d4749d2ca168413f3db659950a1855530b58686d) based on llvm 3.7.1 and confirmed that this behavior still happens.

r9y9 avatar Jan 16 '16 09:01 r9y9

Unfortunately there is no good way to encode this currently because the StdVector type needs to encode size information, but the type parameter itself does not. I may try to fix this when I revisit the type hierarchy mapping, but for now it's not quite possible.

Keno avatar Feb 23 '16 00:02 Keno

I see. Thank you for the clarification.

r9y9 avatar Feb 23 '16 03:02 r9y9

The plan is to fix this by introducing derived type parameters in Base, so you could write:

type CxxValue{T}
    data::NTuple{UInt8,cxxsizeof(T)}
end

Keno avatar Jun 25 '16 23:06 Keno