Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 1 addition & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,13 @@ Exports these zero-dimensional subtypes of `AbstractArray`, differing on topics

* `ZeroDimArray`

* declared with `struct`, not with `mutable struct`

* does not support `setfield!`, or mutating the element otherwise

* `isbits` when the element is `isbits`

* `Box`

* declared with `mutable struct`

* supports `setfield!` for mutating the element

* acts as a reference to its element

* `BoxConst`

* declared with `mutable struct`

* does not support `setfield!`, or mutating the element otherwise

* acts as a reference to its element

* `ZeroDimArrayInTypeParameter`

* declared with `struct`, not with `mutable struct`

* does not support `setfield!`, or mutating the element otherwise

* each concrete subtype is `isbits` and is a singleton type

* the element is stored in a type parameter instead of in a field
See their doc strings for more info!

Any zero-dimensional array is an iterator containing exactly one element (this follows from the zero-dimensional shape). `Ref`, too, is a zero-dimensional iterator, however it's not an array. Even though `Ref` supports being indexed like a zero-dimensional array is commonly indexed, without an index: `x[]`.

Expand Down
153 changes: 153 additions & 0 deletions src/ZeroDimensionalArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,83 @@ export

abstract type AbstractZeroDimensionalArray{T} <: AbstractArray{T, 0} end

"""
ZeroDimArray

A collection type storing exactly one element. More precisely, a zero-dimensional
array, subtyping `AbstractArray{T, 0} where {T}`.

* Has a single type parameter:

* `T`, the element type

* Construct like so:

* `ZeroDimArray(element)`

* `ZeroDimArray{T}(element)`

* Convert from other array types with `convert`.

* Access the element using `getindex`. Julia supports the square bracket syntax for
`getindex`: `array[]` is equivalent to `getindex(array)`.

* After a `ZeroDimArray` is constructed, it is not possible to change the value of
its element.

* Regarding layout in memory, a `ZeroDimArray` is a copy of its element.

* For any `x`, `ZeroDimArray(x) === ZeroDimArray(x)` holds.

* For any `x`, `isbits(ZeroDimArray(x))` as long as `isbits(x)`.

Other exported collection types:

* [`Box`](@ref)

* [`BoxConst`](@ref)

* [`ZeroDimArrayInTypeParameter`](@ref)
"""
struct ZeroDimArray{T} <: AbstractZeroDimensionalArray{T}
v::T
global function new_zero_dimensional_array_immutable(::Type{T}, v) where {T}
new{T}(v)
end
end

"""
Box

A collection type storing exactly one element. More precisely, a zero-dimensional
array, subtyping `AbstractArray{T, 0} where {T}`.

* Has a single type parameter:

* `T`, the element type

* Construct like so:

* `Box(element)`

* `Box{T}(element)`

* Convert from other array types with `convert`.

* After a `Box` is constructed, change the value of its element using `setindex!`.
Julia supports the square bracket syntax for `setindex!`: `array[] = element` is
equivalent to `setindex!(array, element)`.

* Regarding layout in memory, a `Box` is a reference to its element.

Other exported collection types:

* [`BoxConst`](@ref)

* [`ZeroDimArray`](@ref)

* [`ZeroDimArrayInTypeParameter`](@ref)
"""
mutable struct Box{T} <: AbstractZeroDimensionalArray{T}
v::T
global function new_zero_dimensional_array_mutable(::Type{T}, v) where {T}
Expand All @@ -25,13 +95,96 @@ mutable struct Box{T} <: AbstractZeroDimensionalArray{T}
end
end

"""
BoxConst

A collection type storing exactly one element. More precisely, a zero-dimensional
array, subtyping `AbstractArray{T, 0} where {T}`.

* Has a single type parameter:

* `T`, the element type

* Construct like so:

* `BoxConst(element)`

* `BoxConst{T}(element)`

* Convert from other array types with `convert`.

* Access the element using `getindex`. Julia supports the square bracket syntax for
`getindex`: `array[]` is equivalent to `getindex(array)`.

* After a `BoxConst` is constructed, it is not possible to change the value of
its element.

* Regarding layout in memory, a `BoxConst` is a reference to its element.

Other exported collection types:

* [`Box`](@ref)

* [`ZeroDimArray`](@ref)

* [`ZeroDimArrayInTypeParameter`](@ref)
"""
mutable struct BoxConst{T} <: AbstractZeroDimensionalArray{T}
const v::T
global function new_zero_dimensional_array_mutable_const_field(::Type{T}, v) where {T}
new{T}(v)
end
end

"""
ZeroDimArrayInTypeParameter

A collection type storing exactly one element. More precisely, a zero-dimensional
array, subtyping `AbstractArray{T, 0} where {T}`.

* Has two type parameters:

* `T`, the element type

* `Value`, the element

* Construct like so:

* `ZeroDimArrayInTypeParameter(element)`

* `ZeroDimArrayInTypeParameter{T}(element)`

* Convert from other array types with `convert`.

* Access the element using `getindex`. Julia supports the square bracket syntax for
`getindex`: `array[]` is equivalent to `getindex(array)`.

* After a `ZeroDimArrayInTypeParameter` is constructed, it is not possible to
change the value of its element.

* As a `ZeroDimArrayInTypeParameter` stores its element in its type parameter, a
call like `ZeroDimArrayInTypeParameter(x)` might throw in type application if
Julia is not able to use `x` as a type parameter.

* For any `a`, `iszero(sizeof(a))` as long as `a isa ZeroDimArrayInTypeParameter`.

* For any `x`, `ZeroDimArrayInTypeParameter(x) === ZeroDimArrayInTypeParameter(x)`
holds.

* For any `x`, `isbits(ZeroDimArrayInTypeParameter(x))` as long as
`ZeroDimArrayInTypeParameter(x)` returns.

* For any `x`, `Base.issingletontype(typeof(ZeroDimArrayInTypeParameter(x)))` as
long as `ZeroDimArrayInTypeParameter(x)` returns.

Other exported collection types:

* [`Box`](@ref)

* [`BoxConst`](@ref)

* [`ZeroDimArray`](@ref)
"""
struct ZeroDimArrayInTypeParameter{T, Value} <: AbstractZeroDimensionalArray{T}
global function new_zero_dimensional_array_in_type_parameter(::Type{T}, v) where {T}
u = if v isa T
Expand Down