Reference

MemoryViews.MemoryKindType
MemoryKind

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:

  1. M is a concrete subtype of MemoryView. To obtain M from an m::IsMemory{M}, use inner(m).
  2. MemoryView(T) is a valid instance of M.
  3. MemoryView(x) == x for all instances x::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.MemoryViewType
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}
true

Extended help

New types T which are backed by dense memory should implement:

  • MemoryView(x::T) to construct a memory view from x. This should always return a MutableMemoryView when the memory of x is mutable.
  • MemoryKind(x::T), if T is semantically equal to its own memory view. Examples of this include Vector, Memory, and Base.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.

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.

MemoryViews.MutableMemoryViewMethod
MutableMemoryView(::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.UnsafeType
Unsafe

Trait object used to dispatch to unsafe methods. The MemoryViews.unsafe instance is the singleton instance of this type.

MemoryViews.split_atMethod
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 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_firstMethod
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 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_lastMethod
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 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_unalignedMethod
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.

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])