MutatePlainDataArray.jl

Mutate bits data in arrays.
Author medyan-dev
Popularity
2 Stars
Updated Last
10 Months Ago
Started In
May 2022

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.