https://github.com/juliaarrays/customunitranges.jl
Package-specific AbstractUnitRange types for julia
https://github.com/juliaarrays/customunitranges.jl
Last synced: 22 days ago
JSON representation
Package-specific AbstractUnitRange types for julia
- Host: GitHub
- URL: https://github.com/juliaarrays/customunitranges.jl
- Owner: JuliaArrays
- License: other
- Created: 2016-07-08T19:12:41.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2024-04-08T04:39:16.000Z (about 2 years ago)
- Last Synced: 2025-02-21T23:18:41.591Z (over 1 year ago)
- Language: Julia
- Size: 51.8 KB
- Stars: 8
- Watchers: 5
- Forks: 7
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# CustomUnitRanges
[](https://travis-ci.org/JuliaArrays/CustomUnitRanges.jl)
[](http://codecov.io/github/JuliaArrays/CustomUnitRanges.jl?branch=master)
This Julia package supports the creation of array types with
"unconventional" indices, i.e., when the indices may not start at 1.
With this package, each custom array type can have a corresponding
`axes` range type, consequently providing a means for consistency
in allocation by `similar`.
See https://docs.julialang.org/en/v1/devdocs/offset-arrays/ for
more information about defining and using array types with non-1
indices.
# What's in this package
Currently this package defines two `AbstractUnitRange` types:
- `ZeroRange`, where `ZeroRange(n)` is the equivalent of `0:n-1`, except that
Julia's type system knows that the lower bound is 0. (This is
analogous to `Base`'s `OneTo` type.) This is useful for defining
arrays that are indexed starting with 0.
- `URange`, a parallel to `UnitRange`, for defining arbitrary range indices.
# Usage
This package has a somewhat atypical usage: you should `include` files
from this repository at the source level. The reason is that this
package's range types should be **private** to the module that needs
them; consequently you don't want to define a module in the global
namespace.
Instead, suppose you're defining an array type that supports arbitrary
indices. In broad terms, your module might look like this:
```julia
module MyArrayType
using CustomUnitRanges: filename_for_urange
include(filename_for_urange)
struct MyArray{T,N} <: AbstractArray{T,N}
...
end
Base.axes(A::MyArray) = Base.Slice.(map(URange, #=starting indices=#, #=ending indices=#))
...
end
```
Here,
```
using CustomUnitRanges: filename_for_urange
```
brings a non-exported string, `filename_for_urange`, into the scope of
`MyArrayType`. The key line is the `include(filename_for_urange)`
statement, which will load (at source-level) the code for the `URange`
type into your `MyArrayType` module. We chose `"URange.jl"` because
here we want arbitrary indices; had we wanted zero-based indices, we
would have chosen `"ZeroRange.jl"` instead. Second, note that the
output of `axes` is a `Slice` containing a `URange` type. More specifically, it's
creating a tuple of slices with `MyArrayType.URange`---there is no "global"
`URange` type, so the indices-tuple is therefore *specific to this
package*.
The important result is that two packages, defining `MyArray` and
`OtherArray`, can independently exploit `URange`. If `MyArrayType`
includes the specialization
```jl
function Base.similar(f::Union{Type,Function}, shape::Tuple{URange,Vararg{URange}}
MyArray(f(map(length, shape)), #=something for the offset=#)
end
```
and similarly for `OtherArrayType`. Then, if `A` is a `MyArray` and
`B` is an `OtherArray`,
- `similar(Array{Int}, axes(A))` will create another `MyArray`
- `similar(Array{Int}, axes(B))` will create another `OtherArray`
despite the fact that they both use `URange`.