@@ -47,29 +47,32 @@ Base.isassigned(a::FixedSizeArray, i::Int) = isassigned(a.mem, i)
47
47
48
48
# safe product of a tuple of integers, for calculating dimensions size
49
49
50
- checked_dims_impl (a:: Int , :: Tuple{} ) = a
51
- function checked_dims_impl (a:: Int , t:: Tuple{Int,Vararg{Int,N}} ) where {N}
50
+ checked_dims_impl (a:: Int , :: Tuple{} , have_overflow :: Bool ) = (a, have_overflow)
51
+ function checked_dims_impl (a:: Int , t:: Tuple{Int,Vararg{Int,N}} , have_overflow :: Bool ) where {N}
52
52
b = first (t)
53
- tmax = typemax (a)
54
- if (a == tmax) || (b == tmax)
55
- throw (ArgumentError (" array dimension size can't be the maximum representable value" ))
56
- end
57
- if (a < 0 ) || (b < 0 )
58
- throw (ArgumentError (" array dimension size can't be negative" ))
59
- end
60
53
(m, o) = Base. Checked. mul_with_overflow (a, b)
61
- if o
62
- throw (ArgumentError (" array dimensions too great, can't represent length" ))
63
- end
64
54
r = Base. tail (t):: NTuple{N,Int}
65
- checked_dims_impl (m, r):: Int
55
+ checked_dims_impl (m, r, have_overflow | o ):: Tuple{ Int,Bool}
66
56
end
67
57
68
58
checked_dims (:: Tuple{} ) = 1
69
59
function checked_dims (t:: Tuple{Int,Vararg{Int,N}} ) where {N}
60
+ any_is_zero = any (iszero, t):: Bool
61
+ any_is_negative = any ((x -> x < false ), t):: Bool
62
+ any_is_typemax = any ((x -> x == typemax (x)), t):: Bool
70
63
a = first (t)
71
64
r = Base. tail (t):: NTuple{N,Int}
72
- checked_dims_impl (a, r):: Int
65
+ (product, have_overflow) = checked_dims_impl (a, r, false ):: Tuple{Int,Bool}
66
+ if any_is_negative
67
+ throw (ArgumentError (" array dimension size can't be negative" ))
68
+ end
69
+ if any_is_typemax
70
+ throw (ArgumentError (" array dimension size can't be the maximum representable value" ))
71
+ end
72
+ if have_overflow & ! any_is_zero
73
+ throw (ArgumentError (" array dimensions too great, can't represent length" ))
74
+ end
75
+ product
73
76
end
74
77
75
78
# broadcasting
0 commit comments