From 05a97a0d000a9bfa00fdbe47a0e60559bdef718b Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Thu, 11 Feb 2016 11:16:05 -0600 Subject: [PATCH 1/2] Add range-based CartesianRange constructor, scalar addition of CartesianIndex --- base/multidimensional.jl | 7 +++++++ test/arrayops.jl | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 7c7a157f8aa4e..5acbb60ec9e0a 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -61,6 +61,11 @@ for op in (:+, :-, :min, :max) end end +(+){N}(index::CartesianIndex{N}, i::Integer) = CartesianIndex{N}(map(x->x+i, index.I)) +(+){N}(i::Integer, index::CartesianIndex{N}) = index+i +(-){N}(index::CartesianIndex{N}, i::Integer) = CartesianIndex{N}(map(x->x-i, index.I)) +(-){N}(i::Integer, index::CartesianIndex{N}) = CartesianIndex{N}(map(x->i-x, index.I)) + @generated function *{N}(a::Integer, index::CartesianIndex{N}) I = index args = [:(a*index[$d]) for d = 1:N] @@ -78,7 +83,9 @@ end startargs = fill(1, N) :(CartesianRange($I($(startargs...)), I)) end +CartesianRange(::Tuple{}) = CartesianRange{CartesianIndex{0}}(CartesianIndex{0}(()),CartesianIndex{0}(())) CartesianRange{N}(sz::NTuple{N,Int}) = CartesianRange(CartesianIndex(sz)) +CartesianRange{N}(rngs::NTuple{N,Union{Int,UnitRange{Int}}}) = CartesianRange(CartesianIndex(map(r->first(r), rngs)), CartesianIndex(map(r->last(r), rngs))) ndims(R::CartesianRange) = length(R.start) ndims{I<:CartesianIndex}(::Type{CartesianRange{I}}) = length(I) diff --git a/test/arrayops.jl b/test/arrayops.jl index edff1668b653d..c0a95d5afc96b 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1110,6 +1110,8 @@ I2 = CartesianIndex((-1,5,2)) @test I2 + I1 == CartesianIndex((1,8,2)) @test I1 - I2 == CartesianIndex((3,-2,-2)) @test I2 - I1 == CartesianIndex((-3,2,2)) +@test I1 + 1 == CartesianIndex((3,4,1)) +@test I1 - 2 == CartesianIndex((0,1,-2)) @test min(CartesianIndex((2,3)), CartesianIndex((5,2))) == CartesianIndex((2,2)) @test max(CartesianIndex((2,3)), CartesianIndex((5,2))) == CartesianIndex((5,3)) @@ -1147,6 +1149,9 @@ indexes = collect(R) @test length(R) == 12 @test ndims(R) == 2 +@test CartesianRange((3:5,-7:7)) == CartesianRange(CartesianIndex{2}(3,-7),CartesianIndex{2}(5,7)) +@test CartesianRange((3,-7:7)) == CartesianRange(CartesianIndex{2}(3,-7),CartesianIndex{2}(3,7)) + r = 2:3 itr = eachindex(r) state = start(itr) From 5095d821118eaa5453b1bd522a6f2eb0a997fa6f Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 14 Feb 2016 11:54:59 -0600 Subject: [PATCH 2/2] Add tuple-padding, fill_to_length(::Tuple, val, Val{N}) --- base/tuple.jl | 16 ++++++++++++++++ test/tuple.jl | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/base/tuple.jl b/base/tuple.jl index 5e0e6529bd9ca..2470a01513b27 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -85,6 +85,22 @@ tails(t::Tuple, ts::Tuple...) = (tail(t), tails(ts...)...) map(f, ::Tuple{}, ts::Tuple...) = () map(f, ts::Tuple...) = (f(heads(ts...)...), map(f, tails(ts...)...)...) +# type-stable padding +fill_to_length{N}(t::Tuple, val, ::Type{Val{N}}) = _ftl((), val, Val{N}, t...) +_ftl{N}(out::NTuple{N}, val, ::Type{Val{N}}) = out +function _ftl{N}(out::NTuple{N}, val, ::Type{Val{N}}, t...) + @_inline_meta + error("input tuple of length $(N+length(t)), requested $N") +end +function _ftl{N}(out, val, ::Type{Val{N}}, t1, t...) + @_inline_meta + _ftl((out..., t1), val, Val{N}, t...) +end +function _ftl{N}(out, val, ::Type{Val{N}}) + @_inline_meta + _ftl((out..., val), val, Val{N}) +end + ## comparison ## function isequal(t1::Tuple, t2::Tuple) diff --git a/test/tuple.jl b/test/tuple.jl index a704676a14b48..2c1fbea99d2c4 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -37,6 +37,10 @@ @test getindex((5,6,7,8), []) === () +## filling to specified length +@test @inferred(Base.fill_to_length((1,2,3), -1, Val{5})) == (1,2,3,-1,-1) +@test_throws ErrorException Base.fill_to_length((1,2,3), -1, Val{2}) + ## iterating ## @test start((1,2,3)) === 1