Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ uuid = "3821ddf9-e5b5-40d5-8e25-6813ab96b5e2"
authors = ["Mosè Giordano <[email protected]>"]
version = "0.1.0"

[deps]
CheckedSizeProduct = "1b2cc9da-92e3-4b71-9788-30fc110eefda"

[compat]
CheckedSizeProduct = "1"
julia = "1.10"
37 changes: 14 additions & 23 deletions src/FixedSizeArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,32 +96,23 @@ Base.isassigned(a::FixedSizeArray, i::Int) = isassigned(a.mem, i)

# safe product of a tuple of integers, for calculating dimensions size

checked_dims_impl(a::Int, ::Tuple{}, have_overflow::Bool) = (a, have_overflow)
function checked_dims_impl(a::Int, t::Tuple{Int,Vararg{Int,N}}, have_overflow::Bool) where {N}
b = first(t)
(m, o) = Base.Checked.mul_with_overflow(a, b)
r = Base.tail(t)::NTuple{N,Int}
checked_dims_impl(m, r, have_overflow | o)::Tuple{Int,Bool}
end

checked_dims(::Tuple{}) = 1
function checked_dims(t::Tuple{Int,Vararg{Int,N}}) where {N}
any_is_zero = any(iszero, t)::Bool
any_is_negative = any((x -> x < false), t)::Bool
any_is_typemax = any((x -> x == typemax(x)), t)::Bool
a = first(t)
r = Base.tail(t)::NTuple{N,Int}
(product, have_overflow) = checked_dims_impl(a, r, false)::Tuple{Int,Bool}
if any_is_negative
throw(ArgumentError("array dimension size can't be negative"))
end
if any_is_typemax
throw(ArgumentError("array dimension size can't be the maximum representable value"))
end
if have_overflow & !any_is_zero
throw(ArgumentError("array dimensions too great, can't represent length"))
product = checked_size_product(t)
if product isa Int
product
else
if product.any_is_negative
throw(ArgumentError("array dimension size can't be negative"))
end
if product.any_is_typemax
throw(ArgumentError("array dimension size can't be the maximum representable value"))
end
if product.is_not_representable
throw(ArgumentError("array dimensions too great, can't represent length"))
end
throw(ArgumentError("unexpected"))
end
product
end

# broadcasting
Expand Down
2 changes: 2 additions & 0 deletions src/FixedSizeArrays.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module FixedSizeArrays

using CheckedSizeProduct

const default_underlying_storage_type = (@isdefined Memory) ? Memory : Vector

const optional_memory = (@isdefined Memory) ? (Memory,) : ()
Expand Down
Loading