# [−][src]Crate array_lit

Macros for array and `Vec` literals with superpowers. The macro for arrays is called `arr!`; the macro for `Vec` is called `vec!` and shadows the macro from the standard library.

They allow creating an array or `Vec` where only some elements are specified, and the rest is set to a default value.

The following macro specifies three consecutive values at index 0:

```let a = arr![0; 8; { : [1, 2, 3] }];
assert_eq!(a, [1, 2, 3, 0, 0, 0, 0, 0]);```

The square brackets are only needed when specifying multiple consecutive elements:

```let a = arr![1; 8; { 6: 0 }];
assert_eq!(a, [1, 1, 1, 1, 1, 1, 0, 1]);```

You can specify as many single and consecutive values as you like:

```let a = arr![0; 8; {
6: 1,            // 1 at index 6
: [3, 4],     // 3 and 4 starting from index 2
7: 5,            // 5 at index 7
}];
assert_eq!(a, [0, 0, 3, 4, 0, 0, 1, 5]);```

The familiar array syntax (`arr![a; N]` and `arr![a, b, c]`) is also supported, so the `vec!` macro from this crate is a drop-in replacement for `std::vec!`.

## How does it work?

The macros generate a block that first creates a array or `Vec`, and then inserts the specified values:

```arr![4; 5; { 0: 0, 1: 1 }];
// is expanded to
{
let mut arr = [4; 5];  // in the vec! macro, std::vec! is used
arr = 0;
arr = 1;
arr
};```

If an array is inserted that is not of the form `[a, b, c, ..]`, a loop is used:

```arr![4; 10; { : [2; 4] }];
// is expanded to
{
let mut arr = [4; 10];
let mut i = 1;
let end = i + 4;
while i < end {
arr[i] = 2;
i += 1;
}
arr
};```

This even works for slices, arrays and `Vec`s created at runtime:

```let my_slice = &[1, 2, 3, 4];
arr![4; 10; { : my_slice }];```

In trivial cases such as `arr![3; 5]`, the `'static` lifetime is inferred for array literals. This means that they have the exact same behavior as normal array literals.

In the other cases, the `'static` lifetime is not inferred. This means that the array literal is computed at runtime and doesn't have a fixed memory location. It also means that the following

```fn return_temporary() -> &'static [i32; 4] {
&arr![0; 4; { 0: 1 }]
}```

produces `error[E0515]: cannot return reference to temporary value`. This can be solved by assigning the literal to a `const` or `static` variable first:

```fn return_temporary() -> &'static [i32; 4] {
static ARR: &[i32; 4] = &arr![0; 4; { 0: 1 }];
ARR
}```

Values assigned to a `static` or `const` variable must be constant. Due to limitations in the compiler, macros that expand to loops aren't allowed there:

```const ARR: [i32; 4] = arr![0; 16; { : [1; 8] }];
// this is expanded to a loop ~~~~~~~~~~~^^^^^^```

Note that `const` enforces const evaluation, which means that the whole array is included in the application binary. This might not be desirable if the array is large.

## Usage

Import the macros with

`use array_lit::{arr, vec};`

If you don't want to shadow `std::vec!`, you can rename the macro:

`use array_lit::{arr, vec as vector};`

Importing the macros globally is also supported, although not recommended:

```#[macro_use]
extern crate array_lit;```

## Custom indices

If you want to use your own `Index`/`IndexMut` implementation in these macros, you probably need an extra pair of parentheses:

```#[derive(Copy, Clone)]
struct S(bool);

struct Idx(usize);

impl std::ops::Index<Idx> for Vec<S> {
type Output = bool;
// etc.
}

impl std::ops::IndexMut<Idx> for Vec<S> {
// etc.
}

vec![S(true); 1000; { (Idx(16)): false }];
// parens needed ~~~~~^~~~~~~~^```

## `no_std` support

This library supports `no_std`, if default features are disabled. This makes the `vec!` macro unavailable.

## Minimum required Rust version

Requires Rust 1.33.

## Macros

 arr A macro for array literals with superpowers. vec A macro for `Vec` literals with superpowers.