Main API:

FieldViews.FieldViewableType
FieldViewable(array::AbstractArray{T,N}) :: FieldViewable{T,N,Store}

Wrap an array to enable zero-copy field access via properties.

FieldViewable provides a view-like interface for accessing individual fields of immutable structs stored in an array, without copying data. Field access returns FieldView objects that can be indexed and modified in-place, with changes reflected in the original array.

Requirements:

  • Element type T must be a concrete, immutable struct (but can have non-concrete, or mutable elements!)

Examples

struct Point{T}
    x::T
    y::T
    z::T
end

points = [Point(1.0, 2.0, 3.0), Point(4.0, 5.0, 6.0)]
fv = FieldViewable(points)

# Access field views
fv.x  # Returns FieldView{:x, Float64, ...}
fv.x[1]  # Returns 1.0

# Modify in-place (modifies original array)
fv.x[1] = 10.0
points[1].x  # Now 10.0

# Take views
slice = view(fv, 1:1)
slice.y[1] = 99.0
points[1].y  # Now 99.0

See also

  • FieldView: The view type returned by field property access
  • fieldmap: Customize field layout for nested structures
source
FieldViews.FieldViewType
FieldView{field}(parent::AbstractArray)

A view of a specific field across all elements in an array.

FieldView provides element-wise access to a single field of the structs in the parent array. For isbits fields and strided array containers, it uses efficient pointer methods for direct field access. For non-isbits fields, or non-strided arrays it uses a slower fallback which loads the full struct and extracts the field value.

Users typically obtain FieldView objects through property access on FieldViewable:

fv = FieldViewable(points)
x_view = fv.x  # Returns a FieldView{:x, ...}

Indexing

FieldView supports standard array indexing operations:

  • fv.x[i] - Get field value at index i
  • fv.x[i] = val - Set field value at index i (modifies parent array)

Examples

struct Data{T}
    value::T
    weight::Float64
end

arr = [Data(1, 0.5), Data(2, 1.5)]
fv = FieldViewable(arr)

# Access field view
values = fv.value  # FieldView{:value, Int64, ...}
values[1]  # 1

# Modify through view
fv.weight[2] = 2.0
arr[2].weight  # 2.0
source

Adaptions for custom types:

FieldViews.fieldmapFunction
fieldmap(::Type{T}) :: Tuple

Define the field layout for type T to be used by FieldViews.

Add methods to this function to customize how FieldViews accesses fields in your types. This is essential for:

  • Flattening nested structures
  • Renaming fields
  • Exposing only certain fields

Default Behavior

By default, returns fieldnames(T), exposing all fields with their original names.

Return Value

A tuple where each element is one of:

  • Symbol or Int: Direct field access
  • Pair{Symbol,Symbol}: Nested field (e.g., :outer => :inner)
  • Pair{Symbol,Renamed}: Nested field with rename
  • Renamed: Renamed direct field

Examples

Flattening nested structures

struct MyType{T}
    x::T
    rest::@NamedTuple{a::Int, b::Int}
end

function FieldViews.fieldmap(::Type{MyType{T}}) where T
    (:x, :rest => :a, :rest => :b)
end

fv = FieldViewable([MyType(1.0, (a=1, b=2))])
fv.a[1]  # Access nested field directly, returns 1

Renaming fields

struct Foo
    data::@NamedTuple{_internal::Int}
end

function FieldViews.fieldmap(::Type{Foo})
    (:data => Renamed(:_internal, :public),)
end

fv = FieldViewable([Foo((_internal=42,))])
fv.public[1]  # Returns 42

See also

source
FieldViews.RenamedType
Renamed(actual::Union{Int,Symbol}, alias::Symbol)

Specify a field rename in custom field mappings.

Used within fieldmap definitions to expose an internal field under a different name. This is useful when you want to expose a given field using a different name, or access Tuple fields (since their fields are just integers).

Arguments

  • actual: The real field name or field index in the struct
  • alias: The name to expose in the FieldViewable interface

Examples

struct Foo
    data::@NamedTuple{_x::Int, _y::Int}
