1
1
"""
2
- append !(dest::BlockVector, sources...; alias = false)
2
+ blockappend !(dest::BlockVector, sources...) -> dest
3
3
4
- Append items from `sources` to the last block of `dest`. If `alias = true`,
5
- append the blocks in `sources` as-is if they are compatible with the internal
6
- block array type of `dest`. Importantly, this means that mutating `sources`
7
- afterwards alters the items in `dest` and it may even break the invariance
8
- of `dest` if the length of `sources` are changed. The elements may be copied
9
- even if `alias = true` if the corresponding implementation does not exist.
4
+ Append blocks from `sources` to `dest`. The number of blocks in `dest` are
5
+ increased by `sum(blocklength, sources)`.
10
6
11
- The blocks in `dest` must not alias with `sources` or components of them.
12
- For example, the result of `append!(x, x)` is undefined.
13
- """
14
- Base. append! (dest:: BlockVector , sources... ; alias:: Bool = false ) =
15
- foldl ((d, s) -> append! (d, s; alias = alias), sources; init = dest)
16
-
17
- function Base. append! (dest:: BlockVector , src; alias:: Bool = false )
18
- if _blocktype (dest) === _blocktype (src) && alias
19
- return blockappend! (dest, src)
20
- else
21
- return append_copy! (dest, src)
22
- end
23
- end
24
-
25
- _blocktype (:: Any ) = nothing
26
- _blocktype (:: T ) where {T<: AbstractArray } = T
27
- _blocktype (:: BlockArray{<:Any,<:Any,<:AbstractArray{T}} ) where {T<: AbstractArray } = T
28
- _blocktype (:: PseudoBlockArray{<:Any,<:Any,T} ) where {T<: AbstractArray } = T
7
+ This function avoids copying the elements of the blocks in `sources` when
8
+ these blocks are compatible with `dest`. Importantly, this means that
9
+ mutating `sources` afterwards alters the items in `dest` and it may even
10
+ break the invariance of `dest` if the length of `sources` are changed.
29
11
12
+ The blocks in `dest` must not alias with `sources` or components of them.
13
+ For example, the result of `blockappend!(x, x)` is undefined.
14
+
15
+ # Examples
16
+ ```jldoctest
17
+ julia> using BlockArrays
18
+
19
+ julia> blockappend!(mortar([[1], [2, 3]]), mortar([[4, 5]]))
20
+ 3-blocked 5-element BlockArray{Int64,1}:
21
+ 1
22
+ ─
23
+ 2
24
+ 3
25
+ ─
26
+ 4
27
+ 5
28
+ ```
30
29
"""
31
- blockappend!(dest::BlockVector, src)
30
+ blockappend! (dest:: BlockVector , s1, s2, sources... ) =
31
+ foldl (blockappend!, (s1, s2, sources... ); init = dest)
32
32
33
- Append blocks from `src` to `dest`. When `src` is a vector of the same type
34
- as the blocks of `dest`, or a `PseudoBlockVector` with the same underlying
35
- array type, a single vector block is appended to `dest`.
36
- """
37
33
function blockappend! (dest:: BlockVector{<:Any,T} , src:: BlockVector{<:Any,T} ) where {T}
38
34
isempty (src) && return dest
39
35
append! (dest. blocks, src. blocks)
@@ -42,21 +38,60 @@ function blockappend!(dest::BlockVector{<:Any,T}, src::BlockVector{<:Any,T}) whe
42
38
return dest
43
39
end
44
40
45
- blockappend! (
41
+ function blockappend! (
46
42
dest:: BlockVector{<:Any,<:AbstractArray{T}} ,
47
43
src:: PseudoBlockVector{<:Any,T} ,
48
- ) where {T} = blockappend! (dest, src. blocks)
44
+ ) where {T}
45
+ if blocklength (src) == 1
46
+ return blockappend! (dest, src. blocks)
47
+ else
48
+ return blockappend_fallback! (dest, src)
49
+ end
50
+ end
49
51
50
- function blockappend! (dest:: BlockVector{<:Any,<:AbstractArray{T}} , src:: T ) where {T}
52
+ function blockappend! (
53
+ dest:: BlockVector{<:Any,<:AbstractArray{T}} ,
54
+ src:: T ,
55
+ ) where {T<: AbstractVector }
51
56
isempty (src) && return dest
52
57
push! (dest. blocks, src)
53
58
push! (dest. axes[1 ]. lasts, last (dest. axes[1 ]) + length (src))
54
59
return dest
55
60
end
56
61
57
- append_copy! (dest:: BlockVector , src) = _append_copy! (dest, Base. IteratorSize (src), src)
62
+ blockappend! (dest:: BlockVector{<:Any,<:Any} , src:: AbstractVector ) =
63
+ blockappend_fallback! (dest, src)
64
+
65
+ blockappend_fallback! (dest:: BlockVector{<:Any,<:AbstractArray{T}} , src) where {T} =
66
+ blockappend! (dest, mortar ([convert (T, @view src[b]) for b in blockaxes (src, 1 )]))
67
+
68
+ """
69
+ append!(dest::BlockVector, sources...)
70
+
71
+ Append items from `sources` to the last block of `dest`.
72
+
73
+ The blocks in `dest` must not alias with `sources` or components of them.
74
+ For example, the result of `append!(x, x)` is undefined.
75
+
76
+ # Examples
77
+ ```jldoctest
78
+ julia> using BlockArrays
79
+
80
+ julia> append!(mortar([[1], [2, 3]]), mortar([[4], [5]]))
81
+ 2-blocked 5-element BlockArray{Int64,1}:
82
+ 1
83
+ ─
84
+ 2
85
+ 3
86
+ 4
87
+ 5
88
+ ```
89
+ """
90
+ Base. append! (dest:: BlockVector , sources... ) = foldl (append!, sources; init = dest)
91
+
92
+ Base. append! (dest:: BlockVector , src) = append_itr! (dest, Base. IteratorSize (src), src)
58
93
59
- function _append_copy ! (dest:: BlockVector , :: Union{Base.HasShape,Base.HasLength} , src)
94
+ function append_itr ! (dest:: BlockVector , :: Union{Base.HasShape,Base.HasLength} , src)
60
95
block = dest. blocks[end ]
61
96
li = lastindex (block)
62
97
resize! (block, length (block) + length (src))
@@ -72,7 +107,7 @@ function _append_copy!(dest::BlockVector, ::Union{Base.HasShape,Base.HasLength},
72
107
return dest
73
108
end
74
109
75
- function _append_copy ! (dest:: BlockVector , :: Base.SizeUnknown , src)
110
+ function append_itr ! (dest:: BlockVector , :: Base.SizeUnknown , src)
76
111
block = dest. blocks[end ]
77
112
# Equivalent to `n = 0; for x in src; ...; end` but (maybe) faster:
78
113
n = foldl (src, init = 0 ) do n, x
0 commit comments