Skip to content
This repository has been archived by the owner on May 4, 2019. It is now read-only.

Commit

Permalink
Add in-line docstring documentation
Browse files Browse the repository at this point in the history
This commit also removes design notes and code section delineators in preparation for a release version.
  • Loading branch information
davidagold committed Sep 14, 2015
1 parent 79ea444 commit fcc9529
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 95 deletions.
31 changes: 24 additions & 7 deletions src/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ function Base.broadcast!(f, X::NullableArray; lift::Bool=false)
end

@eval let cache = Dict{Any, Dict{Bool, Dict{Int, Dict{Int, Any}}}}()
@doc """
`broadcast!(f, B::NullableArray, As::NullableArray...; lift::Bool=false)`
This method implements the same behavior as that of `broadcast!` when called on
regular `Array` arguments. It also includes the `lift` keyword argument, which
when set to true will lift `f` over the entries of the `As`. Lifting is
disabled by default. Note that this method's signature specifies the destination
`B` array as well as the source `As` arrays as all `NullableArray`s.
Thus, calling `broadcast!` on a arguments consisting of both `Array`s and
`NullableArray`s will fall back to the implementation of `broadcast!` in
`base/broadcast.jl`.
""" ->
function Base.broadcast!(f, B::NullableArray, As::NullableArray...; lift::Bool=false)
nd = ndims(B)
narrays = length(As)
Expand All @@ -74,19 +86,24 @@ end
end
end # let cache

@doc """
`broadcast(f, As::NullableArray...;lift::Bool=false)`
This method implements the same behavior as that of `broadcast` when called on
regular `Array` arguments. It also includes the `lift` keyword argument, which
when set to true will lift `f` over the entries of the `As`. Lifting is
disabled by default. Note that this method's signature specifies the source
`As` arrays as all `NullableArray`s. Thus, calling `broadcast!` on a arguments
consisting of both `Array`s and `NullableArray`s will fall back to the
implementation of `broadcast` in `base/broadcast.jl`.
""" ->
function Base.broadcast(f, As::NullableArray...;lift::Bool=false)
return broadcast!(f, NullableArray(eltype(Base.promote_eltype(As...)),
Base.Broadcast.broadcast_shape(As...)),
As...; lift=lift)
end

#----- broadcasted binary operations -----------------------------------------#

