• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #38162

06 Aug 2025 08:25PM UTC coverage: 25.688% (-43.6%) from 69.336%
#38162

push

local

web-flow
fix runtime cglobal builtin function implementation (#59210)

This had failed to be updated for the LazyLibrary changes to codegen.

12976 of 50513 relevant lines covered (25.69%)

676965.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

3.0
/base/reshapedarray.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
using  Base.MultiplicativeInverses: SignedMultiplicativeInverse
4

5
struct ReshapedArray{T,N,P<:AbstractArray,MI<:Tuple{Vararg{SignedMultiplicativeInverse{Int}}}} <: AbstractArray{T,N}
6
    parent::P
7
    dims::NTuple{N,Int}
8
    mi::MI
9
end
10
ReshapedArray(parent::AbstractArray{T}, dims::NTuple{N,Int}, mi) where {T,N} = ReshapedArray{T,N,typeof(parent),typeof(mi)}(parent, dims, mi)
×
11

12
# IndexLinear ReshapedArray
13
const ReshapedArrayLF{T,N,P<:AbstractArray} = ReshapedArray{T,N,P,Tuple{}}
14

15
# Fast iteration on ReshapedArrays: use the parent iterator
16
struct ReshapedArrayIterator{I,M}
17
    iter::I
18
    mi::NTuple{M,SignedMultiplicativeInverse{Int}}
19
end
20
ReshapedArrayIterator(A::ReshapedArray) = _rs_iterator(parent(A), A.mi)
×
21
function _rs_iterator(P, mi::NTuple{M}) where M
×
22
    iter = eachindex(P)
×
23
    ReshapedArrayIterator{typeof(iter),M}(iter, mi)
×
24
end
25

26
struct ReshapedIndex{T}
27
    parentindex::T
28
end
29

30
# eachindex(A::ReshapedArray) = ReshapedArrayIterator(A)  # TODO: uncomment this line
31
@inline function iterate(R::ReshapedArrayIterator, i...)
×
32
    item, inext = iterate(R.iter, i...)
×
33
    ReshapedIndex(item), inext
×
34
end
35
length(R::ReshapedArrayIterator) = length(R.iter)
×
36
eltype(::Type{<:ReshapedArrayIterator{I}}) where {I} = @isdefined(I) ? ReshapedIndex{eltype(I)} : Any
×
37

38
@noinline throw_dmrsa(dims, len) =
×
39
    throw(DimensionMismatch(LazyString("new dimensions ", dims, " must be consistent with array length ", len)))
40

41
## reshape(::Array, ::Dims) returns a new Array (to avoid conditionally aliasing the structure, only the data)
42
# reshaping to same # of dimensions
43
@eval function reshape(a::Array{T,M}, dims::NTuple{N,Int}) where {T,N,M}
×
44
    len = Core.checked_dims(dims...) # make sure prod(dims) doesn't overflow (and because of the comparison to length(a))
×
45
    if len != length(a)
×
46
        throw_dmrsa(dims, length(a))
×
47
    end
48
    ref = a.ref
×
49
    # or we could use `a = Array{T,N}(undef, ntuple(i->0, Val(N))); a.ref = ref; a.size = dims; return a` here to avoid the eval
50
    return $(Expr(:new, :(Array{T,N}), :ref, :dims))
×
51
end
52

53
## reshape!(::Array, ::Dims) returns the original array, but must have the same dimensions and length as the original
54
# see also resize! for a similar operation that can change the length
55
function reshape!(a::Array{T,N}, dims::NTuple{N,Int}) where {T,N}
×
56
    len = Core.checked_dims(dims...) # make sure prod(dims) doesn't overflow (and because of the comparison to length(a))
×
57
    if len != length(a)
×
58
        throw_dmrsa(dims, length(a))
×
59
    end
60
    setfield!(a, :dims, dims)
×
61
    return a
×
62
end
63

64

65

66
"""
67
    reshape(A, dims...)::AbstractArray
68
    reshape(A, dims)::AbstractArray
69

70
Return an array with the same data as `A`, but with different
71
dimension sizes or number of dimensions. The two arrays share the same
72
underlying data, so that the result is mutable if and only if `A` is
73
mutable, and setting elements of one alters the values of the other.
74

75
The new dimensions may be specified either as a list of arguments or
76
as a shape tuple. At most one dimension may be specified with a `:`,
77
in which case its length is computed such that its product with all
78
the specified dimensions is equal to the length of the original array
79
`A`. The total number of elements must not change.
80

81
# Examples
82
```jldoctest
83
julia> A = Vector(1:16)
84
16-element Vector{Int64}:
85
  1
86
  2
87
  3
88
  4
89
  5
90
  6
91
  7
92
  8
93
  9
94
 10
95
 11
96
 12
97
 13
98
 14
99
 15
100
 16
101

102
julia> reshape(A, (4, 4))
103
4×4 Matrix{Int64}:
104
 1  5   9  13
105
 2  6  10  14
106
 3  7  11  15
107
 4  8  12  16
108

109
julia> reshape(A, 2, :)
110
2×8 Matrix{Int64}:
111
 1  3  5  7   9  11  13  15
112
 2  4  6  8  10  12  14  16
113

114
julia> reshape(1:6, 2, 3)
115
2×3 reshape(::UnitRange{Int64}, 2, 3) with eltype Int64:
116
 1  3  5
117
 2  4  6
118
```
119
"""
120
reshape
121

122
reshape(parent::AbstractArray, dims::IntOrInd...) = reshape(parent, dims)
×
123
reshape(parent::AbstractArray, shp::Tuple{Union{Integer,AbstractOneTo}, Vararg{Union{Integer,AbstractOneTo}}}) = reshape(parent, to_shape(shp))
×
124
# legacy method for packages that specialize reshape(parent::AbstractArray, shp::Tuple{Union{Integer,OneTo,CustomAxis}, Vararg{Union{Integer,OneTo,CustomAxis}}})
125
# leaving this method in ensures that Base owns the more specific method
126
reshape(parent::AbstractArray, shp::Tuple{Union{Integer,OneTo}, Vararg{Union{Integer,OneTo}}}) = reshape(parent, to_shape(shp))
×
127
reshape(parent::AbstractArray, dims::Tuple{Integer, Vararg{Integer}}) = reshape(parent, map(Int, dims))
×
128
reshape(parent::AbstractArray, dims::Dims)        = _reshape(parent, dims)
×
129

130
# Allow missing dimensions with Colon():
131
reshape(parent::AbstractVector, ::Colon) = parent
×
132
reshape(parent::AbstractVector, ::Tuple{Colon}) = parent
×
133
reshape(parent::AbstractArray, dims::Int...) = reshape(parent, dims)
×
134
reshape(parent::AbstractArray, dims::Integer...) = reshape(parent, dims)
×
135
reshape(parent::AbstractArray, dims::Union{Integer,Colon}...) = reshape(parent, dims)
×
136
reshape(parent::AbstractArray, dims::Tuple{Vararg{Union{Integer,Colon}}}) = reshape(parent, _reshape_uncolon(parent, dims))
×
137

138
@noinline throw1(dims) = throw(DimensionMismatch(LazyString("new dimensions ", dims,
×
139
        " may have at most one omitted dimension specified by `Colon()`")))
140
@noinline throw2(lenA, dims) = throw(DimensionMismatch(string("array size ", lenA,
×
141
    " must be divisible by the product of the new dimensions ", dims)))
142

143
@inline function _reshape_uncolon(A, _dims::Tuple{Vararg{Union{Integer, Colon}}})
×
144
    # promote the dims to `Int` at least
145
    dims = map(x -> x isa Colon ? x : promote_type(typeof(x), Int)(x), _dims)
×
146
    pre = _before_colon(dims...)
×
147
    post = _after_colon(dims...)
×
148
    _any_colon(post...) && throw1(dims)
×
149
    len = length(A)
×
150
    _reshape_uncolon_computesize(len, dims, pre, post)
×
151
end
152
@inline function _reshape_uncolon_computesize(len::Int, dims, pre::Tuple{Vararg{Int}}, post::Tuple{Vararg{Int}})
×
153
    sz = if iszero(len)
×
154
        0
×
155
    else
156
        let pr = Core.checked_dims(pre..., post...)  # safe product
×
157
            quo = _reshape_uncolon_computesize_nonempty(len, dims, pr)
×
158
            convert(Int, quo)
×
159
        end
160
    end
161
    (pre..., sz, post...)
×
162
end
163
@inline function _reshape_uncolon_computesize(len, dims, pre, post)
×
164
    pr = prod((pre..., post...))
×
165
    sz = if iszero(len)
×
166
        promote(len, pr)[1] # zero of the correct type
×
167
    else
168
        _reshape_uncolon_computesize_nonempty(len, dims, pr)
×
169
    end
170
    (pre..., sz, post...)
×
171
end
172
@inline function _reshape_uncolon_computesize_nonempty(len, dims, pr)
×
173
    iszero(pr) && throw2(len, dims)
×
174
    (quo, rem) = divrem(len, pr)
×
175
    iszero(rem) || throw2(len, dims)
×
176
    quo
×
177
end
178
@inline _any_colon() = false
×
179
@inline _any_colon(dim::Colon, tail...) = true
×
180
@inline _any_colon(dim::Any, tail...) = _any_colon(tail...)
×
181
@inline _before_colon(dim::Any, tail...) = (dim, _before_colon(tail...)...)
×
182
@inline _before_colon(dim::Colon, tail...) = ()
×
183
@inline _after_colon(dim::Any, tail...) =  _after_colon(tail...)
×
184
@inline _after_colon(dim::Colon, tail...) = tail
×
185

186
reshape(parent::AbstractArray{T,N}, ndims::Val{N}) where {T,N} = parent
1✔
187
function reshape(parent::AbstractArray, ndims::Val{N}) where N
×
188
    reshape(parent, rdims(Val(N), axes(parent)))
×
189
end
190

191
# Move elements from inds to out until out reaches the desired
192
# dimensionality N, either filling with OneTo(1) or collapsing the
193
# product of trailing dims into the last element
194
rdims_trailing(l, inds...) = length(l) * rdims_trailing(inds...)
×
195
rdims_trailing(l) = length(l)
×
196
rdims(out::Val{N}, inds::Tuple) where {N} = rdims(ntuple(Returns(OneTo(1)), Val(N)), inds)
×
197
rdims(out::Tuple{}, inds::Tuple{}) = () # N == 0, M == 0
×
198
rdims(out::Tuple{}, inds::Tuple{Any}) = ()
×
199
rdims(out::Tuple{}, inds::NTuple{M,Any}) where {M} = ()
×
200
rdims(out::Tuple{Any}, inds::Tuple{}) = out # N == 1, M == 0
×
201
rdims(out::NTuple{N,Any}, inds::Tuple{}) where {N} = out # N > 1, M == 0
×
202
rdims(out::Tuple{Any}, inds::Tuple{Any}) = inds # N == 1, M == 1
×
203
rdims(out::Tuple{Any}, inds::NTuple{M,Any}) where {M} = (oneto(rdims_trailing(inds...)),) # N == 1, M > 1
×
204
rdims(out::NTuple{N,Any}, inds::NTuple{N,Any}) where {N} = inds # N > 1, M == N
×
205
rdims(out::NTuple{N,Any}, inds::NTuple{M,Any}) where {N,M} = (first(inds), rdims(tail(out), tail(inds))...) # N > 1, M > 1, M != N
×
206

207

208
# _reshape on Array returns an Array
209
_reshape(parent::Vector, dims::Dims{1}) = parent
×
210
_reshape(parent::Array, dims::Dims{1}) = reshape(parent, dims)
×
211
_reshape(parent::Array, dims::Dims) = reshape(parent, dims)
×
212

213
# When reshaping Vector->Vector, don't wrap with a ReshapedArray
214
function _reshape(v::AbstractVector, dims::Dims{1})
×
215
    require_one_based_indexing(v)
×
216
    len = dims[1]
×
217
    len == length(v) || _throw_dmrs(length(v), "length", len)
×
218
    v
×
219
end
220
# General reshape
221
function _reshape(parent::AbstractArray, dims::Dims)
×
222
    n = length(parent)
×
223
    prod(dims) == n || _throw_dmrs(n, "size", dims)
×
224
    __reshape((parent, IndexStyle(parent)), dims)
×
225
end
226

227
@noinline function _throw_dmrs(n, str, dims)
×
228
    throw(DimensionMismatch("parent has $n elements, which is incompatible with $str $dims ($(prod(dims)) elements)"))
×
229
end
230

231
# Reshaping a ReshapedArray
232
_reshape(v::ReshapedArray{<:Any,1}, dims::Dims{1}) = _reshape(v.parent, dims)
×
233
_reshape(R::ReshapedArray, dims::Dims) = _reshape(R.parent, dims)
×
234

235
function __reshape(p::Tuple{AbstractArray,IndexStyle}, dims::Dims)
×
236
    parent = p[1]
×
237
    strds = front(size_to_strides(map(length, axes(parent))..., 1))
×
238
    strds1 = map(s->max(1,Int(s)), strds)  # for resizing empty arrays
×
239
    mi = map(SignedMultiplicativeInverse, strds1)
×
240
    ReshapedArray(parent, dims, reverse(mi))
×
241
end
242

243
function __reshape(p::Tuple{AbstractArray{<:Any,0},IndexCartesian}, dims::Dims)
×
244
    parent = p[1]
×
245
    ReshapedArray(parent, dims, ())
×
246
end
247

248
function __reshape(p::Tuple{AbstractArray,IndexLinear}, dims::Dims)
×
249
    parent = p[1]
×
250
    ReshapedArray(parent, dims, ())
×
251
end
252

253
size(A::ReshapedArray) = A.dims
×
254
length(A::ReshapedArray) = length(parent(A))
×
255
similar(A::ReshapedArray, eltype::Type, dims::Dims) = similar(parent(A), eltype, dims)
×
256
IndexStyle(::Type{<:ReshapedArrayLF}) = IndexLinear()
×
257
parent(A::ReshapedArray) = A.parent
×
258
parentindices(A::ReshapedArray) = map(oneto, size(parent(A)))
×
259
reinterpret(::Type{T}, A::ReshapedArray, dims::Dims) where {T} = reinterpret(T, parent(A), dims)
×
260
elsize(::Type{<:ReshapedArray{<:Any,<:Any,P}}) where {P} = elsize(P)
×
261

262
unaliascopy(A::ReshapedArray) = typeof(A)(unaliascopy(A.parent), A.dims, A.mi)
×
263
dataids(A::ReshapedArray) = dataids(A.parent)
×
264
# forward the aliasing check the parent in case there are specializations
265
mightalias(A::ReshapedArray, B::ReshapedArray) = mightalias(parent(A), parent(B))
×
266
# special handling for reshaped SubArrays that dispatches to the subarray aliasing check
267
mightalias(A::ReshapedArray, B::SubArray) = mightalias(parent(A), B)
×
268
mightalias(A::SubArray, B::ReshapedArray) = mightalias(A, parent(B))
×
269

270
@inline ind2sub_rs(ax, ::Tuple{}, i::Int) = (i,)
×
271
@inline ind2sub_rs(ax, strds, i) = _ind2sub_rs(ax, strds, i - 1)
×
272
@inline _ind2sub_rs(ax, ::Tuple{}, ind) = (ind + first(ax[end]),)
×
273
@inline function _ind2sub_rs(ax, strds, ind)
×
274
    d, r = divrem(ind, strds[1])
×
275
    (_ind2sub_rs(front(ax), tail(strds), r)..., d + first(ax[end]))
×
276
end
277
offset_if_vec(i::Integer, axs::Tuple{<:AbstractUnitRange}) = i + first(axs[1]) - 1
×
278
offset_if_vec(i::Integer, axs::Tuple) = i
×
279

280
@inline function isassigned(A::ReshapedArrayLF, index::Int)
×
281
    @boundscheck checkbounds(Bool, A, index) || return false
×
282
    indexparent = index - firstindex(A) + firstindex(parent(A))
×
283
    @inbounds ret = isassigned(parent(A), indexparent)
×
284
    ret
×
285
end
286
@inline function isassigned(A::ReshapedArray{T,N}, indices::Vararg{Int, N}) where {T,N}
×
287
    @boundscheck checkbounds(Bool, A, indices...) || return false
×
288
    axp = axes(A.parent)
×
289
    i = offset_if_vec(_sub2ind(size(A), indices...), axp)
×
290
    I = ind2sub_rs(axp, A.mi, i)
×
291
    @inbounds isassigned(A.parent, I...)
×
292
end
293

294
@inline function getindex(A::ReshapedArrayLF, index::Int)
×
295
    @boundscheck checkbounds(A, index)
×
296
    indexparent = index - firstindex(A) + firstindex(parent(A))
×
297
    @inbounds ret = parent(A)[indexparent]
×
298
    ret
×
299
end
300
@inline function getindex(A::ReshapedArray{T,N}, indices::Vararg{Int,N}) where {T,N}
×
301
    @boundscheck checkbounds(A, indices...)
×
302
    _unsafe_getindex(A, indices...)
×
303
end
304
@inline function getindex(A::ReshapedArray, index::ReshapedIndex)
×
305
    @boundscheck checkbounds(parent(A), index.parentindex)
×
306
    @inbounds ret = parent(A)[index.parentindex]
×
307
    ret
×
308
end
309

310
@inline function _unsafe_getindex(A::ReshapedArray{T,N}, indices::Vararg{Int,N}) where {T,N}
×
311
    axp = axes(A.parent)
×
312
    i = offset_if_vec(_sub2ind(size(A), indices...), axp)
×
313
    I = ind2sub_rs(axp, A.mi, i)
×
314
    _unsafe_getindex_rs(parent(A), I)
×
315
end
316
@inline _unsafe_getindex_rs(A, i::Integer) = (@inbounds ret = A[i]; ret)
×
317
@inline _unsafe_getindex_rs(A, I) = (@inbounds ret = A[I...]; ret)
×
318

319
@inline function setindex!(A::ReshapedArrayLF, val, index::Int)
×
320
    @boundscheck checkbounds(A, index)
×
321
    indexparent = index - firstindex(A) + firstindex(parent(A))
×
322
    @inbounds parent(A)[indexparent] = val
×
323
    val
×
324
end
325
@inline function setindex!(A::ReshapedArray{T,N}, val, indices::Vararg{Int,N}) where {T,N}
×
326
    @boundscheck checkbounds(A, indices...)
×
327
    _unsafe_setindex!(A, val, indices...)
×
328
end
329
@inline function setindex!(A::ReshapedArray, val, index::ReshapedIndex)
×
330
    @boundscheck checkbounds(parent(A), index.parentindex)
×
331
    @inbounds parent(A)[index.parentindex] = val
×
332
    val
×
333
end
334

335
@inline function _unsafe_setindex!(A::ReshapedArray{T,N}, val, indices::Vararg{Int,N}) where {T,N}
×
336
    axp = axes(A.parent)
×
337
    i = offset_if_vec(_sub2ind(size(A), indices...), axp)
×
338
    @inbounds parent(A)[ind2sub_rs(axes(A.parent), A.mi, i)...] = val
×
339
    val
×
340
end
341

342
# helpful error message for a common failure case
343
const ReshapedRange{T,N,A<:AbstractRange} = ReshapedArray{T,N,A,Tuple{}}
344
setindex!(A::ReshapedRange, val, index::Int) = _rs_setindex!_err()
×
345
setindex!(A::ReshapedRange{T,N}, val, indices::Vararg{Int,N}) where {T,N} = _rs_setindex!_err()
×
346
setindex!(A::ReshapedRange, val, index::ReshapedIndex) = _rs_setindex!_err()
×
347

348
@noinline _rs_setindex!_err() = error("indexed assignment fails for a reshaped range; consider calling collect")
×
349

350
cconvert(::Type{Ptr{T}}, a::ReshapedArray{T}) where {T} = cconvert(Ptr{T}, parent(a))
×
351
unsafe_convert(::Type{Ptr{T}}, a::ReshapedArray{T}) where {T} = unsafe_convert(Ptr{T}, a.parent)
×
352

353
# Add a few handy specializations to further speed up views of reshaped ranges
354
const ReshapedUnitRange{T,N,A<:AbstractUnitRange} = ReshapedArray{T,N,A,Tuple{}}
355
viewindexing(I::Tuple{Slice, ReshapedUnitRange, Vararg{ScalarIndex}}) = IndexLinear()
×
356
viewindexing(I::Tuple{ReshapedRange, Vararg{ScalarIndex}}) = IndexLinear()
×
357
compute_stride1(s, inds, I::Tuple{ReshapedRange, Vararg{Any}}) = s*step(I[1].parent)
×
358
compute_offset1(parent::AbstractVector, stride1::Integer, I::Tuple{ReshapedRange}) =
×
359
    (@inline; first(I[1]) - first(axes1(I[1]))*stride1)
×
360
substrides(strds::NTuple{N,Int}, I::Tuple{ReshapedUnitRange, Vararg{Any}}) where N =
×
361
    (size_to_strides(strds[1], size(I[1])...)..., substrides(tail(strds), tail(I))...)
362

363
# cconvert(::Type{<:Ptr}, V::SubArray{T,N,P,<:Tuple{Vararg{Union{RangeIndex,ReshapedUnitRange}}}}) where {T,N,P} = V
364
function unsafe_convert(::Type{Ptr{S}}, V::SubArray{T,N,P,<:Tuple{Vararg{Union{RangeIndex,ReshapedUnitRange}}}}) where {S,T,N,P}
365
    parent = V.parent
376,512✔
366
    p = cconvert(Ptr{T}, parent) # XXX: this should occur in cconvert, the result is not GC-rooted
376,512✔
367
    Δmem = if _checkcontiguous(Bool, parent)
376,512✔
368
        (first_index(V) - firstindex(parent)) * elsize(parent)
376,935✔
369
    else
370
        _memory_offset(parent, map(first, V.indices)...)
×
371
    end
372
    return Ptr{S}(unsafe_convert(Ptr{T}, p) + Δmem)
376,935✔
373
end
374

375
_checkcontiguous(::Type{Bool}, A::AbstractArray) = false
×
376
# `strides(A::DenseArray)` calls `size_to_strides` by default.
377
# Thus it's OK to assume all `DenseArray`s are contiguously stored.
378
_checkcontiguous(::Type{Bool}, A::DenseArray) = true
×
379
_checkcontiguous(::Type{Bool}, A::ReshapedArray) = _checkcontiguous(Bool, parent(A))
×
380
_checkcontiguous(::Type{Bool}, A::FastContiguousSubArray) = _checkcontiguous(Bool, parent(A))
509,039✔
381

382
function strides(a::ReshapedArray)
×
383
    _checkcontiguous(Bool, a) && return size_to_strides(1, size(a)...)
×
384
    apsz::Dims = size(a.parent)
×
385
    apst::Dims = strides(a.parent)
×
386
    msz, mst, n = merge_adjacent_dim(apsz, apst) # Try to perform "lazy" reshape
×
387
    n == ndims(a.parent) && return size_to_strides(mst, size(a)...) # Parent is stridevector like
×
388
    return _reshaped_strides(size(a), 1, msz, mst, n, apsz, apst)
×
389
end
390

391
function _reshaped_strides(::Dims{0}, reshaped::Int, msz::Int, ::Int, ::Int, ::Dims, ::Dims)
×
392
    reshaped == msz && return ()
×
393
    throw(ArgumentError("Input is not strided."))
×
394
end
395
function _reshaped_strides(sz::Dims, reshaped::Int, msz::Int, mst::Int, n::Int, apsz::Dims, apst::Dims)
×
396
    st = reshaped * mst
×
397
    reshaped = reshaped * sz[1]
×
398
    if length(sz) > 1 && reshaped == msz && sz[2] != 1
×
399
        msz, mst, n = merge_adjacent_dim(apsz, apst, n + 1)
×
400
        reshaped = 1
×
401
    end
402
    sts = _reshaped_strides(tail(sz), reshaped, msz, mst, n, apsz, apst)
×
403
    return (st, sts...)
×
404
end
405

406
merge_adjacent_dim(::Dims{0}, ::Dims{0}) = 1, 1, 0
×
407
merge_adjacent_dim(apsz::Dims{1}, apst::Dims{1}) = apsz[1], apst[1], 1
×
408
function merge_adjacent_dim(apsz::Dims{N}, apst::Dims{N}, n::Int = 1) where {N}
×
409
    sz, st = apsz[n], apst[n]
×
410
    while n < N
×
411
        szₙ, stₙ = apsz[n+1], apst[n+1]
×
412
        if sz == 1
×
413
            sz, st = szₙ, stₙ
×
414
        elseif stₙ == st * sz || szₙ == 1
×
415
            sz *= szₙ
×
416
        else
417
            break
×
418
        end
419
        n += 1
×
420
    end
×
421
    return sz, st, n
×
422
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc