You can combine templates with `&&` / `||`:

```{r}
vet(numeric(1L) || NULL, NULL)
vet(numeric(1L) || NULL, 42)
vet(numeric(1L) || NULL, "foo")
```

Templates only check structure.  When you need to check values use `.` to
refer to the object:

```{r}
vet(numeric(1L) && . > 0, -42)  # strictly positive scalar numeric
vet(numeric(1L) && . > 0, 42)
```

If you do use the `.` symbol in your vetting expressions in your packages, you
will need to include `utils::globalVariables(".")` as a top-level call to avoid
the "no visible binding for global variable '.'" R CMD check NOTE.

You can compose vetting expressions as language objects and combine them:

```{r}
scalar.num.pos <- quote(numeric(1L) && . > 0)
foo.or.bar <- quote(character(1L) && . %in% c('foo', 'bar'))
vet.exp <- quote(scalar.num.pos || foo.or.bar)

vet(vet.exp, 42)
vet(vet.exp, "foo")
vet(vet.exp, "baz")
```

`all_bw` is available for value range checks (~10x faster than
`isTRUE(all(. >= x & . <= y))` for large vectors):

```{r}
vet(all_bw(., 0, 1), runif(5) + 1)
```

There are a number of predefined vetting tokens you can use in your
vetting expressions such as:

```{r}
vet(NUM.POS, -runif(5))    # positive numeric; see `?vet_token` for others
```

Vetting expressions are designed to be intuitive to use, but their
implementation is complex.  We recommend you look at `example(vet)` for usage
ideas, or at the ["Non Standard Evaluation" section of the vignette][3] for the
gory details.

