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