heyx3 / Bplus.jl

A modern OpenGL 4.6 rendering framework, written in Julia.
Other
69 stars 3 forks source link

Support broadcasting for `Vec` #71

Open heyx3 opened 12 months ago

heyx3 commented 12 months ago

It should work similarly to StaticArrays, usable entirely on the stack and generally type-stable.

I tried this before, but it turns out the implementation of broadcasting is really complicated.

heyx3 commented 10 months ago

ChatGPT suggested the following to support broadcasting:

struct Vec{N, T}
    data::NTuple{N, T}
end

# Broadcasting support
Base.BroadcastStyle(::Type{<:Vec}) = Broadcast.ArrayStyle{Vec}()
Base.broadcastable(v::Vec) = v.data
Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{Vec}}, ::Type{ElType}) where {ElType} =
    Vec{length(bc.args[1].data), ElType}(ntuple(i -> Base.similar(bc.args[1].data[i]), length(bc.args[1].data)))
Base.copyto!(dest::Vec, bc::Base.Broadcast.Broadcasted{Nothing}) = copyto!(dest.data, bc)

# Example usage
v1 = Vec((1, 2, 3))
v2 = Vec((4, 5, 6))
v3 = v1 .+ v2

Here, the BroadcastStyle function tells the broadcasting mechanism to use a custom style for Vec, and the broadcastable function tells it how to access the data of a Vec for broadcasting (by just using the underlying tuple). The similar function tells it how to create a new Vec to hold the result of a broadcasting operation, and copyto! tells it how to perform the actual broadcasting operation.

By implementing these functions, you can make your Vec type behave with broadcasting just like a tuple. You may need to modify the example to exactly match your requirements, but it should give you a good starting point.