# TupleTools.jl

TupleTools contains a bunch of tools for using tuples (mostly homogeneous tuples `NTuple{N}`

) as a collection and performing a number of operations with an inferrable result, typically also an `NTuple{M}`

with inferable length `M`

. Chosen implementations are typically faster than the corresponding functions in base for those small tuple lengths, but can be slower for larger tuples. Inference breaks down for most functions in case of inhomogeneous tuples.

Note that none of the following functions are exported, since their name often collides with the equivalent functions (with different implementations) in `Base`

. Some functions here provided just have an equivalent in `Base`

that doesn't work for tuples at all, like `sort`

or `cumsum`

and `cumprod`

. Some functions also provide reasonable defaults assuming that they are used for tuples of `Int`

s, i.e. `TupleTools.sum(()) = 0`

or `TupleTools.prod(()) = 1`

(whereas the corresponding `Base`

functions would error). This originates from the assumption that these methods are used to operate on tuples of e.g. sizes, indices or strides of multidimensional arrays.

## Types

`TupleTools.StaticLength`

— Type.`struct StaticLength{N} end`

Like `Val{N}`

, `StaticLength`

can be used to construct a tuple of inferrable length using `ntuple(f, StaticLength(N))`

. Here, `StaticLength(N)`

creates `StaticLength{N}()`

using a `Base.@pure`

constructor. Furthermore, one can add and subtract `StaticLength`

objects, such that

`StaticLength(N₁) + StaticLength(N₂) == StaticLength(N₁+N₂)`

and

`StaticLength(N₁) - StaticLength(N₂) == StaticLength(max(0, N₁-N₂))`

## Functions

`TupleTools.tail2`

— Function.`tail2(t::Tuple) -> ::Tuple`

Returns a tuple with the first two elements stripped, equivalent to `tail(tail(t))`

`TupleTools.unsafe_tail`

— Function.`unsafe_tail(t::Tuple) -> ::Tuple`

Returns a tuple with the first element stripped, similar to `tail(t)`

, but does not error on an empty tuple (instead returning an empty tuple again). An empty tuple is thus the fixed point of this function.

`TupleTools.unsafe_front`

— Function.`unsafe_front(t::Tuple) -> ::Tuple`

Returns a tuple with the last element stripped, similar to `front(t)`

, but does not error on an empty tuple (instead returning an empty tuple again). An empty tuple is thus the fixed point of this function.

`TupleTools.getindices`

— Function.`getindices(t::Tuple, I::Tuple{Vararg{Int}}) -> ::Tuple`

Get the indices `t[i] for i in I`

, again as tuple.

`TupleTools.deleteat`

— Function.```
deleteat(t::Tuple, i::Int) -> ::Tuple
deleteat(t::Tuple, I::Tuple{Vararg{Int}}) -> ::Tuple
```

Delete the element at location `i`

in `t`

; if a list `I`

of indices is specified (again as a tuple), the elements of these different positions are deleted.

`TupleTools.insertat`

— Function.`insertat(t::Tuple, i::Int, t2::Tuple) -> ::Tuple`

Insert the elements of tuple `t2`

at location `i`

in `t`

, i.e. the output tuple will look as (t[1:i-1]..., t2..., t[i+1:end]). Note that element `t[i]`

is deleted. Use `setindex`

for setting a single value at position `i`

, or `insertafter(t, i, t2)`

to insert the contents of `t2`

in between element `i`

and `i+1`

in `t`

.

`TupleTools.insertafter`

— Function.`insertafter(t::Tuple, i::Int, t2::Tuple) -> ::Tuple`

Insert the elements of tuple `t2`

after location `i`

in `t`

, i.e. the output tuple will look as (t[1:i]..., t2..., t[i+1:end]). Use index `i=0`

or just `(t2..., t...)`

to insert `t2`

in front of `t`

; also see `insertat`

to overwrite the element at position `i`

.

`TupleTools.vcat`

— Function.`vcat(args...) -> ::Tuple`

Like `vcat`

for tuples, concatenates a combination of tuple arguments and non-tuple arguments into a single tuple. Only works one level deep, i.e. tuples in tuples are not expanded.

`TupleTools.flatten`

— Function.`flatten(args...) -> ::Tuple`

Flatten one or more tuples into a single tuple, such that every element of that tuple is itself not a tuple, otherwise it would also be expanded (i.e. flattened).

`TupleTools.sum`

— Function.`sum(t::Tuple)`

Returns the sum of the element of a tuple, or `0`

for an empty tuple.

`TupleTools.cumsum`

— Function.`cumsum(t::Tuple)`

Returns the cumulative sum of the elements of a tuple, or `()`

for an empty tuple.

`TupleTools.diff`

— Function.`diff(v::Tuple) -> Tuple`

Finite difference operator of tuple `v`

.

`TupleTools.prod`

— Function.`prod(t::Tuple)`

Returns the product of the elements of a tuple, or `1`

for an empty tuple.

`TupleTools.cumprod`

— Function.`cumprod(t::Tuple)`

Returns the cumulative product of the elements of a tuple, or `()`

for an empty tuple.

`TupleTools.minimum`

— Function.`minimum(t::Tuple)`

Returns the smallest element of a tuple

`TupleTools.maximum`

— Function.`maximum(t::Tuple)`

Returns the largest element of a tuple

`TupleTools.findmin`

— Function.`findmin(t::Tuple)`

Returns the value and index of the minimum element in a tuple. If there are multiple minimal elements, then the first one will be returned.

`TupleTools.findmax`

— Function.`findmax(t::Tuple)`

Returns the value and index of the maximum element in a tuple. If there are multiple maximal elements, then the first one will be returned.

`TupleTools.argmin`

— Function.`argmin(t::Tuple)`

Returns the index of the minimum element in a tuple. If there are multiple minimal elements, then the first one will be returned.

`TupleTools.argmax`

— Function.`argmax(t::Tuple)`

Returns the index of the maximum element in a tuple. If there are multiple minimal elements, then the first one will be returned.

`TupleTools.sort`

— Function.`sort(t::Tuple; lt=isless, by=identity, rev::Bool=false) -> ::Tuple`

Sorts the tuple `t`

.

`TupleTools.sortperm`

— Function.`sortperm(t::Tuple; lt=isless, by=identity, rev::Bool=false) -> ::Tuple`

Computes a tuple that contains the permutation required to sort `t`

.

`TupleTools.isperm`

— Function.`isperm(p) -> ::Bool`

A non-allocating alternative to Base.isperm(p) that is much faster for small permutations.

`TupleTools.invperm`

— Function.`invperm(p::NTuple{N,Int}) -> ::NTuple{N,Int}`

Inverse permutation of a permutation `p`

.

`TupleTools.permute`

— Function.`permute(t::Tuple, p) -> ::Tuple`

Permute the elements of tuple `t`

according to the permutation in `p`

.