# The following require specialized implementations because the base/broadcast
# methods return BitArrays instead of similars of the arguments.
# An alternative to the following implementations is simply to let the base
# implementations use convert(::Type{Bool}, ::Nullable{Bool}), but this is
# slower.
# broadcasted ops
for (op, scalar_op) in (
(:(Base.(:(.==))), :(==)),
(:(Base.(:.!=)), :!=),
Expand Down
43 changes: 34 additions & 9 deletions src/indexing.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
# NullableArray is dense and allows fast linear indexing.
import Base: LinearFast

#----- GENERAL INDEXING METHODS ----------------------------------------------#

Base.linearindexing{T <: NullableArray}(::Type{T}) = LinearFast()

# resolve ambiguity created by the two definitions that follow.
function Base.getindex{T, N}(X::NullableArray{T, N})
return X
end

@doc """
`getindex{T, N}(X::NullableArray{T, N}, I::Int...)`
Retrieve a single entry from a `NullableArray`. If the value in the entry
designated by `I` is present, then it will be returned wrapped in a
`Nullable{T}` container. If the value is missing, then this method returns
`Nullable{T}()`.
""" ->
# Extract a scalar element from a `NullableArray`.
@inline function Base.getindex{T, N}(X::NullableArray{T, N}, I::Int...)
if isbits(T)
Expand All @@ -23,13 +29,28 @@ end
end
end

@doc """
`getindex{T, N}(X::NullableArray{T, N}, I::Nullable{Int}...)`
Just as above, with the additional behavior that this method throws an error if
any component of the index `I` is null.
""" ->
@inline function Base.getindex{T, N}(X::NullableArray{T, N},
I::Nullable{Int}...)
anynull(I) && throw(NullException())
values = [ get(i) for i in I ]
return getindex(X, values...)
end

@doc """
`setindex!(X::NullableArray, v::Nullable, I::Int...)`
Set the entry of `X` at position `I` equal to a `Nullable` value `v`. If
`v` is null, then only `X.isnull` is updated to indicate that the entry at
index `I` is null. If `v` is not null, then `X.isnull` is updated to indicate
that the entry at index `I` is present and `X.values` is updated to store the
value wrapped in `v`.
""" ->
# Insert a scalar element from a `NullableArray` from a `Nullable` value.
@inline function Base.setindex!(X::NullableArray, v::Nullable, I::Int...)
if isnull(v)
Expand All @@ -41,15 +62,20 @@ end
return v
end

@doc """
`setindex!(X::NullableArray, v::Any, I::Int...)`
Set the entry of `X` at position `I` equal to `v`. This method always updates
`X.isnull` to indicate that the entry at index `I` is present and `X.values`
to store `v` at `I`.
""" ->
# Insert a scalar element from a `NullableArray` from a non-Nullable value.
@inline function Base.setindex!(X::NullableArray, v::Any, I::Int...)
X.values[I...] = v
X.isnull[I...] = false
return v
end

#----- UNSAFE INDEXING METHODS -----------------------------------------------#

function unsafe_getindex_notnull(X::NullableArray, I::Int...)
return Nullable(getindex(X.values, I...))
end
Expand All @@ -58,8 +84,6 @@ function unsafe_getvalue_notnull(X::NullableArray, I::Int...)
return getindex(X.values, I...)
end

# ----- Base._checkbounds ----------------------------------------------------#

function Base.checkbounds{T<:Real}(::Type{Bool}, sz::Int, x::Nullable{T})
isnull(x) ? throw(NullException()) : checkbounds(Bool, sz, get(x))
end
Expand All @@ -79,15 +103,16 @@ function Base.checkbounds{T<:Real}(::Type{Bool}, sz::Int, I::NullableArray{T})
return inbounds
end

# ----- Base.to_index --------------------------------------------------------#

function Base.to_index(X::NullableArray)
anynull(X) && throw(NullException())
Base.to_index(X.values)
end

# ----- nullify! --------------------------------------------------------------#
@doc """
`nullify!(X::NullableArray, I...)`
This is a convenience method to set the entry of `X` at index `I` to be null
""" ->
function nullify!(X::NullableArray, I...)
setindex!(X, Nullable{eltype(X)}(), I...)
end
18 changes: 16 additions & 2 deletions src/map.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Base.Cartesian

# utilities

function gen_nullcheck(narrays::Int)
As = [symbol("A_"*string(i)) for i = 1:narrays]
e_nullcheck = :($(As[1]).isnull[i])
Expand Down Expand Up @@ -131,6 +129,14 @@ end

# Base.map!
@eval let cache = Dict{Bool, Dict{Int, Dict{Base.Callable, Function}}}()
@doc """
`map!{F}(f::F, dest::NullableArray, As::AbstractArray...; lift::Bool=false)`
This method implements the same behavior as that of `map!` when called on
regular `Array` arguments. It also includes the `lift` keyword argument, which
when set to true will lift `f` over the entries of the `As`. Lifting is
disabled by default.
""" ->
function Base.map!{F}(f::F, dest::NullableArray, As::AbstractArray...;
lift::Bool=false)
narrays = length(As)
Expand All @@ -148,6 +154,14 @@ Base.map!{F}(f::F, X::NullableArray; lift::Bool=false) = map!(f, X, X; lift=lift

# Base.map
@eval let cache = Dict{Int, Dict{Base.Callable, Function}}()
@doc """
`map{F}(f::F, As::AbstractArray...; lift::Bool=false)`
This method implements the same behavior as that of `map!` when called on
regular `Array` arguments. It also includes the `lift` keyword argument, which
when set to true will lift `f` over the entries of the `As`. Lifting is
disabled by default.
""" ->
function Base.map{F}(f::F, As::NullableArray...; lift::Bool=false)
narrays = length(As)
_map_to! = gensym()
Expand Down
Loading

0 comments on commit fcc9529

Please sign in to comment.