Skip to content

Fixes for Julia 0.7 and 1.0 #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
language: julia

os:
- linux
- osx
- linux

julia:
- 0.4
- 0.5
- 0.7
- 1.0
- nightly

# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
# matrix:
# allow_failures:
# - julia: nightly

notifications:
email: false
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia --check-bounds=yes -e 'Pkg.clone(pwd()); Pkg.build("StructsOfArrays"); Pkg.test("StructsOfArrays"; coverage=true)'

#script: # the default script is equivalent to the following
# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
# - julia -e 'Pkg.clone(pwd()); Pkg.build("Example"); Pkg.test("Example"; coverage=true)';

after_success:
- julia -e 'cd(Pkg.dir("StructsOfArrays")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
# - julia -e 'if VERSION >= v"0.7.0-" using Pkg end; cd(Pkg.dir("StructsOfArrays")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())';
- julia -e 'if VERSION >= v"0.7.0-" using Pkg end; cd(Pkg.dir("StructsOfArrays")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())';
3 changes: 1 addition & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
julia 0.4
Compat 0.19
julia 0.7
42 changes: 24 additions & 18 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.4/julia-0.4-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.4/julia-0.4-latest-win64.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
- julia_version: 0.7
- julia_version: 1
- julia_version: nightly

platform:
- x86 # 32-bit
- x64 # 64-bit

# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
# matrix:
# allow_failures:
# - julia_version: nightly

branches:
only:
Expand All @@ -19,19 +26,18 @@ notifications:
on_build_status_changed: false

