Skip to content

Commit 6975d6d

Browse files
authored
specialize reshape, ensuring it returns FixedSizeArray (#41)
This is analogous with the behavior for `Array` and should make type stability easier for some uses.
1 parent 7bccccc commit 6975d6d

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/FixedSizeArrays.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,14 @@ Base.unsafe_convert(::Type{Ptr{T}}, a::FixedSizeArray{T}) where {T} = Base.unsaf
160160

161161
Base.elsize(::Type{A}) where {A<:FixedSizeArray} = Base.elsize(parent_type(A))
162162

163+
# `reshape`: specializing it to ensure it returns a `FixedSizeArray`
164+
165+
function Base.reshape(a::FixedSizeArray{T}, size::NTuple{N,Int}) where {T,N}
166+
len = checked_dims(size)
167+
if length(a) != len
168+
throw(DimensionMismatch("new shape not consistent with existing array length"))
169+
end
170+
FixedSizeArray{T,N}(Internal(), a.mem, size)
171+
end
172+
163173
end # module FixedSizeArrays

test/runtests.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,36 @@ end
301301
end
302302
end
303303
end
304+
305+
@testset "`reshape`" begin
306+
length_to_shapes = Dict(
307+
(0 => ((0,), (0, 0), (0, 1), (1, 0), (1, 0, 0), (0, 0, 1))),
308+
(1 => ((), (1,), (1, 1), (1, 1, 1))),
309+
(2 => ((2,), (1, 2), (2, 1), (1, 2, 1))),
310+
(3 => ((3,), (1, 3), (3, 1), (1, 3, 1))),
311+
(4 => ((4,), (1, 4), (4, 1), (2, 2), (1, 2, 2), (2, 1, 2))),
312+
(6 => ((6,), (1, 6), (6, 1), (2, 3), (3, 2), (1, 3, 2), (2, 1, 3))),
313+
)
314+
for elem_type (Int, Number, Union{Nothing,Int})
315+
for len keys(length_to_shapes)
316+
shapes = length_to_shapes[len]
317+
for shape1 shapes
318+
a = FixedSizeArray{elem_type,length(shape1)}(undef, shape1)
319+
@test_throws DimensionMismatch reshape(a, length(a)+1)
320+
@test_throws DimensionMismatch reshape(a, length(a)+1, 1)
321+
@test_throws DimensionMismatch reshape(a, 1, length(a)+1)
322+
for shape2 shapes
323+
@test prod(shape1) === prod(shape2) === len # meta
324+
T = FixedSizeArray{elem_type,length(shape2)}
325+
test_inferred_noalloc(reshape, T, (a, shape2))
326+
test_inferred_noalloc(reshape, T, (a, shape2...))
327+
b = reshape(a, shape2)
328+
@test size(b) === shape2
329+
@test a.mem === b.mem
330+
@test a === reshape(b, shape1)
331+
end
332+
end
333+
end
334+
end
335+
end
304336
end

0 commit comments

Comments
 (0)