end

function FieldViews.fieldmap(::Type{Foo})
    (:data => Renamed(:_x, :x), :data => Renamed(:_y, :y))
end

fv = FieldViewable([Foo((_x=1, _y=2))])
fv.x[1]  # Access via alias 'x', returns 1

See also

  • fieldmap: Define custom field layouts using Renamed
source
FieldViews.StridedArrayTraitType
StridedArrayTrait(::Type{T}) :: StridedArrayTrait
StridedArrayTrait(x) :: StridedArrayTrait

Query or define whether an array type has strided memory layout.

Returns IsStrided() if the array has constant stride offsets in memory, or Unknown() otherwise. Arrays which support IsStrided() auotmatically get more efficient getindex/setindex! implementations for their isbits fields.

IsStrided arrays must support pointer(v, i) methods, and linear indexing.

Default Behavior

  • StridedArray types return IsStrided()
  • Other AbstractArray types return Unknown()

Extending Support

To opt into the strided interface for a custom array type:

FieldViews.StridedArrayTrait(::Type{<:MyArrayType}) = FieldViews.IsStrided()

Examples

StridedArrayTrait(Vector{Int})  # IsStrided()
StridedArrayTrait(view([1,2,3,4], 1:2:4))  # IsStrided()
StridedArrayTrait(view([1,2,3,4], [1,3,4]))  # Unknown() - non-contiguous indices

A strided array is one where elements are stored at fixed offsets from each other in memory. For example, [1, 2, 3, 4] is strided, as is view(v, 1:2:4) (every other element), but view(v, [1, 3, 4]) is not strided (arbitrary indices).

See also

source
FieldViews.IsStridedType
IsStrided <: StridedArrayTrait

Trait indicating that an array type has strided (constant offset) memory layout.

Used by FieldViews to dispatch on array types that support efficient field access through pointer arithmetic.

See also

source
FieldViews.UnknownType
Unknown <: StridedArrayTrait

Trait indicating that an array type's memory layout is unknown or non-strided.

For arrays with this trait, FieldViews will fall back on accessing/modifying field elements by loading/storing the entire containing struct, and then using FieldLens to manipulate and set the required field. This can be slower in some circumstances.

See also

source

Utility

FieldViews.FieldLensType
FieldLens{field}

An optic for accessing and modifying a specific field of a struct.

FieldLens implements the lens interface from Accessors.jl, providing functional field access and immutable updates. It is primarily used internally by FieldViews for non-isbits field access, but can also be used directly with the Accessors.jl API.

Constructor

FieldLens(field::Union{Symbol,Int})
FieldLens{field}()

Examples

struct Point{T}
    x::T
    y::T
end

lens = FieldLens{:x}()

p = Point(1, 2)
lens(p)  # Get: returns 1

using Accessors
set(p, lens, 10)  # Set: returns Point(10, 2)

See also

  • Accessors.jl documentation for general lens usage
source

Dangerous tools

FieldViews.mappedfieldschemaFunction
mappedfieldschema(::Type{T}) -> NamedTuple

Compute the complete field schema for type T, computed using its fieldmap.

Returns a NamedTuple mapping field names (after renaming) to schema information containing:

  • lens: An optic for accessing the field
  • offset: Byte offset of the field in memory (for isbits fields)
  • type: The field's data type

This function processes the output of fieldmap to generate the internal schema used by FieldViews for efficient field access.

Examples

struct Point{T}
    x::T
    y::T
    z::T
end

schema = FieldViews.mappedfieldschema(Point{Float64})
# Returns: (x = (lens=..., offset=0, type=Float64),
#           y = (lens=..., offset=8, type=Float64),
#           z = (lens=..., offset=16, type=Float64))

schema.x.offset  # 0
schema.y.offset  # 8
schema.z.type    # Float64

Implementation Note

This is typically called internally by FieldViews and rarely needs to be called directly by users. Adding methods to mappedfieldschema incorrectly could cause undefined behaviour.

See also

  • fieldmap: The user-facing API for defining field layouts
source