@@ -242,26 +242,25 @@ Rather conveniently, such types have *exactly* the same binary layout in memory,
242
242
and therefore we can use ` reinterpret ` to convert between the two formats
243
243
``` julia
244
244
function svectors (x:: Matrix{T} , :: Val{N} ) where {T,N}
245
- size (x,1 ) == N || throw (" sizes mismatch" )
246
- isbitstype (T) || throw (" use for bitstypes only" )
247
- reinterpret (SVector{N,T}, reshape (x, length (x) ))
245
+ size (x,1 ) == N || error (" sizes mismatch" )
246
+ isbitstype (T) || error (" use for bitstypes only" )
247
+ reinterpret (SVector{N,T}, vec (x ))
248
248
end
249
249
```
250
- Such a conversion does not copy the data, rather it refers to the * same* memory.
251
- Arguably, a ` Vector ` of ` SVector ` s is often preferable to a ` Matrix ` because
252
- (a) it provides a better abstraction of the objects contained in the array and
253
- (b) it allows the fast * StaticArrays* methods to act on elements
254
-
255
- However, the resulting object is a Base.ReinterpretArray, not an Array, which may carry some
256
- runtime penalty on every single access. If you can afford the memory for a copy and can live with
257
- the non-shared mutation semantics, then it is better to pull a copy by e.g.
250
+ Such a conversion does not copy the data, rather it refers to the * same* memory.
251
+ Arguably, a ` Vector ` of ` SVector ` s is often preferable to a ` Matrix ` because it
252
+ provides a better abstraction of the objects contained in the array and it
253
+ allows the fast * StaticArrays* methods to act on elements.
254
+
255
+ However, the resulting object is a Base.ReinterpretArray, not an Array, which
256
+ carries some runtime penalty on every single access. If you can afford the
257
+ memory for a copy and can live with the non-shared mutation semantics, then it
258
+ is better to pull a copy by e.g.
258
259
``` julia
259
260
function svectorscopy (x:: Matrix{T} , :: Val{N} ) where {T,N}
260
- size (x,1 ) == N || throw (" sizes mismatch" )
261
- isbitstype (T) || throw (" use for bitstypes only" )
262
- res = Vector {SVector{N,T}} (undef, size (x,2 ))
263
- GC. @preserve res x ccall (:memcpy , Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), pointer (res), pointer (x), sizeof (x))
264
- return res
261
+ size (x,1 ) == N || error (" sizes mismatch" )
262
+ isbitstype (T) || error (" use for bitstypes only" )
263
+ copy (reinterpret (SVector{N,T}, vec (x)))
265
264
end
266
265
```
267
266
For example:
@@ -275,28 +274,14 @@ julia> svectors(M, Val{2}())
275
274
3-element reinterpret(SArray{Tuple{2},Int64,1,2}, ::Array{Int64,1}):
276
275
[1, 2]
277
276
[3, 4]
278
- [5, 6]
277
+ [5, 6]
279
278
280
- julia> svectorscopy(M, Val{2}())
279
+ julia> svectorscopy(M, Val{2}())
281
280
3-element Array{SArray{Tuple{2},Int64,1,2},1}:
282
281
[1, 2]
283
282
[3, 4]
284
283
[5, 6]
285
284
```
286
- If applications absolutely insist on obtaining a ` Vector{<:SVector} ` referencing the same memory,
287
- then this is possible by directly calling into the runtime. However, starting from
288
- Julia 0.7 and 1.0, this violates the language specifications about aliasing
289
- (Arrays with different ` eltype ` must not share memory), and is to be considered a dirty hack.
290
- This is nevertheless safe on 1.0.* or earlier versions of the Julia compiler, but will violate
291
- compiler assumptions on Julia 1.1 or later, and cause subtle data-corrupting miscompilation bugs.
292
- ``` julia
293
- function unmaintainable_svectors (x:: Matrix{T} , :: Val{N} ) where {T,N}
294
- size (x,1 ) == N || throw (" sizes mismatch" )
295
- isbitstype (T) || throw (" use for bitstypes only" )
296
- ccall (:jl_reshape_array , Vector{SVector{N,T}}, (Any,Any,Any), Vector{SVector{N,T}}, x, (size (x,2 ),))
297
- end
298
- ```
299
-
300
285
301
286
### Working with mutable and immutable arrays
302
287
0 commit comments