Skip to content

use CheckedSizeProduct.jl for implementing checked_dims #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
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 <mose@gnu.org>"]
version = "0.1.0"

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

[compat]
CheckedSizeProduct = "1"
julia = "1.10"
29 changes: 7 additions & 22 deletions src/FixedSizeArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,32 +96,17 @@ 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
product = checked_size_product(t)
if product isa Int
product
else
if product isa CheckedSizeProduct.StatusInvalidValue
throw(ArgumentError("invalid array dimension size, can't be negative or the maximum representable value"))
end
throw(ArgumentError("array dimensions too great, can't represent length"))
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