Reference
MemoryViews.DelimitedIterator — Type
Iterator struct created by split_each.
Type and parameters are public, but otherwise the interface is defined by split_each,
MemoryViews.Immutable — Type
Trait struct, only used in the mutability parameter of MemoryView
MemoryViews.IsMemory — Type
IsMemory{T <: MemoryView} <: MemoryKindSee: MemoryKind
MemoryViews.MemoryKind — Type
MemoryKindTrait object used to signal if values of a type is semantically equal to their own MemoryView.
If so, MemoryKind(T) should return an instance of IsMemory,
else NotMemory(). The default implementation MemoryKind(::Type) returns NotMemory().
If MemoryKind(T) isa IsMemory{M}, the following must hold:
Mis a concrete subtype ofMemoryView. To obtainMfrom anm::IsMemory{M}, useinner(m).MemoryView(::T)is a valid instance ofM(except in cases where there can be invalid instances ofTthat instead errors, e.g. uninitialized instances).MemoryView(x) == xfor all instancesx::T
Some objects can be turned into MemoryView without being IsMemory.
For example, MemoryView(::String) returns a valid MemoryView even though
MemoryKind(String) === NotMemory().
This is because strings have different semantics than memory views - the latter
is a dense AbstractArray while strings are not, and so the fourth requirement
MemoryView(x::String) == x does not hold.
See also: MemoryView
MemoryViews.MemoryView — Type
MemoryView{T, M} <: DenseVector{T}View into a Memory{T}.
Construct from memory-backed values x with MemoryView(x).
MemoryViews are guaranteed to point to contiguous, valid CPU memory,
except where they have size zero.
The parameter M controls the mutability of the memory view,
and may be Mutable or Immutable, corresponding to the
the aliases MutableMemoryView{T} and ImmutableMemoryView{T}.
See also: MemoryKind
Examples
julia> v = view([1, 2, 3, 4], 2:3);
julia> mem = MemoryView(v)
2-element MutableMemoryView{Int64}:
2
3
julia> MemoryView(codeunits("abc")) isa ImmutableMemoryView{UInt8}
trueExtended help
New types T which are backed by dense memory should implement:
MemoryView(x::T)to construct a memory view fromx. This should always return aMutableMemoryViewwhen the memory ofxis mutable.MemoryKind(x::T), ifTis semantically equal to its own memory view. Examples of this includeVector,Memory, andBase.CodeUnits{UInt8, String}. If so,x == MemoryView(x)should hold.
If MemoryView(x) is implemented, then ImmutableMemoryView(x) will
automatically work, even if MemoryView(x) returns a mutable view.
It is not possible to mutate memory though an ImmutableMemoryView, but the existence
of the view does not protect the same memory from being mutated though another
variable, or through explicitly unsafe functions.
The precise memory layout of the data in a MemoryView follows that of Memory.
This includes the fact that some elements in the array, such as Strings,
may be stored as pointers, and [isbits Union optimisations]
(https://docs.julialang.org/en/v1/devdocs/isbitsunionarrays/).
MemoryViews.Mutable — Type
Trait struct, only used in the mutability parameter of MemoryView
MemoryViews.NotMemory — Type
NotMemory <: MemoryKindSee: MemoryKind
Core.memoryref — Method
Base.memoryref(x::MemoryView{T})::MemoryRef{T}Get the MemoryRef of x. This reference is guaranteed to be inbounds,
except if x is empty, where it may point to one element past the end.
MemoryViews.inner — Method
MemoryViews.split_at — Method
split_at(v::T, i::Int) -> Tuple{T, T} where {T <: MemoryView}Split a memory view into two at an index.
The first will contain all indices in 1:i-1, the second i:end.
This function will throw a LightBoundsError if i is not in 1:end+1.
Examples
julia> split_at(MemoryView([1,2,3,4,5]), 2)
([1], [2, 3, 4, 5])
julia> split_at(MemoryView(Int8[1, 2, 3]), 4)
(Int8[1, 2, 3], Int8[])MemoryViews.split_each — Method
split_each(data, x::T)Return an iterator over memory-backed data data of eltype T.
Returns MemoryViews of the same elements as data, separated by by x.
Items are compared by isequal.
An empty input data yields no elements. Empty elements are otherwise
yielded.
Examples
julia> split_each(b"abbc", UInt8('b')) |> collect |> print
ImmutableMemoryView{UInt8}[[0x61], [], [0x63]]
julia> split_each(b"babceb", UInt8('b')) |> collect |> print
ImmutableMemoryView{UInt8}[[], [0x61], [0x63, 0x65], []]
julia> split_each(UInt8[], UInt8('b')) |> collect |> print
MutableMemoryView{UInt8}[]MemoryViews.split_first — Method
split_first(v::MemoryView{T}) -> Tuple{T, MemoryView{T}}Return the first element of v and all other elements as a new memory view.
This function will throw a LightBoundsError if v is empty.
See also: split_last
Examples
julia> v = MemoryView([0x01, 0x02, 0x03]);
julia> split_first(v)
(0x01, UInt8[0x02, 0x03])
julia> split_first(v[1:1])
(0x01, UInt8[])
julia> split_first(v[1:0])
ERROR: LightBoundsErrors.LightBoundsError: out-of-bounds indexing: `collection[1]`, where:
[...]MemoryViews.split_last — Method
split_last(v::MemoryView{T}) -> Tuple{T, MemoryView{T}}Return the last element of v and all other elements as a new memory view.
This function will throw a LightBoundsError if v is empty.
See also: split_first
Examples
julia> v = MemoryView([0x01, 0x02, 0x03]);
julia> split_last(v)
(0x03, UInt8[0x01, 0x02])
julia> split_last(v[1:1])
(0x01, UInt8[])
julia> split_last(v[1:0])
ERROR: LightBoundsErrors.LightBoundsError: out-of-bounds indexing: `collection[1]`, where:
[...]MemoryViews.split_unaligned — Method
split_unaligned(v::T, ::Val{A}) -> Tuple{T, T} where {T <: MemoryView}Split memory view v into two views a and b, where a is the smallest prefix of v
that guarantees the starting memory address of b is is aligned to the integer value A.
A must be a normal bit-integer, and a power of two in the range 1:64.
If v is empty or already aligned, a will be empty.
If no elements of v is aligned, b will be empty and a will be equal to v.
The element type of v must be a bitstype.
When using this function, make sure to GC.@preserve v, to make sure Julia
does not move v in memory.
Examples:
julia> split_unaligned(MemoryView(Int16[1, 2, 3]), Val(8))
(Int16[], Int16[1, 2, 3])
julia> split_unaligned(MemoryView(collect(0x01:0x20))[6:13], Val(8))
(UInt8[0x06, 0x07, 0x08], UInt8[0x09, 0x0a, 0x0b, 0x0c, 0x0d])MemoryViews.unsafe_from_parts — Method
unsafe_from_parts(ref::MemoryRef{T}, len::Int)::MutableMemoryView{T}Create a mutable memory view from its parts.
Safety: Callers are responsible to ensure that:
lenis not negativeAll indices
i in 1:lenare valid forref(i.e.memoryref(ref, i)would not throw)If
refis derived from immutable memory, it is the caller's responsibility to ensure that mutating the memory does not result in undefined behaviour. For example,refmay be derived from aString, and mutatingStrings in Julia may result in undefined behaviour.
Examples
julia> v = [1,2,3,4];
julia> ref = Base.cconvert(Ptr, v);
julia> view = unsafe_from_parts(ref, 3)
3-element MutableMemoryView{Int64}:
1
2
3