Reference
MemoryViews.DelimitedIterator
— TypeIterator struct created by split_each
. Type and parameters are public, but otherwise the interface is defined by split_each
,
MemoryViews.Immutable
— TypeTrait struct, only used in the mutability parameter of MemoryView
MemoryViews.IsMemory
— TypeIsMemory{T <: MemoryView} <: MemoryKind
See: MemoryKind
MemoryViews.MemoryKind
— TypeMemoryKind
Trait 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:
M
is a concrete subtype ofMemoryView
. To obtainM
from anm::IsMemory{M}
, useinner(m)
.MemoryView(::T)
is a valid instance ofM
(except in cases where there can be invalid instances ofT
that instead errors, e.g. uninitialized instances).MemoryView(x) == x
for 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
— TypeMemoryView{T, M} <: DenseVector{T}
View into a Memory{T}
. Construct from memory-backed values x
with MemoryView(x)
.
MemoryView
s 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}
true
Extended 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 aMutableMemoryView
when the memory ofx
is mutable.MemoryKind(x::T)
, ifT
is 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 String
s, may be stored as pointers, and isbits Union optimisations.
MemoryViews.Mutable
— TypeTrait struct, only used in the mutability parameter of MemoryView
MemoryViews.MutableMemoryView
— MethodMutableMemoryView(::Unsafe, x::MemoryView)
Convert a memory view into a mutable memory view. Note that it may cause undefined behaviour, if supposedly immutable data is observed to be mutated.
MemoryViews.NotMemory
— TypeNotMemory <: MemoryKind
See: MemoryKind
MemoryViews.Unsafe
— TypeUnsafe
Trait object used to dispatch to unsafe methods. The MemoryViews.unsafe
instance is the singleton instance of this type.
MemoryViews.inner
— MethodMemoryViews.split_at
— Methodsplit_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 BoundsError
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
— Methodsplit_each(data, x::T)
Return an iterator over memory-backed data data
of eltype T
. Returns MemoryView
s 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
— Methodsplit_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 BoundsError
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: BoundsError: attempt to access 0-element MutableMemoryView{UInt8} at index [1]
[...]
MemoryViews.split_last
— Methodsplit_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 BoundsError
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: BoundsError: attempt to access 0-element MutableMemoryView{UInt8} at index [1]
[...]
MemoryViews.split_unaligned
— Methodsplit_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.
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
— Methodunsafe_from_parts(ref::MemoryRef{T}, len::Int)::MutableMemoryView{T}
Create a mutable memory view from its parts.
Safety: Callers are responsible to ensure that:
len
is not negative- All indices
i in 1:len
are valid forref
(i.e.memoryref(ref, i)
would not throw) - If
ref
is derived from immutable memory, the returned memory view must not be mutated. The caller should immediately convert it to an immutable view.
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