Skip to content

medyan-dev/MutatePlainDataArray.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MutatePlainDataArray.jl

Build Status

Enable mutating immutable plain data fields using aref wrapper, allowing mutating immutable plain data fields using the following syntax:

    aref(v)[i].a.b._i._j[] = val

The nested fields can be accessed using either the field name, or the field index prefixed with _. Except for the wrapped vector, every field in the chain must be immutable. The final type to be mutated must be bits type.

Examples:

julia> using MutatePlainDataArray

julia> a = [1, 2, 3];

julia> aref(a)[1][] = 4
4

julia> a
3-element Vector{Int64}:
 4
 2
 3

julia> b = [(tup=(1, 2.5), s="a"), (tup=(2, 4.5), s="b")];
 
julia> aref(b)[1].tup._2[] = Inf
Inf

julia> b
2-element Vector{NamedTuple{(:tup, :s), Tuple{Tuple{Int64, Float64}, String}}}:
 (tup = (1, Inf), s = "a")
 (tup = (2, 4.5), s = "b")

julia> aref(b)[2]._1._1[] *= 100
200

julia> b
2-element Vector{NamedTuple{(:tup, :s), Tuple{Tuple{Int64, Float64}, String}}}:
 (tup = (1, Inf), s = "a")
 (tup = (200, 4.5), s = "b")

julia> aref(b)[1].s[] = "invalid"
ERROR: The field type String (field s in NamedTuple{(:tup, :s), Tuple{Tuple{Int64, Float64}, String}}) is not immutable.
Stacktrace:
 ...

The mutation provided by this package is

  • Efficient. Under the hood, the mutation is achieved by pointer load/store, where the address offset is known at type inference time.
  • Safe. Compile-time type check is enforced. Reference to the original vector is obtained to prevent garbage collection. Bounds check is performed unless @inbounds is used. This package is inspired by and acts as a safer counterpart to UnsafePointers.jl.