|
38 | 38 | ## copy ## |
39 | 39 |
|
40 | 40 | function unsafe_copy!{T}(dest::Ptr{T}, src::Ptr{T}, n) |
| 41 | + # Do not use this to copy data between arrays. |
| 42 | + # It can't be made safe no matter how carefully you checked. |
41 | 43 | ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, UInt), |
42 | 44 | dest, src, n*sizeof(T)) |
43 | 45 | return dest |
|
65 | 67 |
|
66 | 68 | copy!{T}(dest::Array{T}, src::Array{T}) = copy!(dest, 1, src, 1, length(src)) |
67 | 69 |
|
68 | | -function copy(a::Array) |
69 | | - b = similar(a) |
70 | | - ccall(:memcpy, Ptr{Void}, (Ptr{Void}, Ptr{Void}, UInt), b, a, sizeof(a)) |
71 | | - return b |
72 | | -end |
| 70 | +copy{T<:Array}(a::T) = ccall(:jl_array_copy, Ref{T}, (Any,), a) |
73 | 71 |
|
74 | 72 | function reinterpret{T,S}(::Type{T}, a::Array{S,1}) |
75 | 73 | nel = Int(div(length(a)*sizeof(S),sizeof(T))) |
@@ -120,14 +118,14 @@ end |
120 | 118 | ## Constructors ## |
121 | 119 |
|
122 | 120 | similar(a::Array, T::Type, dims::Dims) = Array{T}(dims) |
123 | | -similar{T}(a::Array{T,1}) = Array{T}(size(a,1)) |
124 | | -similar{T}(a::Array{T,2}) = Array{T}(size(a,1), size(a,2)) |
| 121 | +similar{T<:Array}(a::T) = |
| 122 | + ccall(:jl_array_similar, Ref{T}, (Any,), a) |
| 123 | +similar{T}(a::Array{T}, m::Int) = |
| 124 | + ccall(:jl_array_similar_1d, Ref{Vector{T}}, (Any, Any, Int), Vector{T}, a, m) |
| 125 | +similar{T}(a::Array{T,1}, S::Type) = Vector{S}(size(a,1)) |
| 126 | +similar{T}(a::Array{T,2}, S::Type) = Matrix{S}(size(a,1), size(a,2)) |
125 | 127 | similar{T}(a::Array{T,1}, dims::Dims) = Array{T}(dims) |
126 | | -similar{T}(a::Array{T,1}, m::Int) = Array{T}(m) |
127 | | -similar{T}(a::Array{T,1}, S::Type) = Array{S}(size(a,1)) |
128 | 128 | similar{T}(a::Array{T,2}, dims::Dims) = Array{T}(dims) |
129 | | -similar{T}(a::Array{T,2}, m::Int) = Array{T}(m) |
130 | | -similar{T}(a::Array{T,2}, S::Type) = Array{S}(size(a,1), size(a,2)) |
131 | 129 |
|
132 | 130 | # T[x...] constructs Array{T,1} |
133 | 131 | function getindex(T::Type, vals...) |
@@ -387,66 +385,13 @@ setindex!{T, N}(A::Array{T, N}, x::Number, ::Vararg{Colon, N}) = fill!(A, x) |
387 | 385 |
|
388 | 386 | # efficiently grow an array |
389 | 387 |
|
390 | | -function _growat!(a::Vector, i::Integer, delta::Integer) |
391 | | - n = length(a) |
392 | | - if i < div(n,2) |
393 | | - _growat_beg!(a, i, delta) |
394 | | - else |
395 | | - _growat_end!(a, i, delta) |
396 | | - end |
397 | | - return a |
398 | | -end |
399 | | - |
400 | | -function _growat_beg!(a::Vector, i::Integer, delta::Integer) |
401 | | - ccall(:jl_array_grow_beg, Void, (Any, UInt), a, delta) |
402 | | - if i > 1 |
403 | | - ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t), |
404 | | - pointer(a, 1), pointer(a, 1+delta), (i-1)*elsize(a)) |
405 | | - end |
406 | | - return a |
407 | | -end |
408 | | - |
409 | | -function _growat_end!(a::Vector, i::Integer, delta::Integer) |
410 | | - ccall(:jl_array_grow_end, Void, (Any, UInt), a, delta) |
411 | | - n = length(a) |
412 | | - if n >= i+delta |
413 | | - ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t), |
414 | | - pointer(a, i+delta), pointer(a, i), (n-i-delta+1)*elsize(a)) |
415 | | - end |
416 | | - return a |
417 | | -end |
| 388 | +_growat!(a::Vector, i::Integer, delta::Integer) = |
| 389 | + ccall(:jl_array_grow_at, Void, (Any, Int, UInt), a, i - 1, delta) |
418 | 390 |
|
419 | 391 | # efficiently delete part of an array |
420 | 392 |
|
421 | | -function _deleteat!(a::Vector, i::Integer, delta::Integer) |
422 | | - n = length(a) |
423 | | - last = i+delta-1 |
424 | | - if i-1 < n-last |
425 | | - _deleteat_beg!(a, i, delta) |
426 | | - else |
427 | | - _deleteat_end!(a, i, delta) |
428 | | - end |
429 | | - return a |
430 | | -end |
431 | | - |
432 | | -function _deleteat_beg!(a::Vector, i::Integer, delta::Integer) |
433 | | - if i > 1 |
434 | | - ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t), |
435 | | - pointer(a, 1+delta), pointer(a, 1), (i-1)*elsize(a)) |
436 | | - end |
437 | | - ccall(:jl_array_del_beg, Void, (Any, UInt), a, delta) |
438 | | - return a |
439 | | -end |
440 | | - |
441 | | -function _deleteat_end!(a::Vector, i::Integer, delta::Integer) |
442 | | - n = length(a) |
443 | | - if n >= i+delta |
444 | | - ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t), |
445 | | - pointer(a, i), pointer(a, i+delta), (n-i-delta+1)*elsize(a)) |
446 | | - end |
447 | | - ccall(:jl_array_del_end, Void, (Any, UInt), a, delta) |
448 | | - return a |
449 | | -end |
| 393 | +_deleteat!(a::Vector, i::Integer, delta::Integer) = |
| 394 | + ccall(:jl_array_del_at, Void, (Any, Int, UInt), a, i - 1, delta) |
450 | 395 |
|
451 | 396 | ## Dequeue functionality ## |
452 | 397 |
|
@@ -526,34 +471,20 @@ function shift!(a::Vector) |
526 | 471 | end |
527 | 472 |
|
528 | 473 | function insert!{T}(a::Array{T,1}, i::Integer, item) |
529 | | - if !(1 <= i <= length(a)+1) |
530 | | - throw(BoundsError()) |
531 | | - end |
532 | | - if i == length(a)+1 |
533 | | - return push!(a, item) |
534 | | - end |
535 | | - item = convert(T, item) |
| 474 | + # Throw convert error before changing the shape of the array |
| 475 | + _item = convert(T, item) |
536 | 476 | _growat!(a, i, 1) |
537 | | - a[i] = item |
| 477 | + # _growat! already did bound check |
| 478 | + @inbounds a[i] = _item |
538 | 479 | return a |
539 | 480 | end |
540 | 481 |
|
541 | | -function deleteat!(a::Vector, i::Integer) |
542 | | - if !(1 <= i <= length(a)) |
543 | | - throw(BoundsError()) |
544 | | - end |
545 | | - return _deleteat!(a, i, 1) |
546 | | -end |
| 482 | +deleteat!(a::Vector, i::Integer) = (_deleteat!(a, i, 1); a) |
547 | 483 |
|
548 | 484 | function deleteat!{T<:Integer}(a::Vector, r::UnitRange{T}) |
549 | 485 | n = length(a) |
550 | | - isempty(r) && return a |
551 | | - f = first(r) |
552 | | - l = last(r) |
553 | | - if !(1 <= f && l <= n) |
554 | | - throw(BoundsError()) |
555 | | - end |
556 | | - return _deleteat!(a, f, length(r)) |
| 486 | + isempty(r) || _deleteat!(a, first(r), length(r)) |
| 487 | + return a |
557 | 488 | end |
558 | 489 |
|
559 | 490 | function deleteat!(a::Vector, inds) |
@@ -620,18 +551,9 @@ function splice!{T<:Integer}(a::Vector, r::UnitRange{T}, ins=_default_splice) |
620 | 551 |
|
621 | 552 | if m < d |
622 | 553 | delta = d - m |
623 | | - if f-1 < n-l |
624 | | - _deleteat_beg!(a, f, delta) |
625 | | - else |
626 | | - _deleteat_end!(a, l-delta+1, delta) |
627 | | - end |
| 554 | + _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta) |
628 | 555 | elseif m > d |
629 | | - delta = m - d |
630 | | - if f-1 < n-l |
631 | | - _growat_beg!(a, f, delta) |
632 | | - else |
633 | | - _growat_end!(a, l+1, delta) |
634 | | - end |
| 556 | + _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d) |
635 | 557 | end |
636 | 558 |
|
637 | 559 | k = 1 |
@@ -684,27 +606,8 @@ function reverse!(v::AbstractVector, s=1, n=length(v)) |
684 | 606 | return v |
685 | 607 | end |
686 | 608 |
|
687 | | -function vcat{T}(arrays::Vector{T}...) |
688 | | - n = 0 |
689 | | - for a in arrays |
690 | | - n += length(a) |
691 | | - end |
692 | | - arr = Array{T}(n) |
693 | | - ptr = pointer(arr) |
694 | | - offset = 0 |
695 | | - if isbits(T) |
696 | | - elsz = sizeof(T) |
697 | | - else |
698 | | - elsz = Core.sizeof(Ptr{Void}) |
699 | | - end |
700 | | - for a in arrays |
701 | | - nba = length(a)*elsz |
702 | | - ccall(:memcpy, Ptr{Void}, (Ptr{Void}, Ptr{Void}, UInt), |
703 | | - ptr+offset, a, nba) |
704 | | - offset += nba |
705 | | - end |
706 | | - return arr |
707 | | -end |
| 609 | +vcat{T}(arrays::Vector{T}...) = |
| 610 | + ccall(:jl_array_vcat_vectors, Ref{Vector{T}}, (Any,), arrays) |
708 | 611 |
|
709 | 612 | function hcat{T}(V::Vector{T}...) |
710 | 613 | height = length(V[1]) |
|
0 commit comments