install:
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile(
$env:JULIA_URL,
"C:\projects\julia-binary.exe")
# Run installer silently, output to C:\projects\julia
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
- ps: iex ((new-object net.webclient).DownloadString("https://github.com/raw/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))

build_script:
# Need to convert from shallow to complete for Pkg.clone to work
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia -e "versioninfo();
Pkg.clone(pwd(), \"StructsOfArrays\"); Pkg.build(\"StructsOfArrays\")"
- echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"

test_script:
- C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"StructsOfArrays\")"
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"

# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
30 changes: 14 additions & 16 deletions src/StructsOfArrays.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
module StructsOfArrays

using Compat

export StructOfArrays

immutable StructOfArrays{T,N,U<:Tuple} <: AbstractArray{T,N}
struct StructOfArrays{T,N,U<:Tuple} <: AbstractArray{T,N}
arrays::U
end

function gather_eltypes(T, visited = Set{Type}())
(!isleaftype(T) || T.mutable) && throw(ArgumentError("can only create an StructOfArrays of leaf type immutables"))
(!isconcretetype(T) || T.mutable) && throw(ArgumentError("can only create an StructOfArrays of concrete type immutable structs"))
isempty(T.types) && throw(ArgumentError("cannot create an StructOfArrays of an empty or bitstype"))
types = Type[]
push!(visited, T)
Expand All @@ -25,29 +23,29 @@ function gather_eltypes(T, visited = Set{Type}())
types
end

@generated function StructOfArrays{T}(::Type{T}, dims::Integer...)
@generated function StructOfArrays(::Type{T}, dims::Integer...) where {T}
N = length(dims)
types = gather_eltypes(T)
arrtuple = Tuple{[Array{S,N} for S in types]...}
:(StructOfArrays{T,$N,$arrtuple}(($([:(Array{$(S)}(dims)) for S in types]...),)))
:(StructOfArrays{T,$N,$arrtuple}(($([:(Array{$(S)}(undef, dims)) for S in types]...),)))
end
StructOfArrays(T::Type, dims::Tuple{Vararg{Integer}}) = StructOfArrays(T, dims...)

@compat Base.IndexStyle{T<:StructOfArrays}(::Type{T}) = IndexLinear()
Base.IndexStyle(::Type{T}) where {T<:StructOfArrays} = IndexLinear()

@generated function Base.similar{T}(A::StructOfArrays, ::Type{T}, dims::Dims)
if isbits(T) && length(T.types) > 1
@generated function Base.similar(A::StructOfArrays, ::Type{T}, dims::Dims) where {T}
if isbitstype(T) && length(T.types) > 1
:(StructOfArrays(T, dims))
else
:(Array{T}(dims))
:(Array{T}(undef, dims))
end
end

Base.convert{T,S,N}(::Type{StructOfArrays{T,N}}, A::AbstractArray{S,N}) =
copy!(StructOfArrays(T, size(A)), A)
Base.convert{T,S,N}(::Type{StructOfArrays{T}}, A::AbstractArray{S,N}) =
Base.convert(::Type{StructOfArrays{T,N}}, A::AbstractArray{S,N}) where {T,S,N} =
copyto!(StructOfArrays(T, size(A)), A)
Base.convert(::Type{StructOfArrays{T}}, A::AbstractArray{S,N}) where {T,S,N} =
convert(StructOfArrays{T,N}, A)
Base.convert{T,N}(::Type{StructOfArrays}, A::AbstractArray{T,N}) =
Base.convert(::Type{StructOfArrays}, A::AbstractArray{T,N}) where {T,N} =
convert(StructOfArrays{T,N}, A)

Base.size(A::StructOfArrays) = size(A.arrays[1])
Expand All @@ -68,7 +66,7 @@ function generate_getindex(T, arraynum)
Expr(:new, T, members...), arraynum
end

@generated function Base.getindex{T}(A::StructOfArrays{T}, i::Integer...)
@generated function Base.getindex(A::StructOfArrays{T}, i::Integer...) where {T}
strct, _ = generate_getindex(T, 1)
Expr(:block, Expr(:meta, :inline), strct)
end
Expand All @@ -89,7 +87,7 @@ function generate_setindex(T, x, arraynum)
exprs, arraynum
end

@generated function Base.setindex!{T}(A::StructOfArrays{T}, x, i::Integer...)
@generated function Base.setindex!(A::StructOfArrays{T}, x, i::Integer...) where {T}
exprs = Expr(:block, generate_setindex(T, :x, 1)[1]...)
quote
$(Expr(:meta, :inline))
Expand Down
1 change: 0 additions & 1 deletion test/REQUIRE

This file was deleted.

19 changes: 9 additions & 10 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
using StructsOfArrays
using Base.Test
using Compat
using Test

regular = @compat complex.(randn(10000), randn(10000))
regular = complex.(randn(10000), randn(10000))
soa = convert(StructOfArrays, regular)
@test regular == soa
@test sum(regular) ≈ sum(soa)

soa64 = convert(StructOfArrays{Complex64}, regular)
@test convert(Array{Complex64}, regular) == soa64
soa64 = convert(StructOfArrays{ComplexF32}, regular)
@test convert(Array{ComplexF32}, regular) == soa64

sim = similar(soa)
@test typeof(sim) == typeof(soa)
@test size(sim) == size(soa)

regular = @compat complex.(randn(10, 5), randn(10, 5))
regular = complex.(randn(10, 5), randn(10, 5))
soa = convert(StructOfArrays, regular)
for i = 1:10, j = 1:5
@test regular[i, j] == soa[i, j]
end
@test size(soa, 1) == 10
@test size(soa, 2) == 5

immutable OneField
struct OneField
x::Int
end

small = StructOfArrays(Complex64, 2)
small = StructOfArrays(ComplexF32, 2)
@test typeof(similar(small, Complex)) === Vector{Complex}
@test typeof(similar(small, Int)) === Vector{Int}
@test typeof(similar(small, SubString)) === Vector{SubString}
@test typeof(similar(small, OneField)) === Vector{OneField}
@test typeof(similar(small, Complex128)) <: StructOfArrays
@test typeof(similar(small, ComplexF64)) <: StructOfArrays

# Recursive structs
immutable TwoField
struct TwoField
one::OneField
two::OneField
end
Expand Down