Skip to content

Commit b69943a

Browse files
authored
Merge pull request #3 from N5N3/patch2
second try
2 parents acbb8f4 + 996e272 commit b69943a

File tree

40 files changed

+546
-331
lines changed

40 files changed

+546
-331
lines changed

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ New library features
3939
Standard library changes
4040
------------------------
4141

42+
* The `length` function on certain ranges of certain specific element types no longer checks for integer
43+
overflow in most cases. The new function `checked_length` is now available, which will try to use checked
44+
arithmetic to error if the result may be wrapping. Or use a package such as SaferIntegers.jl when
45+
constructing the range. ([#40382])
46+
4247
#### Package Manager
4348

4449
#### LinearAlgebra

README.md

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,16 @@
88
Documentation:
99
[![version 1][docs-img]](https://docs.julialang.org)
1010

11+
Code coverage:
12+
[![coveralls][coveralls-img]](https://coveralls.io/r/JuliaLang/julia?branch=master)
13+
[![codecov][codecov-img]](https://codecov.io/github/JuliaLang/julia?branch=master)
14+
15+
Continuous integration: [![Build status](https://badge.buildkite.com/f28e0d28b345f9fad5856ce6a8d64fffc7c70df8f4f2685cd8.svg?branch=master)](https://buildkite.com/julialang/julia)
16+
1117
[docs-img]: https://img.shields.io/badge/docs-v1-blue.svg
18+
[coveralls-img]: https://img.shields.io/coveralls/github/JuliaLang/julia/master.svg?label=coveralls
19+
[codecov-img]: https://img.shields.io/codecov/c/github/JuliaLang/julia/master.svg?label=codecov
20+
1221

1322
## The Julia Language
1423

@@ -141,19 +150,3 @@ Supported IDEs include: [julia-vscode](https://github.com/JuliaEditorSupport/jul
141150
Code plugin), [Juno](http://junolab.org/) (Atom plugin). [Jupyter](https://jupyter.org/)
142151
notebooks are available through the [IJulia](https://github.com/JuliaLang/IJulia.jl) package, and
143152
[Pluto](https://github.com/fonsp/Pluto.jl) notebooks through the Pluto.jl package.
144-
145-
## Continuous Integration (CI) Builders
146-
147-
Code coverage:
148-
[![coveralls][coveralls-img]](https://coveralls.io/r/JuliaLang/julia?branch=master)
149-
[![codecov][codecov-img]](https://codecov.io/github/JuliaLang/julia?branch=master)
150-
151-
| Builder | Status |
152-
| ---------- | ------ |
153-
| Overall | [![Build status](https://badge.buildkite.com/f28e0d28b345f9fad5856ce6a8d64fffc7c70df8f4f2685cd8.svg?branch=master)](https://buildkite.com/julialang/julia) |
154-
| analyzegc | [![Build status](https://badge.buildkite.com/f28e0d28b345f9fad5856ce6a8d64fffc7c70df8f4f2685cd8.svg?branch=master&step=analyzegc)](https://buildkite.com/julialang/julia) |
155-
| llvmpasses | [![Build status](https://badge.buildkite.com/f28e0d28b345f9fad5856ce6a8d64fffc7c70df8f4f2685cd8.svg?branch=master&step=llvmpasses)](https://buildkite.com/julialang/julia) |
156-
| coverage | [![Build status](https://badge.buildkite.com/d5ae34dbbf6fefe615300c4f3118bf63cb4a5ae7fd962263c1.svg?branch=master)](https://buildkite.com/julialang/julia-coverage-linux64) |
157-
158-
[coveralls-img]: https://img.shields.io/coveralls/github/JuliaLang/julia/master.svg?label=coveralls
159-
[codecov-img]: https://img.shields.io/codecov/c/github/JuliaLang/julia/master.svg?label=codecov

base/Base.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,6 @@ include("refpointer.jl")
124124
include("checked.jl")
125125
using .Checked
126126

127-
# SIMD loops
128-
@pure sizeof(s::String) = Core.sizeof(s) # needed by gensym as called from simdloop
129-
include("simdloop.jl")
130-
using .SimdLoop
131-
132127
# array structures
133128
include("indices.jl")
134129
include("array.jl")
@@ -177,6 +172,14 @@ using .MultiplicativeInverses
177172
include("abstractarraymath.jl")
178173
include("arraymath.jl")
179174

175+
# SIMD loops
176+
@pure sizeof(s::String) = Core.sizeof(s) # needed by gensym as called from simdloop
177+
include("simdloop.jl")
178+
using .SimdLoop
179+
180+
# functions for AbstractArray with @simd
181+
include("abstractarraypatch.jl")
182+
180183
# map-reduce operators
181184
include("reduce.jl")
182185

base/abstractarray.jl

Lines changed: 34 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ axes1(A::AbstractArray{<:Any,0}) = OneTo(1)
116116
axes1(A::AbstractArray) = (@_inline_meta; axes(A)[1])
117117
axes1(iter) = oneto(length(iter))
118118

119-
unsafe_indices(A) = axes(A)
120-
unsafe_indices(r::AbstractRange) = (oneto(unsafe_length(r)),) # Ranges use checked_sub for size
121-
122119
"""
123120
keys(a::AbstractArray)
124121
@@ -580,14 +577,14 @@ end
580577
function trailingsize(inds::Indices, n)
581578
s = 1
582579
for i=n:length(inds)
583-
s *= unsafe_length(inds[i])
580+
s *= length(inds[i])
584581
end
585582
return s
586583
end
587584
# This version is type-stable even if inds is heterogeneous
588585
function trailingsize(inds::Indices)
589586
@_inline_meta
590-
prod(map(unsafe_length, inds))
587+
prod(map(length, inds))
591588
end
592589

593590
## Bounds checking ##
@@ -688,7 +685,7 @@ function checkbounds_indices(::Type{Bool}, ::Tuple{}, I::Tuple)
688685
@_inline_meta
689686
checkindex(Bool, OneTo(1), I[1])::Bool & checkbounds_indices(Bool, (), tail(I))
690687
end
691-
checkbounds_indices(::Type{Bool}, IA::Tuple, ::Tuple{}) = (@_inline_meta; all(x->unsafe_length(x)==1, IA))
688+
checkbounds_indices(::Type{Bool}, IA::Tuple, ::Tuple{}) = (@_inline_meta; all(x->length(x)==1, IA))
692689
checkbounds_indices(::Type{Bool}, ::Tuple{}, ::Tuple{}) = true
693690

694691
throw_boundserror(A, I) = (@_noinline_meta; throw(BoundsError(A, I)))
@@ -886,7 +883,35 @@ function copy!(dst::AbstractArray, src::AbstractArray)
886883
end
887884

888885
## from general iterable to any array
886+
887+
"""
888+
copyto!(dest::AbstractArray, src) -> dest
889+
890+
Copy all elements from collection `src` to array `dest`, whose length must be greater than
891+
or equal to the length `n` of `src`. The first `n` elements of `dest` are overwritten,
892+
the other elements are left untouched.
889893
894+
See also [`copy!`](@ref Base.copy!), [`copy`](@ref).
895+
896+
# Examples
897+
```jldoctest
898+
julia> x = [1., 0., 3., 0., 5.];
899+
900+
julia> y = zeros(7);
901+
902+
julia> copyto!(y, x);
903+
904+
julia> y
905+
7-element Vector{Float64}:
906+
1.0
907+
0.0
908+
3.0
909+
0.0
910+
5.0
911+
0.0
912+
0.0
913+
```
914+
"""
890915
function copyto!(dest::AbstractArray, src)
891916
destiter = eachindex(dest)
892917
y = iterate(destiter)
@@ -964,87 +989,6 @@ function copyto!(dest::AbstractArray, dstart::Integer, src, sstart::Integer, n::
964989
return dest
965990
end
966991

967-
## copy between abstract arrays - generally more efficient
968-
## since a single index variable can be used.
969-
970-
"""
971-
copyto!(dest::AbstractArray, src) -> dest
972-
973-
Copy all elements from collection `src` to array `dest`, whose length must be greater than
974-
or equal to the length `n` of `src`. The first `n` elements of `dest` are overwritten,
975-
the other elements are left untouched.
976-
977-
See also [`copy!`](@ref Base.copy!), [`copy`](@ref).
978-
979-
# Examples
980-
```jldoctest
981-
julia> x = [1., 0., 3., 0., 5.];
982-
983-
julia> y = zeros(7);
984-
985-
julia> copyto!(y, x);
986-
987-
julia> y
988-
7-element Vector{Float64}:
989-
1.0
990-
0.0
991-
3.0
992-
0.0
993-
5.0
994-
0.0
995-
0.0
996-
```
997-
"""
998-
function copyto!(dest::AbstractArray, src::AbstractArray)
999-
isempty(src) && return dest
1000-
src′ = unalias(dest, src)
1001-
copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(src′), src′)
1002-
end
1003-
1004-
function copyto!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
1005-
isempty(src) && return dest
1006-
src′ = unalias(dest, src)
1007-
copyto_unaliased!(deststyle, dest, srcstyle, src′)
1008-
end
1009-
1010-
function copyto_unaliased!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
1011-
isempty(src) && return dest
1012-
length(dest) >= length(src) || throw(BoundsError(dest, LinearIndices(src)))
1013-
if deststyle isa IndexLinear
1014-
if srcstyle isa IndexLinear
1015-
Δi = firstindex(dest) - firstindex(src)
1016-
for i in eachindex(src)
1017-
@inbounds dest[i + Δi] = src[i]
1018-
end
1019-
else
1020-
j = firstindex(dest) - 1
1021-
@inbounds @simd for I in eachindex(src)
1022-
dest[j+=1] = src[I]
1023-
end
1024-
end
1025-
else
1026-
if srcstyle isa IndexLinear
1027-
i = firstindex(src) - 1
1028-
@inbounds @simd for J in eachindex(dest)
1029-
dest[J] = src[i+=1]
1030-
end
1031-
else
1032-
iterdest, itersrc = eachindex(dest), eachindex(src)
1033-
if iterdest == itersrc
1034-
# Shared-iterator implementation
1035-
@inbounds @simd for I in itersrc
1036-
dest[I] = src[I]
1037-
end
1038-
else
1039-
for (I,J) in zip(itersrc, iterdest)
1040-
@inbounds dest[J] = src[I]
1041-
end
1042-
end
1043-
end
1044-
end
1045-
return dest
1046-
end
1047-
1048992
function copyto!(dest::AbstractArray, dstart::Integer, src::AbstractArray)
1049993
copyto!(dest, dstart, src, first(LinearIndices(src)), length(src))
1050994
end
@@ -2497,8 +2441,8 @@ function _sub2ind_recurse(inds, L, ind, i::Integer, I::Integer...)
24972441
end
24982442

24992443
nextL(L, l::Integer) = L*l
2500-
nextL(L, r::AbstractUnitRange) = L*unsafe_length(r)
2501-
nextL(L, r::Slice) = L*unsafe_length(r.indices)
2444+
nextL(L, r::AbstractUnitRange) = L*length(r)
2445+
nextL(L, r::Slice) = L*length(r.indices)
25022446
offsetin(i, l::Integer) = i-1
25032447
offsetin(i, r::AbstractUnitRange) = i-first(r)
25042448

@@ -2524,7 +2468,7 @@ end
25242468
_lookup(ind, d::Integer) = ind+1
25252469
_lookup(ind, r::AbstractUnitRange) = ind+first(r)
25262470
_div(ind, d::Integer) = div(ind, d), 1, d
2527-
_div(ind, r::AbstractUnitRange) = (d = unsafe_length(r); (div(ind, d), first(r), d))
2471+
_div(ind, r::AbstractUnitRange) = (d = length(r); (div(ind, d), first(r), d))
25282472

25292473
# Vectorized forms
25302474
function _sub2ind(inds::Indices{1}, I1::AbstractVector{T}, I::AbstractVector{T}...) where T<:Integer

base/abstractarraypatch.jl

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
## copy between abstract arrays - generally more efficient
4+
## since a single index variable can be used.
5+
## copyto_unaliased! use @simd to speed up, so these definition is seperated from abstractarray.jl
6+
7+
function copyto!(dest::AbstractArray, src::AbstractArray)
8+
isempty(src) && return dest
9+
src′ = unalias(dest, src)
10+
copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(src′), src′)
11+
end
12+
13+
function copyto!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
14+
isempty(src) && return dest
15+
src′ = unalias(dest, src)
16+
copyto_unaliased!(deststyle, dest, srcstyle, src′)
17+
end
18+
19+
function copyto_unaliased!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
20+
isempty(src) && return dest
21+
length(dest) >= length(src) || throw(BoundsError(dest, LinearIndices(src)))
22+
if deststyle isa IndexLinear
23+
if srcstyle isa IndexLinear
24+
Δi = firstindex(dest) - firstindex(src)
25+
for i in eachindex(src)
26+
@inbounds dest[i + Δi] = src[i]
27+
end
28+
else
29+
j = firstindex(dest) - 1
30+
@inbounds @simd for I in eachindex(src)
31+
dest[j+=1] = src[I]
32+
end
33+
end
34+
else
35+
if srcstyle isa IndexLinear
36+
i = firstindex(src) - 1
37+
@inbounds @simd for J in eachindex(dest)
38+
dest[J] = src[i+=1]
39+
end
40+
else
41+
iterdest, itersrc = eachindex(dest), eachindex(src)
42+
if iterdest == itersrc
43+
# Shared-iterator implementation
44+
@inbounds @simd for I in itersrc
45+
dest[I] = src[I]
46+
end
47+
else
48+
for (I,J) in zip(itersrc, iterdest)
49+
@inbounds dest[J] = src[I]
50+
end
51+
end
52+
end
53+
end
54+
return dest
55+
end

base/broadcast.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ an `Int`.
566566
"""
567567
Base.@propagate_inbounds newindex(arg, I::CartesianIndex) = CartesianIndex(_newindex(axes(arg), I.I))
568568
Base.@propagate_inbounds newindex(arg, I::Integer) = CartesianIndex(_newindex(axes(arg), (I,)))
569-
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple) = (ifelse(Base.unsafe_length(ax[1])==1, ax[1][1], I[1]), _newindex(tail(ax), tail(I))...)
569+
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple) = (ifelse(length(ax[1]) == 1, ax[1][1], I[1]), _newindex(tail(ax), tail(I))...)
570570
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple) = ()
571571
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple{}) = (ax[1][1], _newindex(tail(ax), ())...)
572572
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = ()

base/checked.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ module Checked
66

77
export checked_neg, checked_abs, checked_add, checked_sub, checked_mul,
88
checked_div, checked_rem, checked_fld, checked_mod, checked_cld,
9-
add_with_overflow, sub_with_overflow, mul_with_overflow
9+
checked_length, add_with_overflow, sub_with_overflow, mul_with_overflow
1010

1111
import Core.Intrinsics:
1212
checked_sadd_int, checked_ssub_int, checked_smul_int, checked_sdiv_int,
1313
checked_srem_int,
1414
checked_uadd_int, checked_usub_int, checked_umul_int, checked_udiv_int,
1515
checked_urem_int
16-
import ..no_op_err, ..@_inline_meta, ..@_noinline_meta
16+
import ..no_op_err, ..@_inline_meta, ..@_noinline_meta, ..checked_length
1717

1818
# define promotion behavior for checked operations
1919
checked_add(x::Integer, y::Integer) = checked_add(promote(x,y)...)
@@ -349,4 +349,12 @@ The overflow protection may impose a perceptible performance penalty.
349349
"""
350350
checked_cld(x::T, y::T) where {T<:Integer} = cld(x, y) # Base.cld already checks
351351

352+
"""
353+
Base.checked_length(r)
354+
355+
Calculates `length(r)`, but may check for overflow errors where applicable when
356+
the result doesn't fit into `Union{Integer(eltype(r)),Int}`.
357+
"""
358+
checked_length(r) = length(r) # for most things, length doesn't error
359+
352360
end

base/compiler/compiler.jl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ add_with_overflow(x::T, y::T) where {T<:SignedInt} = checked_sadd_int(x, y)
7070
add_with_overflow(x::T, y::T) where {T<:UnsignedInt} = checked_uadd_int(x, y)
7171
add_with_overflow(x::Bool, y::Bool) = (x+y, false)
7272

73-
# SIMD loops (The new copyto_unalias! use @simd)
74-
@pure sizeof(s::String) = Core.sizeof(s) # needed by gensym as called from simdloop
75-
include("simdloop.jl")
76-
using .SimdLoop
77-
7873
# core array operations
7974
include("indices.jl")
8075
include("array.jl")

base/deprecated.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ end
240240
@deprecate cat_shape(dims, shape::Tuple{}, shapes::Tuple...) cat_shape(dims, shapes) false
241241
cat_shape(dims, shape::Tuple{}) = () # make sure `cat_shape(dims, ())` do not recursively calls itself
242242

243+
@deprecate unsafe_indices(A) axes(A) false
244+
@deprecate unsafe_length(r) length(r) false
245+
243246
# END 1.6 deprecations
244247

245248
# BEGIN 1.7 deprecations

0 commit comments

Comments
 (0)