1#' Increasing sequence of integers in an interval
2#'
3#' These helpers take two endpoints and return the sequence of all
4#' integers within that interval. For `seq2_along()`, the upper
5#' endpoint is taken from the length of a vector. Unlike
6#' `base::seq()`, they return an empty vector if the starting point is
7#' a larger integer than the end point.
8#'
9#' @param from The starting point of the sequence.
10#' @param to The end point.
11#' @param x A vector whose length is the end point.
12#' @return An integer vector containing a strictly increasing
13#'   sequence.
14#' @export
15#' @examples
16#' seq2(2, 10)
17#' seq2(10, 2)
18#' seq(10, 2)
19#'
20#' seq2_along(10, letters)
21seq2 <- function(from, to) {
22  if (length(from) != 1) {
23    abort("`from` must be length one")
24  }
25  if (length(to) != 1) {
26    abort("`to` must be length one")
27  }
28
29  if (from > to) {
30    int()
31  } else {
32    seq.int(from, to)
33  }
34}
35#' @rdname seq2
36#' @export
37seq2_along <- function(from, x) {
38  seq2(from, length(x))
39}
40
41first <- function(x) {
42  .subset2(x, 1L)
43}
44last <- function(x) {
45  .subset2(x, length_(x))
46}
47
48validate_index <- function(i, n) {
49  seq_len(n)[i]
50}
51
52
53#' Poke values into a vector
54#'
55#' @description
56#'
57#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("experimental")}
58#'
59#' These tools are for R experts only. They copy elements from `y`
60#' into `x` by mutation. You should only do this if you own `x`,
61#' i.e. if you have created it or if you are certain that it doesn't
62#' exist in any other context. Otherwise you might create unintended
63#' side effects that have undefined consequences.
64#'
65#' @param x The destination vector.
66#' @param start The index indicating where to start modifying `x`.
67#' @param y The source vector.
68#' @param from The index indicating where to start copying from `y`.
69#' @param n How many elements should be copied from `y` to `x`.
70#' @param to The index indicating the end of the range to copy from `y`.
71#'
72#' @keywords internal
73#' @export
74vec_poke_n <- function(x, start, y,
75                       from = 1L,
76                       n = length(y)) {
77  stopifnot(
78    is_integerish(start),
79    is_integerish(from),
80    is_integerish(n)
81  )
82  .Call(rlang_vec_poke_n, x, start, y, from, n)
83}
84#' @rdname vec_poke_n
85#' @export
86vec_poke_range <- function(x, start, y,
87                           from = 1L,
88                           to = length(y) - from + 1L) {
89  stopifnot(
90    is_integerish(start),
91    is_integerish(from),
92    is_integerish(to)
93  )
94  .Call(rlang_vec_poke_range, x, start, y, from, to)
95}
96