Compact set of positions

`type t`````

A `t` value represent a sequence of positions. The focus is on small memory footprint.

Given a s-expression and a sequence of positions, one can reconstruct the location of every sub s-expression. This is used to report location informations without having to annotate every node in the s-expression during parsing.

The s-expression parser saves the positions of each opening and closing parentheses as well as the positions of the first and last character of each atom.

Note that a `t` can hold the same given positions no more than twice. The parser stores the same position twice for non-quoted single character atoms.

`include sig ... end`
`val sexp_of_t : t ‑> Parsexp__.Import.Ppx_sexp_conv_lib.Sexp.t`
`val compare : t ‑> t ‑> int`
`type pos````=` `{`

`line : int;` | (** Line number. The first line has number `1`. *)
`col : int;` | (** Column number. The first column has number `0`. *)
`offset : int;` | (** Number of bytes from the beginning of the input. The first byte has offset `0`. *)

`}```

Represent a position in the input

`include sig ... end`
`val sexp_of_pos : pos ‑> Parsexp__.Import.Ppx_sexp_conv_lib.Sexp.t`
`val compare_pos : pos ‑> pos ‑> int`
`val beginning_of_file : pos`
`val shift_pos : pos ‑> cols:int ‑> pos`
`type range````=` `{`

`start_pos : pos;`
`end_pos : pos;`

`}```

Range of positions, as reported in error messages. We follow the lexing conventions of OCaml, i.e. `start_pos` points to the first character and `end_pos` points to the position just after the last character.

This allow for instance to represent empty ranges with `start_pos = end_pos`.

`include sig ... end`
`val sexp_of_range : range ‑> Parsexp__.Import.Ppx_sexp_conv_lib.Sexp.t`
`val compare_range : range ‑> range ‑> int`
`val make_range_incl : start_pos:pos ‑> last_pos:pos ‑> range`

Make a range from two positions where both positions are inclusive, i.e. `start_pos` points to the first character and `end_pos` points to the last one. The character at `last_pos` is assumed to not be a newline character.

`module Builder : sig ... end with type positions := t`
`val to_list : t ‑> pos list`

Build the list of all positions in `t`.

`val to_array : t ‑> pos array`

Build the array of all positions in `t`.

`val find : t ‑> int ‑> int ‑> range`

`find t start stop` returns the range of positions starting at position with index `start` in `t` and ending at position with index `stop`.

`find t i j` is the same as:

          let a = to_array t in
          make_range_incl ~start_pos:a.(i) ~last_pos:a.(j)

but more efficient.

`val find_sub_sexp_phys : t ‑> Parsexp__.Import.Ppx_sexp_conv_lib.Sexp.t ‑> sub:Parsexp__.Import.Ppx_sexp_conv_lib.Sexp.t ‑> range option`

`find_sub_sexp_phys t sexp ~sub` looks for `sub` in `sexp` and return its location, assuming `t` is the sequence of positions associated with `sexp`.

Comparison is done using physical equality.

`val find_sub_sexp_in_list_phys : t ‑> Parsexp__.Import.Ppx_sexp_conv_lib.Sexp.t list ‑> sub:Parsexp__.Import.Ppx_sexp_conv_lib.Sexp.t ‑> range option`
`val memory_footprint_in_bytes : t ‑> int`

Returns how much memory is used by `t`

`module Iterator : sig ... end with type positions := t`

API for iterating over positions in an efficient way