view index.jl @ 96:0743e1247384 cell_based_test

Add Index type for keeping track of regions
author Jonatan Werpers <jonatan@werpers.com>
date Tue, 05 Feb 2019 14:57:02 +0100
parents
children 50273f745f05
line wrap: on
line source

abstract type Region end
struct Interior <: Region end
struct Lower    <: Region end
struct Upper    <: Region end

struct Index{R<:Region, T<:Integer}
    i::T

    Index{R,T}(i::T) where {R<:Region,T<:Integer} = new{R,T}(i)
    Index{R}(i::T) where {R<:Region,T<:Integer} = new{R,T}(i)
    Index(i::T, ::Type{R}) where {R<:Region,T<:Integer} = Index{R,T}(i)
    Index(t::Tuple{T, DataType}) where {R<:Region,T<:Integer} = Index{t[2],T}(t[1]) # TBD: This is not very specific in what types are allowed in t[2]. Can this be fixed?
end

# Index(R::Type{<:Region}) = Index{R}

## Vill kunna skriva
## IndexTupleType(Int, (Lower, Interior))
Index(R::Type{<:Region}, T::Type{<:Integer}) = Index{R,T}
IndexTupleType(T::Type{<:Integer},R::NTuple{N, DataType} where N) = Tuple{Index.(R, T)...}

Base.convert(::Type{T}, i::Index{R,T} where R) where T = i.i
Base.convert(::Type{CartesianIndex}, I::NTuple{N,Index} where N) = CartesianIndex(convert.(Int, I))

Base.Int(I::Index) = I.i

function Index(i::Integer, boundary_width::Integer, dim_size::Integer)
    if 0 < i <= boundary_width
        return Index{Lower}(i)
    elseif boundary_width < i <= dim_size-boundary_width
        return Index{Interior}(i)
    elseif dim_size-boundary_width < i <= dim_size
        return Index{Upper}(i)
    else
        error("Bounds error") # TODO: Make this more standard
    end
end

IndexTuple(t::Vararg{Tuple{T, DataType}}) where T<:Integer = Index.(t)