`for_all p s` checks if all characters in `s` satisfy the predicate `p`.

**Since:** 4.13

`val exists : f:(char -> bool) -> bytes -> bool`

`exists p s` checks if at least one character of `s` satisfies the predicate `p`.

**Since:** 4.13

`val trim : bytes -> bytes`

Return a copy of the argument, without leading and trailing whitespace. The bytes regarded as whitespace are the ASCII characters ' ', '\012', '\n', '\r', and '\t`.

`val escaped : bytes -> bytes`

Return a copy of the argument, with special characters represented by escape sequences, following the lexical conventions of OCaml. All characters outside the ASCII printable range (32..126) are escaped, as well as backslash and double-quote.

**Raises** `Invalid_argument` if the result is longer than `Sys.max_string_length[29.60]` bytes.

`val index : bytes -> char -> int`

`index s c` returns the index of the first occurrence of byte `c` in `s`.

**Raises** `Not_found` if `c` does not occur in `s`.

`val index_opt : bytes -> char -> int option`

`index_opt s c` returns the index of the first occurrence of byte `c` in `s` or `None` if `c` does not occur in `s`.

**Since:** 4.05

`val rindex : bytes -> char -> int`

`rindex s c` returns the index of the last occurrence of byte `c` in `s`.

**Raises** `Not_found` if `c` does not occur in `s`.

`val rindex_opt : bytes -> char -> int option`

`rindex_opt s c` returns the index of the last occurrence of byte `c` in `s` or `None` if `c` does not occur in `s`.

**Since:** 4.05

`val index_from : bytes -> int -> char -> int`

`index_from s i c` returns the index of the first occurrence of byte `c` in `s` after position `i`.

`index s c` is equivalent to `index_from s 0 c`.

**Raises**

* `Invalid_argument` if `i` is not a valid position in `s`.

* `Not_found` if `c` does not occur in `s` after position `i`.
val get_temp_dir_name : unit -> string

The name of the temporary directory: Under Unix, the value of the `TMPDIR` environment variable, or `/tmp` if the variable is not set. Under Windows, the value of the `TEMP` environment variable, or `.` if the variable is not set. The temporary directory can be changed with `Filename.set_temp_dir_name[28.19]`.

**Since:** 4.00

val set_temp_dir_name : string -> unit

Change the temporary directory returned by `Filename.get_temp_dir_name[28.19]` and used by `Filename.temp_file[28.19]` and `Filename.open_temp_file[28.19]`. The temporary directory is a domain-local value which is inherited by child domains.

**Since:** 4.00

val quote : string -> string

Return a quoted version of a file name, suitable for use as one argument in a command line, escaping all meta-characters. Warning: under Windows, the output is only suitable for use with programs that follow the standard Windows quoting conventions.

val quote_command :
    string ->
    ?stdin: string -> ?stdout: string -> ?stderr: string -> string list -> string
    quote_command cmd args returns a quoted command line, suitable for use as an argument
to Sys.command[28.55], Unix.system[30.1], and the Unix.open_process[30.1] functions.

The string `cmd` is the command to call. The list `args` is the list of arguments to pass to this command. It can be empty.

The optional arguments `?stdin` and `?stdout` and `?stderr` are file names used to redirect the standard input, the standard output, or the standard error of the command. If `~stdin:f` is given, a redirection `< f` is performed and the standard input of the command reads from file `f`. If `~stdout:f` is given, a redirection `> f` is performed and the standard output of the command is written to file `f`. If `~stderr:f` is given, a redirection `2> f` is performed and the standard error of the command is written to file `f`. If both `~stdout:f` and `~stderr:f` are given, with the exact same file name `f`, a `2>&1` redirection is performed so that the standard output and the standard error of the command are interleaved and redirected to the same file `f`.

Under Unix and Cygwin, the command, the arguments, and the redirections if any are quoted using `Filename.quote[28.19]`, then concatenated. Under Win32, additional quoting is performed as required by the `cmd.exe` shell that is called by `Sys.command[28.55]`.

**Since:** 4.10

**Raises** Failure if the command cannot be escaped on the current platform.
val index_from_opt : bytes -> int -> char -> int option

index_from_opt s i c returns the index of the first occurrence of byte c in s after position i or None if c does not occur in s after position i. index_opt s c is equivalent to index_from_opt s 0 c.

Since: 4.05

Raises Invalid_argument if i is not a valid position in s.

val rindex_from : bytes -> int -> char -> int

rindex_from s i c returns the index of the last occurrence of byte c in s before position i+1. rindex s c is equivalent to rindex_from s (length s - 1) c.

Raises

* Invalid_argument if i+1 is not a valid position in s.

* Not_found if c does not occur in s before position i+1.

val rindex_from_opt : bytes -> int -> char -> int option

rindex_from_opt s i c returns the index of the last occurrence of byte c in s before position i+1 or None if c does not occur in s before position i+1. rindex_opt s c is equivalent to rindex_from s (length s - 1) c.

Since: 4.05

Raises Invalid_argument if i+1 is not a valid position in s.

val contains : bytes -> char -> bool

contains s c tests if byte c appears in s.

val contains_from : bytes -> int -> char -> bool

contains_from s start c tests if byte c appears in s after position start. contains s c is equivalent to contains_from s 0 c.

Raises Invalid_argument if start is not a valid position in s.

val rcontains_from : bytes -> int -> char -> bool

rcontains_from s stop c tests if byte c appears in s before position stop+1.

Raises Invalid_argument if stop < 0 or stop+1 is not a valid position in s.

val uppercase波 : bytes -> bytes

Return a copy of the argument, with all lowercase letters translated to uppercase, using the
US-ASCII character set.

Since: 4.05

val lowercase波 : bytes -> bytes
## 28.20 Module Float: Floating-point arithmetic.

OCaml's floating-point numbers follow the IEEE 754 standard, using double precision (64 bits) numbers. Floating-point operations never raise an exception on overflow, underflow, division by zero, etc. Instead, special IEEE numbers are returned as appropriate, such as `infinity` for 1.0 / 0.0, `neg_infinity` for -1.0 / 0.0, and `nan` ('not a number') for 0.0 / 0.0. These special numbers then propagate through floating-point computations as expected: for instance, 1.0 / infinity is 0.0, basic arithmetic operations (+, -, *, /) with `nan` as an argument return `nan`, ...

**Since:** 4.07

**val zero : float**
The floating point 0.

**Since:** 4.08

**val one : float**
The floating-point 1.

**Since:** 4.08

**val minus_one : float**
The floating-point -1.

**Since:** 4.08

**val neg : float -> float**
Unary negation.

**val add : float -> float -> float**
Floating-point addition.

**val sub : float -> float -> float**
Floating-point subtraction.

**val mul : float -> float -> float**
Floating-point multiplication.

**val div : float -> float -> float**
Floating-point division.

**val fma : float -> float -> float -> float**
fma x y z returns x * y + z, with a best effort for computing this expression with a single rounding, using either hardware instructions (providing full IEEE compliance) or a software emulation.
Return a copy of the argument, with all uppercase letters translated to lowercase, using the US-ASCII character set.

**Since: 4.05**

**val capitalize_ascii: bytes -> bytes**

Return a copy of the argument, with the first character set to uppercase, using the US-ASCII character set.

**Since: 4.05**

**val un capital ize_ascii : bytes -> bytes**

Return a copy of the argument, with the first character set to lowercase, using the US-ASCII
character set.

Since: 4.05

type t = bytes

An alias for the type of byte sequences.

val compare : t -> t -> int

The comparison function for byte sequences, with the same specification as compare[28.2].
Along with the type t, this function compare allows the module Bytes to be passed as
argument to the functors Set.Make[29.54] and Map.Make[29.35].

val equal : t -> t -> bool

The equality function for byte sequences.

Since: 4.05

val starts_with : prefix:bytes -> bytes -> bool

starts_with ~prefix s is true if and only if s starts with prefix.

Since: 4.13

val ends_with : suffix:bytes -> bytes -> bool

ends_with ~suffix s is true if and only if s ends with suffix.

Since: 4.13

Unsafe conversions (for advanced users)

This section describes unsafe, low-level conversion functions between `bytes` and `string`. They do not copy the internal data; used improperly, they can break the immutability invariant on strings. They are available for expert library authors, but for most purposes you should use the always-correct `BytesLabels.to_string` [29.9] and `BytesLabels.of_string` [29.9] instead.

val unsafe_to_string : bytes -> string
On 64-bit Cygwin, 64-bit mingw-w64 and MSVC 2017 and earlier, this function may be
emulated owing to known bugs on limitations on these platforms. Note: since software
emulation of the fma is costly, make sure that you are using hardware fma support if
performance matters.

Since: 4.08

val rem : float -> float -> float

rem a b returns the remainder of a with respect to b. The returned value is a -. n *. b,
where n is the quotient a / b rounded towards zero to an integer.

val succ : float -> float

succ x returns the floating point number right after x i.e., the smallest floating-point number greater than x. See also `Float.next_after[28.20]`.

Since: 4.08

val pred : float -> float

pred x returns the floating-point number right before x i.e., the greatest floating-point number smaller than x. See also `Float.next_after[28.20]`.

Since: 4.08

val abs : float -> float

abs f returns the absolute value of f.

val infinity : float

Positive infinity.

val neg_infinity : float

Negative infinity.

val nan : float

A special floating-point value denoting the result of an undefined operation such as 0.0 / .
0.0. Stands for 'not a number'. Any floating-point operation with nan as argument returns
nan as result, unless otherwise specified in IEEE 754 standard. As for floating-point
comparisons, =, <, <=, > and >= return false and <> returns true if one or both of their
arguments is nan.

nan is quiet_nan since 5.1; it was a signaling NaN before.

val signaling_nan : float

Signaling NaN. The corresponding signals do not raise OCaml exception, but the value can be
useful for interoperability with C libraries.

Since: 5.1

val quiet_nan : float
Unsafely convert a byte sequence into a string.

To reason about the use of `unsafe_to_string`, it is convenient to consider an "ownership" discipline. A piece of code that manipulates some data "owns" it; there are several disjoint ownership modes, including:

* Unique ownership: the data may be accessed and mutated

* Shared ownership: the data has several owners, that may only access it, not mutate it.

Unique ownership is linear: passing the data to another piece of code means giving up ownership (we cannot write the data again). A unique owner may decide to make the data shared (giving up mutation rights on it), but shared data may not become uniquely-owned again.

`unsafe_to_string` `s` can only be used when the caller owns the byte sequence `s` – either uniquely or as shared immutable data. The caller gives up ownership of `s`, and gains ownership of the returned string.

There are two valid use-cases that respect this ownership discipline:

1. Creating a string by initializing and mutating a byte sequence that is never changed after initialization is performed.

```python
let string_init len f : string =
    let s = Bytes.create len in
    for i = 0 to len - 1 do Bytes.set s i (f i) done;
    Bytes.unsafe_to_string s
```

This function is safe because the byte sequence `s` will never be accessed or mutated after `unsafe_to_string` is called. The `string_init` code gives up ownership of `s`, and returns the ownership of the resulting string to its caller.

Note that it would be unsafe if `s` was passed as an additional parameter to the function `f` as it could escape this way and be mutated in the future – `string_init` would give up ownership of `s` to pass it to `f`, and could not call `unsafe_to_string` safely.

We have provided the `String.init[29.58]`, `String.map[29.58]` and `String.mapi[29.58]` functions to cover most cases of building new strings. You should prefer those over `to_string` or `unsafe_to_string` whenever applicable.

2. Temporarily giving ownership of a byte sequence to a function that expects a uniquely owned string and returns ownership back, so that we can mutate the sequence again after the call ended.

```python
let bytes_length (s : bytes) =
    String.length (Bytes.unsafe_to_string s)
```

In this use-case, we do not promise that `s` will never be mutated after the call to `bytes_length s`. The `String.length[29.58]` function temporarily borrows unique ownership
Quiet NaN.

**Since: 5.1**

**val pi : float**

The constant pi.

**val max_float : float**

The largest positive finite value of type `float`.

**val min_float : float**

The smallest positive, non-zero, non-denormalized value of type `float`.

**val epsilon : float**

The difference between 1.0 and the smallest exactly representable floating-point number greater than 1.0.

**val is finite : float -> bool**

`is finite x` is true if and only if `x` is finite i.e., not infinite and not `Float.nan[28.20]`.

**Since: 4.08**

**val is_infinite : float -> bool**

`is_infinite x` is true if and only if `x` is `Float POS infinity[28.20]` or `Float NEG infinity[28.20]`.

**Since: 4.08**

**val is_nan : float -> bool**

`is_nan x` is true if and only if `x` is not a number (see `Float.nan[28.20]`).

**Since: 4.08**

**val is_integer : float -> bool**

`is_integer x` is true if and only if `x` is an integer.

**Since: 4.08**

**val of_int : int -> float**

Convert an integer to floating-point.

**val to_int : float -> int**

Truncate the given floating-point number to an integer. The result is unspecified if the argument is `nan` or falls outside the range of representable integers.

**val of_string : string -> float**
of the byte sequence (and sees it as a *string*), but returns this ownership back to the caller, which may assume that *s* is still a valid byte sequence after the call. Note that this is only correct because we know that `String.length[29.58]` does not capture its argument – it could escape by a side-channel such as a memoization combinator.

The caller may not mutate *s* while the string is borrowed (it has temporarily given up ownership). This affects concurrent programs, but also higher-order functions: if `String.length[29.58]` returned a closure to be called later, *s* should not be mutated until this closure is fully applied and returns ownership.

### `val unsafe_of_string : string -> bytes`

Unsafely convert a shared string to a byte sequence that should not be mutated.

The same ownership discipline that makes `unsafe_to_string` correct applies to `unsafe_of_string`: you may use it if you were the owner of the `string` value, and you will own the return `bytes` in the same mode.

In practice, unique ownership of string values is extremely difficult to reason about correctly. You should always assume strings are shared, never uniquely owned.

For example, string literals are implicitly shared by the compiler, so you never uniquely own them.

```kotlin
let incorrect = Bytes.unsafe_of_string "hello"
let s = Bytes.of_string "hello"
```

The first declaration is incorrect, because the string literal `"hello"` could be shared by the compiler with other parts of the program, and mutating `incorrect` is a bug. You must always use the second version, which performs a copy and is thus correct.

Assuming unique ownership of strings that are not string literals, but are (partly) built from string literals, is also incorrect. For example, mutating `unsafe_of_string ("foo" ^ s)` could mutate the shared string `"foo"` – assuming a rope-like representation of strings. More generally, functions operating on strings will assume shared ownership, they do not preserve unique ownership. It is thus incorrect to assume unique ownership of the result of `unsafe_of_string`.

The only case we have reasonable confidence is safe is if the produced `bytes` is shared – used as an immutable byte sequence. This is possibly useful for incremental migration of low-level programs that manipulate immutable sequences of bytes (for example ` Marshal.from_bytes[29.36]`) and previously used the `string` type for this purpose.

### `val split_on_char : sep:char -> bytes -> bytes list`

`split_on_char sep s` returns the list of all (possibly empty) subsequences of *s* that are delimited by the `sep` character. If *s* is empty, the result is the singleton list `[empty]`.

The function's output is specified by the following invariants:

* The list is not empty.
Convert the given string to a float. The string is read in decimal (by default) or in hexadecimal (marked by 0x or 0X). The format of decimal floating-point numbers is `[-]dd.ddd (e|E) [+|-]dd`, where `d` stands for a decimal digit. The format of hexadecimal floating-point numbers is `[-]0(x|X) hh.hhh (p|P) [+|-]dd`, where `h` stands for an hexadecimal digit and `d` for a decimal digit. In both cases, at least one of the integer and fractional parts must be given; the exponent part is optional. The `_` (underscore) character can appear anywhere in the string and is ignored. Depending on the execution platforms, other representations of floating-point numbers can be accepted, but should not be relied upon.

**Raises** Failure if the given string is not a valid representation of a float.

**val of_string_opt : string -> float option**

Same as `of_string`, but returns `None` instead of raising.

**val to_string : float -> string**

Return a string representation of a floating-point number.

This conversion can involve a loss of precision. For greater control over the manner in which the number is printed, see `f[28.43]`.

This function is an alias for `string_of_float[27.2]`.

**type fpclass = fpclass =**

`| FP_normal`

Normal number, none of the below

`| FP_subnormal`

Number very close to 0.0, has reduced precision

`| FP_zero`

Number is 0.0 or -0.0

`| FP_infinite`

Number is positive or negative infinity

`| FP_nan`

Not a number: result of an undefined operation

The five classes of floating-point numbers, as determined by the `Float.classify_float[28.20]` function.

**val classify_float : float -> fpclass**

Return the class of the given floating-point number: normal, subnormal, zero, infinite, or not a number.

**val pow : float -> float -> float**

Exponentiation.
* Concatenating its elements using `sep` as a separator returns a byte sequence equal to the input (Bytes.concat (Bytes.make 1 sep) (Bytes.split_on_char sep s) = s).

* No byte sequence in the result contains the `sep` character.

**Since:** 4.13

## Iterators

`val to_seq : t -> char Seq.t`

Iterate on the string, in increasing index order. Modifications of the string during iteration will be reflected in the sequence.

**Since:** 4.07

`val to_seqi : t -> (int * char) Seq.t`

Iterate on the string, in increasing order, yielding indices along chars

**Since:** 4.07

`val of_seq : char Seq.t -> t`

Create a string from the generator

**Since:** 4.07

# UTF codecs and validations

## UTF-8

`val get_utf_8_uchar : t -> int -> Uchar.utf_decode`

`get_utf_8_uchar b i` decodes an UTF-8 character at index `i` in `b`.

`val set_utf_8_uchar : t -> int -> Uchar.t -> int`

`set_utf_8_uchar b i u` UTF-8 encodes `u` at index `i` in `b` and returns the number of bytes `n` that were written starting at `i`. If `n` is 0 there was not enough space to encode `u` at `i` and `b` was left untouched. Otherwise a new character can be encoded at `i + n`.

`val is_valid_utf_8 : t -> bool`

`is_valid_utf_8 b` is true if and only if `b` contains valid UTF-8 data.

## UTF-16BE

`val get_utf_16be_uchar : t -> int -> Uchar.utf_decode`

`get_utf_16be_uchar b i` decodes an UTF-16BE character at index `i` in `b`.

`val set_utf_16be_uchar : t -> int -> Uchar.t -> int`
val sqrt : float -> float
Square root.

val cbrt : float -> float
Cube root.

Since: 4.13

val exp : float -> float
Exponential.

val exp2 : float -> float
Base 2 exponential function.

Since: 4.13

val log : float -> float
Natural logarithm.

val log10 : float -> float
Base 10 logarithm.

val log2 : float -> float
Base 2 logarithm.

Since: 4.13

val expm1 : float -> float
expm1 x computes exp x -. 1.0, giving numerically-accurate results even if x is close to
0.0.

val log1p : float -> float
log1p x computes log(1.0 +. x) (natural logarithm), giving numerically-accurate results
even if x is close to 0.0.

val cos : float -> float
Cosine. Argument is in radians.

val sin : float -> float
Sine. Argument is in radians.

val tan : float -> float
Tangent. Argument is in radians.

val acos : float -> float
Arc cosine. The argument must fall within the range [-1.0, 1.0]. Result is in radians and
is between 0.0 and pi.
`set_utf_16be_uchar b i u` UTF-16BE encodes `u` at index `i` in `b` and returns the number of bytes `n` that were written starting at `i`. If `n` is 0 there was not enough space to encode `u` at `i` and `b` was left untouched. Otherwise a new character can be encoded at `i + n`.

`val is_valid_utf_16be : t -> bool`

`is_valid_utf_16be b` is `true` if and only if `b` contains valid UTF-16BE data.

## UTF-16LE

`val get_utf_16le_uchar : t -> int -> Uchar.utf_decode`

`get_utf_16le_uchar b i` decodes an UTF-16LE character at index `i` in `b`.

`val set_utf_16le_uchar : t -> int -> Uchar.t -> int`

`set_utf_16le_uchar b i u` UTF-16LE encodes `u` at index `i` in `b` and returns the number of bytes `n` that were written starting at `i`. If `n` is 0 there was not enough space to encode `u` at `i` and `b` was left untouched. Otherwise a new character can be encoded at `i + n`.

`val is_valid_utf_16le : t -> bool`

`is_valid_utf_16le b` is `true` if and only if `b` contains valid UTF-16LE data.

## Binary encoding/decoding of integers

The functions in this section binary encode and decode integers to and from byte sequences.

All following functions raise `Invalid_argument` if the space needed at index `i` to decode or encode the integer is not available.

Little-endian (resp. big-endian) encoding means that least (resp. most) significant bytes are stored first. Big-endian is also known as network byte order. Native-endian encoding is either little-endian or big-endian depending on `Sys.big_endian` [29.60].

32-bit and 64-bit integers are represented by the `int32` and `int64` types, which can be interpreted either as signed or unsigned numbers.

8-bit and 16-bit integers are represented by the `int` type, which has more bits than the binary encoding. These extra bits are handled as follows:

* Functions that decode signed (resp. unsigned) 8-bit or 16-bit integers represented by `int` values sign-extend (resp. zero-extend) their result.

* Functions that encode 8-bit or 16-bit integers represented by `int` values truncate their input to their least significant bytes.

`val get_uint8 : bytes -> int -> int`

`get_uint8 b i` is `b`'s unsigned 8-bit integer starting at byte index `i`.

Since: 4.08

`val get_int8 : bytes -> int -> int`
val asin : float -> float

Arc sine. The argument must fall within the range [-1.0, 1.0]. Result is in radians and is between -pi/2 and pi/2.

val atan : float -> float

Arc tangent. Result is in radians and is between -pi/2 and pi/2.

val atan2 : float -> float -> float

atan2 y x returns the arc tangent of y / x. The signs of x and y are used to determine the quadrant of the result. Result is in radians and is between -pi and pi.

val hypot : float -> float -> float

hypot x y returns sqrt(x * x + y * y), that is, the length of the hypotenuse of a right-angled triangle with sides of length x and y, or, equivalently, the distance of the point (x,y) to origin. If one of x or y is infinite, returns infinity even if the other is nan.

val cosh : float -> float

Hyperbolic cosine. Argument is in radians.

val sinh : float -> float

Hyperbolic sine. Argument is in radians.

val tanh : float -> float

Hyperbolic tangent. Argument is in radians.

val acosh : float -> float

Hyperbolic arc cosine. The argument must fall within the range [1.0, inf]. Result is in radians and is between 0.0 and inf.

Since: 4.13

val asinh : float -> float

Hyperbolic arc sine. The argument and result range over the entire real line. Result is in radians.

Since: 4.13

val atanh : float -> float

Hyperbolic arc tangent. The argument must fall within the range [-1.0, 1.0]. Result is in radians and ranges over the entire real line.

Since: 4.13

val erf : float -> float

Error function. The argument ranges over the entire real line. The result is always within [-1.0, 1.0].

Since: 4.13
get_int8 b i is b's signed 8-bit integer starting at byte index i.

Since: 4.08

val get_uint16_ne : bytes -> int -> int

get_uint16_ne b i is b's native-endian unsigned 16-bit integer starting at byte index i.

Since: 4.08

val get_uint16_be : bytes -> int -> int

get_uint16_be b i is b's big-endian unsigned 16-bit integer starting at byte index i.

Since: 4.08

val get_uint16_le : bytes -> int -> int

get_uint16_le b i is b's little-endian unsigned 16-bit integer starting at byte index i.

Since: 4.08

val get_int16_ne : bytes -> int -> int

get_int16_ne b i is b's native-endian signed 16-bit integer starting at byte index i.

Since: 4.08

val get_int16_be : bytes -> int -> int

get_int16_be b i is b's big-endian signed 16-bit integer starting at byte index i.

Since: 4.08

val get_int16_le : bytes -> int -> int

get_int16_le b i is b's little-endian signed 16-bit integer starting at byte index i.

Since: 4.08

val get_int32_ne : bytes -> int -> int32

get_int32_ne b i is b's native-endian 32-bit integer starting at byte index i.

Since: 4.08

val get_int32_be : bytes -> int -> int32

get_int32_be b i is b's big-endian 32-bit integer starting at byte index i.

Since: 4.08

val get_int32_le : bytes -> int -> int32

get_int32_le b i is b's little-endian 32-bit integer starting at byte index i.

Since: 4.08

val get_int64_ne : bytes -> int -> int64
### `val erfc: float -> float`

Complementary error function ($erfc x = 1 - erf x$). The argument ranges over the entire real line. The result is always within [-1.0, 1.0].

**Since:** 4.13

### `val trunc: float -> float`

`trunc x` rounds `x` to the nearest integer whose absolute value is less than or equal to `x`.

**Since:** 4.08

### `val round: float -> float`

`round x` rounds `x` to the nearest integer with ties (fractional values of 0.5) rounded away from zero, regardless of the current rounding direction. If `x` is an integer, `+0.`, `-0.`, `nan`, or infinite, `x` itself is returned.

On 64-bit mingw-w64, this function may be emulated owing to a bug in the C runtime library (CRT) on this platform.

**Since:** 4.08

### `val ceil: float -> float`

Round above to an integer value. `ceil f` returns the least integer value greater than or equal to `f`. The result is returned as a float.

### `val floor: float -> float`

Round below to an integer value. `floor f` returns the greatest integer value less than or equal to `f`. The result is returned as a float.

### `val next_after: float -> float -> float`

`next_after x y` returns the next representable floating-point value following `x` in the direction of `y`. More precisely, if `y` is greater (resp. less) than `x`, it returns the smallest (resp. largest) representable number greater (resp. less) than `x`. If `x` equals `y`, the function returns `y`. If `x` or `y` is `nan`, a `nan` is returned. Note that `next_after max_float infinity = infinity` and that `next_after 0. infinity` is the smallest denormalized positive number. If `x` is the smallest denormalized positive number, `next_after x 0. = 0.`

**Since:** 4.08

### `val copy_sign: float -> float -> float`

`copy_sign x y` returns a float whose absolute value is that of `x` and whose sign is that of `y`. If `x` is `nan`, returns `nan`. If `y` is `nan`, returns either `x` or `-`. `x`, but it is not specified which.

### `val sign_bit: float -> bool`

`sign_bit x` is `true` if and only if the sign bit of `x` is set. For example `sign_bit 1.` and `signbit 0.` are `false` while `sign_bit (-1.)` and `sign_bit (-0.)` are `true`.

**Since:** 4.08
`get_int64_ne` b i is b's native-endian 64-bit integer starting at byte index i.

Since: 4.08

`val get_int64_be`: `bytes -> int -> int64`

`get_int64_be` b i is b's big-endian 64-bit integer starting at byte index i.

Since: 4.08

`val get_int64_le`: `bytes -> int -> int64`

`get_int64_le` b i is b's little-endian 64-bit integer starting at byte index i.

Since: 4.08

`val set_uint8`: `bytes -> int -> int -> unit`

`set_uint8` b i v sets b's unsigned 8-bit integer starting at byte index i to v.

Since: 4.08

`val set_int8`: `bytes -> int -> int -> unit`

`set_int8` b i v sets b's signed 8-bit integer starting at byte index i to v.

Since: 4.08

`val set_uint16_ne`: `bytes -> int -> int -> unit`

`set_uint16_ne` b i v sets b's native-endian unsigned 16-bit integer starting at byte index i to v.

Since: 4.08

`val set_uint16_be`: `bytes -> int -> int -> unit`

`set_uint16_be` b i v sets b's big-endian unsigned 16-bit integer starting at byte index i to v.

Since: 4.08

`val set_uint16_le`: `bytes -> int -> int -> unit`

`set_uint16_le` b i v sets b's little-endian unsigned 16-bit integer starting at byte index i to v.

Since: 4.08

`val set_int16_ne`: `bytes -> int -> int -> unit`

`set_int16_ne` b i v sets b's native-endian signed 16-bit integer starting at byte index i to v.

Since: 4.08

`val set_int16_be`: `bytes -> int -> int -> unit`

`set_int16_be` b i v sets b's big-endian signed 16-bit integer starting at byte index i to v.

Since: 4.08
val frexp : float -> float * int

frexp f returns the pair of the significant and the exponent of f. When f is zero, the
significant x and the exponent n of f are equal to zero. When f is non-zero, they are defined
by $f = x *$. $2 ** n$ and $0.5 <= x < 1.0$.

val ldexp : float -> int -> float

ldexp x n returns x *. 2 ** n.

val modf : float -> float * float

modf f returns the pair of the fractional and integral part of f.

type t = float

An alias for the type of floating-point numbers.

val compare : t -> t -> int

compare x y returns 0 if x is equal to y, a negative integer if x is less than y, and a positive integer if x is greater than y. compare treats nan as equal to itself and less than any other float value. This treatment of nan ensures that compare defines a total ordering relation.

val equal : t -> t -> bool

The equal function for floating-point numbers, compared using Float comparisons.

val min : t -> t -> t

min x y returns the minimum of x and y. It returns nan when x or y is nan. Moreover min
(-0.) (+0.) = -0.

Since: 4.08

val max : float -> float -> float

max x y returns the maximum of x and y. It returns nan when x or y is nan. Moreover max
(-0.) (+0.) = +0.

Since: 4.08

val min_max : float -> float -> float * float

min_max x y is (min x y, max x y), just more efficient.

Since: 4.08

val min_num : t -> t -> t

min_num x y returns the minimum of x and y treating nan as missing values. If both x and y are nan, nan is returned. Moreover min_num (-0.) (+0.) = -0.

Since: 4.08

val max_num : t -> t -> t
val set_int16_le : bytes -> int -> int -> unit
  set_int16_le b i v sets b's little-endian signed 16-bit integer starting at byte index i to v.
  Since: 4.08

val set_int32_ne : bytes -> int -> int32 -> unit
  set_int32_ne b i v sets b's native-endian 32-bit integer starting at byte index i to v.
  Since: 4.08

val set_int32_be : bytes -> int -> int32 -> unit
  set_int32_be b i v sets b's big-endian 32-bit integer starting at byte index i to v.
  Since: 4.08

val set_int32_le : bytes -> int -> int32 -> unit
  set_int32_le b i v sets b's little-endian 32-bit integer starting at byte index i to v.
  Since: 4.08

val set_int64_ne : bytes -> int -> int64 -> unit
  set_int64_ne b i v sets b's native-endian 64-bit integer starting at byte index i to v.
  Since: 4.08

val set_int64_be : bytes -> int -> int64 -> unit
  set_int64_be b i v sets b's big-endian 64-bit integer starting at byte index i to v.
  Since: 4.08

val set_int64_le : bytes -> int -> int64 -> unit
  set_int64_le b i v sets b's little-endian 64-bit integer starting at byte index i to v.
  Since: 4.08

## Byte sequences and concurrency safety

Care must be taken when concurrently accessing byte sequences from multiple domains: accessing a byte sequence will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

## Atomicity

Every byte sequence operation that accesses more than one byte is not atomic. This includes iteration and scanning.

For example, consider the following program:

```python
let size = 100_000_000
let b = Bytes.make size ' '
let update b f () =
```
`max_num` x y returns the maximum of x and y treating `nan` as missing values. If both x and y are `nan` `nan` is returned. Moreover `max_num` (`-0.`) (`+0.`) = `+0`.

Since: 4.08

`val min_max_num : float -> float -> float * float`

`min_max_num` x y is (`min_num` x y, `max_num` x y), just more efficient. Note that in particular `min_max_num` x `nan` = (x, x) and `min_max_num` `nan` y = (y, y).

Since: 4.08

`val seeded_hash : int -> t -> int`

A seeded hash function for floats, with the same output value as `Hashtbl.seeded_hash[28.24]`. This function allows this module to be passed as argument to the functor `Hashtbl.MakeSeeded[28.24]`.

Since: 5.1

`val hash : t -> int`

An unseeded hash function for floats, with the same output value as `Hashtbl.hash[28.24]`. This function allows this module to be passed as argument to the functor `Hashtbl.Make[28.24]`.

`module Array :`

sig

type t = floatarray

The type of float arrays with packed representation.

Since: 4.08

`val length : t -> int`

Return the length (number of elements) of the given floatarray.

`val get : t -> int -> float`

`get` n returns the element number n of floatarray a.

Raises `Invalid_argument` if n is outside the range 0 to (length a - 1).

`val set : t -> int -> float -> unit`

`set` a n x modifies floatarray a in place, replacing element number n with x.

Raises `Invalid_argument` if n is outside the range 0 to (length a - 1).

`val make : int -> float -> t`

`make` n x returns a fresh floatarray of length n, initialized with x.

Raises `Invalid_argument` if n < 0 or n > Sys.max_floatarray_length.
```h
Bytes.iteri (fun i x -> Bytes.set b i (Char.chr (f (Char.code x)))) b
let d1 = Domain spawn (update b (fun x -> x + 1))
let d2 = Domain spawn (update b (fun x -> 2 * x + 1))
let () = Domain.join d1; Domain.join d2
```

the bytes sequence `b` may contain a non-deterministic mixture of `!`, `'A'`, `'B'`, and `'C'` values.

After executing this code, each byte of the sequence `b` is either `!`, `'A'`, `'B'`, or `'C'`. If atomicity is required, then the user must implement their own synchronization (for example, using `Mutex.t[29.38]`).

## Data races

If two domains only access disjoint parts of a byte sequence, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same byte without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the elements of the sequence.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location.

## Mixed-size accesses

Another subtle point is that if a data race involves mixed-size writes and reads to the same location, the order in which those writes and reads are observed by domains is not specified. For instance, the following code write sequentially a 32-bit integer and a `char` to the same index

```h
let b = Bytes.make 10 '\000'
let d1 = Domain spawn (fun () -> Bytes.set_int32_ne b 0 100; b.[0] <- 'd')
```

In this situation, a domain that observes the write of 'd' to b.0 is not guaranteed to also observe the write to indices 1, 2, or 3.

## 29.10 Module Callback : Registering OCaml values with the C runtime.

This module allows OCaml values to be registered with the C runtime under a symbolic name, so that C code can later call back registered OCaml functions, or raise registered OCaml exceptions.

```h
val register : string -> 'a -> unit
```
```kotlin
val create : int -> t
```

`create` n returns a fresh floatarray of length n, with uninitialized data.

**Raises** Invalid_argument if n < 0 or n > Sys.maxFloatarray_length.

```kotlin
val init : int -> (int -> float) -> t
```

`init` n f returns a fresh floatarray of length n, with element number i initialized to the result of f i. In other terms, `init` n f tabulates the results of f applied to the integers 0 to n-1.

**Raises** Invalid_argument if n < 0 or n > Sys.maxFloatarray_length.

```kotlin
val append : t -> t -> t
```

`append` v1 v2 returns a fresh floatarray containing the concatenation of the floatarrays v1 and v2.

**Raises** Invalid_argument if length v1 + length v2 > Sys.maxFloatarray_length.

```kotlin
val concat : t list -> t
```

Same as `Float Array.append[28.20]`, but concatenates a list of floatarrays.

```kotlin
val sub : t -> int -> int -> t
```

`sub` a pos len returns a fresh floatarray of length len, containing the elements number pos to pos + len - 1 of floatarray a.

**Raises** Invalid_argument if pos and len do not designate a valid subarray of a; that is, if pos < 0, or len < 0, or pos + len > length a.

```kotlin
val copy : t -> t
```

`copy` a returns a copy of a, that is, a fresh floatarray containing the same elements as a.

```kotlin
val fill : t -> int -> int -> float -> unit
```

`fill` a pos len x modifies the floatarray a in place, storing x in elements number pos to pos + len - 1.

**Raises** Invalid_argument if pos and len do not designate a valid subarray of a.

```kotlin
val blit : t -> int -> t -> int -> int -> unit
```

`blit` src src_pos dst dst_pos len copies len elements from floatarray src, starting at element number src_pos, to floatarray dst, starting at element number dst_pos. It works correctly even if src and dst are the same floatarray, and the source and destination chunks overlap.

**Raises** Invalid_argument if src_pos and len do not designate a valid subarray of src, or if dst_pos and len do not designate a valid subarray of dst.
`Callback.register` n v registers the value v under the name n. C code can later retrieve a handle to v by calling `caml_named_value(n)`.

`val register_exception : string -> exn -> unit`

`Callback.register_exception` n exn registers the exception contained in the exception value exn under the name n. C code can later retrieve a handle to the exception by calling `caml_named_value(n)`. The exception value thus obtained is suitable for passing as first argument to `raiseConstant` or `raise_with_arg`.

## 29.11 Module Char : Character operations.

Characters are the elements of `string` and `bytes` values. Characters represent bytes, that is an integer in the range `[0x00;0xFF]`.

Some of the functions of this module interpret the characters in the range `[0x00;0x7F]` as the characters of the ASCII character set.

### Characters

`type t = char`

An alias for the type of characters.

`val code : char -> int`

Return the integer code of the argument.

`val chr : int -> char`

Return the character with the given integer code.

**Raises** `Invalid_argument` if the argument is outside the range `[0x00;0xFF]`.

`val escaped : char -> string`

Return a string representing the given character, with special characters escaped following the lexical conventions of OCaml. All characters outside the ASCII printable range `[0x20;0x7E]` are escaped, as well as backslash, double-quote, and single-quote.

### Predicates and comparisons

See also the `Char.Ascii`[29.11] module.

`val compare : t -> t -> int`

The comparison function for characters, with the same specification as `compare`[28.2]. Along with the type `t`, this function `compare` allows the module `Char` to be passed as argument to the functors `Set.Make`[29.54] and `Map.Make`[29.35].

`val equal : t -> t -> bool`
val to_list : t -> float list

to_list a returns the list of all the elements of a.

val of_list : float list -> t

of_list l returns a fresh floatarray containing the elements of l.

Raises Invalid_argument if the length of l is greater than
Sys.max_floatarray_length.

Iterators

val iter : (float -> unit) -> t -> unit

iter f a applies function f in turn to all the elements of a. It is equivalent to f a.(0);
f a.(1); ...; f a.(length a - 1); ().

val iteri : (int -> float -> unit) -> t -> unit

Same as Float Array.iter [28.20], but the function is applied with the index of the element as first argument, and the element itself as second argument.

val map : (float -> float) -> t -> t

map f a applies function f to all the elements of a, and builds a floatarray with the
results returned by f.

val map_inplace : (float -> float) -> t -> unit

map_inplace f a applies function f to all elements of a, and updates their values in
place.

Since: 5.1

val mapi : (int -> float -> float) -> t -> t

Same as Float Array.map [28.20], but the function is applied to the index of the element as first argument, and the element itself as second argument.

val mapi_inplace : (int -> float -> float) -> t -> unit

Same as Float Array.map_inplace [28.20], but the function is applied to the index of
the element as first argument, and the element itself as second argument.

Since: 5.1

val fold_left : ('acc -> float -> 'acc) -> 'acc -> t -> 'acc

fold_left f x init computes f (... (f (f x init.(0)) init.(1)) ...) init.(n-1), where n is the length of the floatarray init.

val fold_right : (float -> 'acc -> 'acc) -> t -> 'acc -> 'acc

fold_right f a init computes f a.(0) (f a.(1) (... (f a.(n-1) init) ...)), where n is the length of the floatarray a.
The equal function for chars.

Since: 4.03

ASCII characters

module Ascii :
sig

Characters

val min : char

min is '\x00'.

val max : char

max is '\x7F'.

Predicates

val is_valid : char -> bool

is_valid c is true if and only if c is an ASCII character, that is a byte in the range
[Char.Ascii.min[29.11];Char.Ascii.max[29.11]].

val is_upper : char -> bool

is_upper c is true if and only if c is an ASCII uppercase letter 'A' to 'Z', that is a
byte in the range [0x41;0x5A].

val is_lower : char -> bool

is_lower c is true if and only if c is an ASCII lowercase letter 'a' to 'z', that is a
byte in the range [0x61;0x7A].

val is_letter : char -> bool

is_letter c is Char.Ascii.is_lower[29.11] c || Char.Ascii.is_upper[29.11] c.

val is_alphanum : char -> bool

is_alphanum c is Char.Ascii.is_letter[29.11] c || Char.Ascii.is\n' (0x0A), vertical tab (0x0B), form feed (0x0C), carriage return
c.

val is_white : char -> bool

is_white c is true if and only if c is an ASCII white space character, that is one of tab
'\t' (0x09), newline '\n' (0x0A), vertical tab (0x0B), form feed (0x0C), carriage return
'\r' (0x0D) or space ' ' (0x20),
## Iterators on two arrays

```kotlin
val iter2 : (float -> float -> unit) -> t -> t -> unit
```

Array.iter2 f a b applies function f to all the elements of a and b.

**Raises** Invalid_argument if the floatarrays are not the same size.

```kotlin
val map2 : (float -> float -> float) -> t -> t -> t
```

map2 f a b applies function f to all the elements of a and b, and builds a floatarray with the results returned by f: `[| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|]`.

**Raises** Invalid_argument if the floatarrays are not the same size.

## Array scanning

```kotlin
val for_all : (float -> bool) -> t -> bool
```

for_all f [|a1; ...; an|] checks if all elements of the floatarray satisfy the predicate f. That is, it returns (f a1) && (f a2) && ... && (f an).

```kotlin
val exists : (float -> bool) -> t -> bool
```

exists f [|a1; ...; an|] checks if at least one element of the floatarray satisfies the predicate f. That is, it returns (f a1) || (f a2) || ... || (f an).

```kotlin
val mem : float -> t -> bool
```

mem a set is true if and only if there is an element of set that is structurally equal to a, i.e. there is an x in set such that compare a x = 0.

```kotlin
val mem_ieee : float -> t -> bool
```

Same as `Float Array.mem` [28.20], but uses IEEE equality instead of structural equality.

## Array searching

```kotlin
val find_opt : (float -> bool) -> t -> float option
```

```kotlin
val find_index : (float -> bool) -> t -> int option
```

find_index f a returns Some i, where i is the index of the first element of the array a that satisfies f x, if there is such an element.

It returns None if there is no such element.

**Since:** 5.1

```kotlin
val find_map : (float -> 'a option) -> t -> 'a option
```

```kotlin
val find_mapi : (int -> float -> 'a option) -> t -> 'a option
```
```python
val isBlank : char -> bool
```

isalter c is true if and only if c is an ASCII blank character, that is either space ' ' (0x20) or tab '\t' (0x09).

```python
val isGraphic : char -> bool
```

isGraphic c is true if and only if c is an ASCII graphic character, that is a byte in the range [0x21;0x7E].

```python
val isPrint : char -> bool
```

is_print c is Char.Ascii.is_graphic[29.11] c || c = ' '.

```python
val isControl : char -> bool
```

is_control c is true if and only if c is an ASCII control character, that is a byte in the range [0x00;0x1F] or 0x7F.

## Decimal digits

```python
val isDigit : char -> bool
```

isDigit c is true if and only if c is an ASCII decimal digit '0' to '9', that is a byte in the range [0x30;0x39].

```python
def digit_to_int(c) -> int
```

digit_to_int c is the numerical value of a digit that satisfies
Char.Ascii.is[29.11]. Raises Invalid_argument if
Char.Ascii.isDigit[29.11] c is false.

```python
def digit_of_int(n) -> char
```

digit_of_int n is an ASCII decimal digit for the decimal value abs (n mod 10).

## Hexadecimal digits

```python
val isHexDigit : char -> bool
```

is_hexузци c is true if and only if c is an ASCII hexadecimal digit '0' to '9', 'a' to 'f' or 'A' to 'F', that is a byte in one of the ranges [0x30;0x39], [0x41;0x46], [0x61;0x66].

```python
val hexDigitToInt : char -> int
```

hexDigit_to_int c is the numerical value of a digit that satisfies
Char.Ascii.is_hexDigit[29.11]. Raises Invalid_argument if
Char.Ascii.is_hexузци[29.11] c is false.
Same as `find_map`, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

**Since: 5.1**

## Sorting

`val sort : (float -> float -> int) -> t -> unit`

Sort a floatarray in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, `compare[27.2]` is a suitable comparison function. After calling `sort`, the array is sorted in place in increasing order. `sort` is guaranteed to run in constant heap space and (at most) logarithmic stack space.

The current implementation uses Heap Sort. It runs in constant stack space.

Specification of the comparison function: Let `a` be the floatarray and `cmp` the comparison function. The following must be true for all `x`, `y`, `z` in `a`:

* `cmp x y > 0` if and only if `cmp y x < 0`

* if `cmp x y ≥ 0` and `cmp y z ≥ 0` then `cmp x z ≥ 0`

When `sort` returns, `a` contains the same elements as before, reordered in such a way that for all `i` and `j` valid indices of `a`:

* `cmp a.(i) a.(j) ≥ 0` if and only if `i ≥ j`

`val stable_sort : (float -> float -> int) -> t -> unit`

Same as `FloatolaSort`. But the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.

The current implementation uses Merge Sort. It uses a temporary floatarray of length `n/2`, where `n` is the length of the floatarray. It is usually faster than the current implementation of `FloatolaSort`.

`val fast_sort : (float -> float -> int) -> t -> unit`

Same as `Float Array.sort` [28.20] or `Float Array.stable_sort` [28.20], whichever is faster on typical input.

## Float arrays and Sequences

`val to_seq : t -> float Seq.t`

Iterate on the floatarray, in increasing order. Modifications of the floatarray during iteration will be reflected in the sequence.
```h
val lower_hexузdigit_of_int : int -> char
```

`lower_hex謝digit_of_int n` is a lowercase ASCII hexadecimal digit for the hexadecimal value `abs (n mod 16)`.

```h
val upper_hex謝digit_of_int : int -> char
```

`upper_hex謝digit_of_int n` is an uppercase ASCII hexadecimal digit for the hexadecimal value `abs (n mod 16)`.

## Casing transforms

```h
val uppercase : char -> char
```

`uppercase c` is `c` with ASCII characters 'a' to 'z' respectively mapped to uppercase characters 'A' to 'Z'. Other characters are left untouched.

```h
val lowercase : char -> char
```

`lowercase c` is `c` with ASCII characters 'A' to 'Z' respectively mapped to lowercase characters 'a' to 'z'. Other characters are left untouched.

end

ASCII character set support.

These functions give meaning to the integers `[0x00;0x7F]` of the ASCII character set[https://en.wikipedia.org/wiki/ASCII#Character_set].

Since the UTF-8 encoding of Unicode has the same encoding and character semantics (U+0000 to U+001F) for these bytes, the functions can be safely used on elements of UTF-8 encoded `string` and `bytes` values. However the functions only deal with ASCII related matters. For example the notion of Unicode whitespace is much larger than the ASCII whitespace determined by `Char.Ascii.is_white[29.11]`.

Since: 5.4

```h
val lowercase_ascii : char -> char
```

Use the equivalent `Char.Ascii.lowercase[29.11]` instead.

Since: 4.03

```h
val uppercase_ascii : char -> char
```

Use the equivalent `Char.Ascii.uppercase[29.11]` instead.

Since: 4.03
```h
val to_seqi : t -> (int * float) Seq.t
```

Iterate on the floatarray, in increasing order, yielding indices along elements.

Modifications of the floatarray during iteration will be reflected in the sequence.

```h
val of_seq : float Seq.t -> t
```

Create an array from the generator.

```h
val map_to_array : (float -> 'a) -> t -> 'a array
```

map_to_array f a applies function f to all the elements of a, and builds an array with the results returned by f: `[| f a.(0); f a.(1); ...; f a.(length a - 1) |]`.

```h
val map_from_array : ('a -> float) -> 'a array -> t
```

map_from_array f a applies function f to all the elements of a, and builds a floatarray with the results returned by f.

## Arrays and concurrency safety

Care must be taken when concurrently accessing float arrays from multiple domains: accessing an array will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

## Atomicity

Every float array operation that accesses more than one array element is not atomic. This includes iteration, scanning, sorting, splitting and combining arrays.

For example, consider the following program:

```h
let size = 100_000_000
let a = Float Array.make size 1.
let update a f () =
    Float Array.iteri (fun i x -> Float Array.set a i (f x)) a
let d1 = Domain spawn (update a (fun x -> x +. 1.))
let d2 = Domain spawn (update a (fun x -> 2. *. x +. 1.))
let () = Domain.join d1; Domain.join d2
```

After executing this code, each field of the float array a is either 2., 3., 4. or 5.. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t[28.36]).
Hashing

val seeded_hash : int -> t -> int

A seeded hash function for characters, with the same output value as
`Hashtbl.seeded_hash[29.26]`. This function allows this module to be passed as argument to
the functor `Hashtbl.MakeSeeded[29.26]`.

Since: 5.1

val hash : t -> int

An unseeded hash function for characters, with the same output value as
`Hashtbl.hash[29.26]`. This function allows this module to be passed as argument to the
functor `Hashtbl.Make[29.26]`.

Since: 5.1

## 29.12 Module Complex : Complex numbers.

This module provides arithmetic operations on complex numbers. Complex numbers are represented by their real and imaginary parts (cartesian representation). Each part is represented by a double-precision floating-point number (type `float`).

type t =
  { re : float ;
    im : float ;
  }

The type of complex numbers. `re` is the real part and `im` the imaginary part.

val zero : t

The complex number 0.

val one : t

The complex number 1.

val i : t

The complex number i.

val neg : t -> t

Unary negation.

val conj : t -> t

Conjugate: given the complex $x + i.y$, returns $x - i.y$.

val add : t -> t -> t

Addition
## Data races

If two domains only access disjoint parts of the array, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same array element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the array elements.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location with a few exceptions.

## Tearing

Float arrays have two supplementary caveats in the presence of data races.

First, the blit operation might copy an array byte-by-byte. Data races between such a blit operation and another operation might produce surprising values due to tearing: partial writes interleaved with other operations can create float values that would not exist with a sequential execution.

For instance, at the end of

```javascript
let zeros = Float Array.make size 0.
let max_floats = Float Array.make size Float.max_float
let res = Float Array.copy zeros
let d1 = Domain spawn (fun () -> Float Array.blit zeros 0 res 0 size)
let d2 = Domain spawn (fun () -> Float Array.blit max_floats 0 res 0 size)
let () = Domain.join d1; Domain.join d2
```

the `res` float array might contain values that are neither 0. nor `max_float`.

Second, on 32-bit architectures, getting or setting a field involves two separate memory accesses. In the presence of data races, the user may observe tearing on any operation.

end

Float arrays with packed representation.

```javascript
module ArrayLabels :
sig
    type t = floatarray
```

The type of float arrays with packed representation.

**Since: 4.08**
val sub : t -> t -> t

Subtraction

val mul : t -> t -> t

Multiplication

val inv : t -> t

Multiplicative inverse (1/z).

val div : t -> t -> t

Division

val sqrt : t -> t

Square root. The result x + i.y is such that x > 0 or x = 0 and y >= 0. This function has a discontinuity along the negative real axis.

val norm2 : t -> float

Norm squared: given x + i.y, returns x^2 + y^2.

val norm : t -> float

Norm: given x + i.y, returns sqrt(x^2 + y^2).

val arg : t -> float

Argument. The argument of a complex number is the angle in the complex plane between the positive real axis and a line passing through zero and the number. This angle ranges from -pi to pi. This function has a discontinuity along the negative real axis.

val polar : float -> float -> t

polar norm arg returns the complex having norm norm and argument arg.

val exp : t -> t

Exponentiation. exp z returns e to the z power.

val log : t -> t

Natural logarithm (in base e).

val pow : t -> t -> t

Power function. pow z1 z2 returns z1 to the z2 power.
```kotlin
val length : t -> int
```

Return the length (number of elements) of the given floatarray.

```kotlin
val get : t -> int -> float
```

get a `n` returns the element number `n` of floatarray `a`.

**Raises** Invalid_argument if `n` is outside the range 0 to (`length a` - 1).

```kotlin
val set : t -> int -> float -> unit
```

set a `n` modifies floatarray `a` in place, replacing element number `n` with `x`.

**Raises** Invalid_argument if `n` is outside the range 0 to (`length a` - 1).

```kotlin
val make : int -> float -> t
```

make `n` returns a fresh floatarray of length `n`, initialized with `x`.

**Raises** Invalid_argument if `n < 0` or `n > Sys.maxFloatarray_length`.

```kotlin
val create : int -> t
```

create `n` returns a fresh floatarray of length `n`, with uninitialized data.

**Raises** Invalid_argument if `n < 0` or `n > Sys.maxFloatarray_length`.

```kotlin
val init : int -> f:(int -> float) -> t
```

init `n ~f` returns a fresh floatarray of length `n`, with element number `i` initialized to the result of `f i`. In other terms, init `n ~f` tabulates the results of `f` applied to the integers 0 to `n-1`.

**Raises** Invalid_argument if `n < 0` or `n > Sys.maxFloatarray_length`.

```kotlin
val append : t -> t -> t
```

append `v1 v2` returns a fresh floatarray containing the concatenation of the floatarrays `v1` and `v2`.

**Raises** Invalid_argument if length `v1` + length `v2` > Sys.maxFloatarray_length.

```kotlin
val concat : t list -> t
```

Same as `Float.arrayLabels.append[28.20]`, but concatenates a list of floatarrays.

```kotlin
val sub : t -> pos:int -> len:int -> t
```

sub `a ~pos ~len` returns a fresh floatarray of length `len`, containing the elements number `pos` to `pos + len - 1` of floatarray `a`.

**Raises** Invalid_argument if `pos` and `len` do not designate a valid subarray of `a`; that is, if `pos < 0`, or `len < 0`, or `pos + len > length a`.

```kotlin
val copy : t -> t
```
## 29.13 Module Condition : Condition variables.

Condition variables are useful when several threads wish to access a shared data structure that is protected by a mutex (a mutual exclusion lock).

A condition variable is a communication channel. On the receiver side, one or more threads can indicate that they wish to wait for a certain property to become true. On the sender side, a thread can signal that this property has become true, causing one (or more) waiting threads to be woken up.

For instance, in the implementation of a queue data structure, if a thread that wishes to extract an element finds that the queue is currently empty, then this thread waits for the queue to become nonempty. A thread that inserts an element into the queue signals that the queue has become nonempty. A condition variable is used for this purpose. This communication channel conveys the information that the property "the queue is nonempty" is true, or more accurately, may be true. (We explain below why the receiver of a signal cannot be certain that the property holds.)

To continue the example of the queue, assuming that the queue has a fixed maximum capacity, then a thread that wishes to insert an element may find that the queue is full. Then, this thread must wait for the queue to become not full, and a thread that extracts an element of the queue signals that the queue has become not full. Another condition variable is used for this purpose.

In short, a condition variable `c` is used to convey the information that a certain property `P` about a shared data structure `D`, protected by a mutex `m`, may be true.

Condition variables provide an efficient alternative to busy-waiting. When one wishes to wait for the property `P` to be true, instead of writing a busy-waiting loop:

```c
Mutex.lock m;
while not P do
    Mutex unlock m; Mutex.lock m
done;
<update the data structure>;
Mutex unlock m
```

one uses `Condition.wait` [29.13] in the body of the loop, as follows:

```c
Mutex.lock m;
while not P do
    Condition.wait c m
done;
<update the data structure>;
Mutex unlock m
```

The busy-waiting loop is inefficient because the waiting thread consumes processing time and creates contention of the mutex `m`. Calling `Condition.wait` [29.13] allows the waiting thread to be suspended, so it does not consume any computing resources while waiting.

With a condition variable `c`, exactly one mutex `m` is associated. This association is implicit: the mutex `m` is not explicitly passed as an argument to `Condition.create` [29.13]. It is up to the programmer to know, for each condition variable `c`, which is the associated mutex `m`.
copy a returns a copy of a, that is, a fresh floatarray containing the same elements as a.

val fill : t -> pos:int -> len:int -> float -> unit

fill a ~pos ~len x modifies the floatarray a in place, storing x in elements number pos to pos + len - 1.

**Raises** Invalid_argument if pos and len do not designate a valid subarray of a.

val blit : src:t ->
src_pos:int -> dst:t -> dst_pos:int -> len:int -> unit

blit ~src ~src_pos ~dst ~dst_pos ~len copies len elements from floatarray src,
starting at element number src_pos, to floatarray dst, starting at element number
dst_pos. It works correctly even if src and dst are the same floatarray, and the source
and destination chunks overlap.

**Raises** Invalid_argument if src_pos and len do not designate a valid subarray of src,
or if dst_pos and len do not designate a valid subarray of dst.

val to_list : t -> float list

to_list a returns the list of all the elements of a.

val of_list : float list -> t

of_list l returns a fresh floatarray containing the elements of l.

Raises Invalid_argument if the length of l is greater than
Sys.maxFloatarray_length.

Iterators

val iter : f:(float -> unit) -> t -> unit

iter ~f a applies function f in turn to all the elements of a. It is equivalent to f
a.(0); f a.(1); ...; f a.(length a - 1); ().

val iteri : f:(int -> float -> unit) -> t -> unit

Same as `Float ArrayLabels.iter` [28.20], but the function is applied with the index of the element as first argument, and the element itself as second argument.

val map : f:(float -> float) -> t -> t

map ~f a applies function f to all the elements of a, and builds a floatarray with the
results returned by f.

val map_inplace : f:(float -> float) -> t -> unit

map_inplace f a applies function f to all elements of a, and updates their values in
place.

Since: 5.1
With a mutex `m`, several condition variables can be associated. In the example of the bounded queue, one condition variable is used to indicate that the queue is nonempty, and another condition variable is used to indicate that the queue is not full.

With a condition variable `c`, exactly one logical property `P` should be associated. Examples of such properties include "the queue is nonempty" and "the queue is not full". It is up to the programmer to keep track, for each condition variable, of the corresponding property `P`. A signal is sent on the condition variable `c` as an indication that the property `P` is true, or may be true. On the receiving end, however, a thread that is woken up cannot assume that `P` is true; after a call to `Condition.wait` [29.13] terminates, one must explicitly test whether `P` is true. There are several reasons why this is so. One reason is that, between the moment when the signal is sent and the moment when a waiting thread receives the signal and is scheduled, the property `P` may be falsified by some other thread that is able to acquire the mutex `m` and alter the data structure `D`. Another reason is that spurious wakeups may occur: a waiting thread can be woken up even if no signal was sent.

Here is a complete example, where a mutex protects a sequential unbounded queue, and where a condition variable is used to signal that the queue is nonempty.

```pascal
type 'a safe_queue =
  { queue : 'a Queue.t; mutex : Mutex.t; nonempty : Condition.t }

let create () =
  { queue = Queue.create(); mutex = Mutex.create();
    nonempty = Condition.create() }

let add v q =
  Mutex.lock q.mutex;
  let was_empty = Queue.is_empty q.queue in
  Queue.add v q.queue;
  if was_empty then Condition broadcasts q.nonempty;
  Mutex unlock q.mutex

let take q =
  Mutex.lock q.mutex;
  while Queue.is_empty q.queue do Condition.wait q.nonempty q.mutex done;
  let v = Queue.take q.queue in (* cannot fail since queue is nonempty *)
  Mutex unlock q.mutex;
  v
```

Because the call to `Condition broadcasts` [29.13] takes place inside the critical section, the following property holds whenever the mutex is unlocked: *if the queue is nonempty, then no thread is waiting*, or, in other words, *if some thread is waiting, then the queue must be empty*. This is a desirable property: if a thread that attempts to execute a `take` operation could remain suspended even though the queue is nonempty, that would be a problematic situation, known as a deadlock.

```pascal
type t
```
```kotlin
val mapi : f:(int -> float -> float) -> t -> t
```

Same as `Floatola陣列`. `ArrayLabels.map[28.20]`, but the function is applied to the index of the element as first argument, and the element itself as second argument.

```kotlin
val mapi_inplace : f:(int -> float -> float) -> t -> unit
```

Same as `Floatola陣列`. `map_inplace[28.20]`, but the function is applied to the index of the element as first argument, and the element itself as second argument.

Since: 5.1

```kotlin
val fold_left : f:'acc -> float -> 'acc) -> init:'acc -> t -> 'acc
```

`fold_left ~f x ~init` computes `f (...) (f (f x init.(0)) init.(1)) ...)`
`init.(n-1)`, where n is the length of the `floatarray init`.

```kotlin
val fold_right : f:(float -> 'acc -> 'acc) -> t -> init:'acc -> 'acc
```

`fold_right f a init` computes `f a.(0) (f a.(1) (... (f a.(n-1) init) ...))`, where n is the length of the `floatarray a`.

## Iterators on two arrays

```kotlin
val iter2 : f:(float -> float -> unit) ->
```

`t -> t -> unit`

`Array.iter2 ~f a b` applies function `f` to all the elements of `a` and `b`.

**Raises** `Invalid_argument` if the `floatarrays` are not the same size.

```kotlin
val map2 : f:(float -> float -> float) ->
```

`t -> t -> t`

`map2 ~f a b` applies function `f` to all the elements of `a` and `b`, and builds a `floatarray` with the results returned by `f: [| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|]`.

**Raises** `Invalid_argument` if the `floatarrays` are not the same size.

## Array scanning

```kotlin
val for_all : f:(float -> bool) -> t -> bool
```

`for_all ~f [|a1; ...; an|]` checks if all elements of the `floatarray` satisfy the predicate `f`. That is, it returns `(f a1) && (f a2) && ... && (f an)`.

```kotlin
val exists : f:(float -> bool) -> t -> bool
```

`exists f [|a1; ...; an|]` checks if at least one element of the `floatarray` satisfies the predicate `f`. That is, it returns `(f a1) || (f a2) || ... || (f an)`.
The type of condition variables.

### `val create : unit -> t`

`create()` creates and returns a new condition variable. This condition variable should be associated (in the programmer's mind) with a certain mutex `m` and with a certain property `P` of the data structure that is protected by the mutex `m`.

### `val wait : t -> Mutex.t -> unit`

The call `wait c m` is permitted only if `m` is the mutex associated with the condition variable `c`, and only if `m` is currently locked. This call atomically unlocks the mutex `m` and suspends the current thread on the condition variable `c`. This thread can later be woken up after the condition variable `c` has been signaled via `Condition.signal[29.13]` or `Condition broadcasts[29.13]`; however, it can also be woken up for no reason. The mutex `m` is locked again before `wait` returns. One cannot assume that the property `P` associated with the condition variable `c` holds when `wait` returns; one must explicitly test whether `P` holds after calling `wait`.

### `val signal : t -> unit`

`signal c` wakes up one of the threads waiting on the condition variable `c`, if there is one. If there is none, this call has no effect.

It is recommended to call `signal c` inside a critical section, that is, while the mutex `m` associated with `c` is locked.

### `val broadcast : t -> unit`

`broadcast c` wakes up all threads waiting on the condition variable `c`. If there are none, this call has no effect.

It is recommended to call `broadcast c` inside a critical section, that is, while the mutex `m` associated with `c` is locked.

## 29.14 Module Domain: Domains.

See 'Parallel programming' chapter in the manual.

**Since: 5.0**

**Alert unstable.** The Domain interface may change in incompatible ways in the future.

### `type !'a t`

A domain of type `'a t` runs independently, eventually producing a result of type `'a`, or an exception

### `val spawn : (unit -> 'a) -> 'a t`

`spawn f` creates a new domain that runs in parallel with the current domain.

**Raises Failure** if the program has insufficient resources to create another domain.
`val mem : float -> set:t -> bool`

`mem a ~set` is true if and only if there is an element of `set` that is structurally equal to `a`, i.e. there is an `x` in `set` such that `compare a x = 0`.

`val mem_ieee : float -> set:t -> bool`

Same as `Float ArrayLabels.mem` [28.20], but uses IEEE equality instead of structural equality.

## Array searching

`val find_opt : f:(float -> bool) -> t -> float option`

`val find_index : f:(float -> bool) -> t -> int option`

`find_index ~f a` returns `Some i`, where `i` is the index of the first element of the array `a` that satisfies `f x`, if there is such an element.

It returns `None` if there is no such element.

**Since:** 5.1

`val find_map : f:(float -> 'a option) -> t -> 'a option`

`val find_mapi : f:(int -> float -> 'a option) -> t -> 'a option`

Same as `find_map`, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

**Since:** 5.1

## Sorting

`val sort : cmp:(float -> float -> int) -> t -> unit`

Sort a `floatarray` in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, `compare` [27.2] is a suitable comparison function.

After calling `sort`, the array is sorted in place in increasing order. `sort` is guaranteed to run in constant heap space and (at most) logarithmic stack space.

The current implementation uses `Heap Sort`. It runs in constant stack space.

Specification of the comparison function: Let `a` be the `floatarray` and `cmp` the comparison function. The following must be true for all `x`, `y`, `z` in `a`:

* `cmp x y > 0` if and only if `cmp y x < 0`

* if `cmp x y ≥ 0` and `cmp y z ≥ 0` then `cmp x z ≥ 0`

When `sort` returns, `a` contains the same elements as before, reordered in such a way that for all `i` and `j` valid indices of `a`:
```rust
val join: 'a t -> 'a
```

join d blocks until domain d runs to completion. If d results in a value, then that is returned by join d. If d raises an uncaught exception, then that is re-raised by join d.

```rust
type id = private int
```

Domains have unique integer identifiers

```rust
val get_id: 'a t -> id
```

get_id d returns the identifier of the domain d

```rust
val self: unit -> id
```

self () is the identifier of the currently running domain

```rust
val before_first spawn: (unit -> unit) -> unit
```

before_first spawn f registers f to be called before the first domain is spawned by the program. The functions registered with before_first spawn are called on the main (initial) domain. The functions registered with before_first spawn are called in 'first in, first out' order: the oldest function added with before_first spawn is called first.

**Raises** Invalid_argument if the program has already spawned a domain.

```rust
val at_exit: (unit -> unit) -> unit
```

at_exit f registers f to be called when the current domain exits. Note that at_exit callbacks are domain-local and only apply to the calling domain. The registered functions are called in 'last in, first out' order: the function most recently added with at_exit is called first. An example:

```rust
let temp_file_key = Domain.DLS.new_key (fun _ ->
    let tmp = snd (Filename.open_temp_file "" "") in
    Domain.at_exit (fun () -> close_out_noerr tmp);
    tmp)
```

The snippet above creates a key that when retrieved for the first time will open a temporary file and register an at_exit callback to close it, thus guaranteeing the descriptor is not leaked in case the current domain exits.

```rust
val cpu_relax: unit -> unit
```

If busy-waiting, calling cpu_relax () between iterations will improve performance on some CPU architectures

```rust
val is_main_domain: unit -> bool
```

is_main_domain () returns true if called from the initial domain.

```rust
val recommended_domain_count: unit -> int
```
* `cmp a.(i) a.(j) ≥ 0` if and only if `i ≥ j`

`val stable_sort : cmp:(float -> float -> int) -> t -> unit`

Same as `Float.arrayLabels.sort[28.20]`, but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.

The current implementation uses Merge Sort. It uses a temporary floatarray of length `n/2`, where `n` is the length of the floatarray. It is usually faster than the current implementation of `Float.arrayLabels.sort[28.20]`.

`val fast_sort : cmp:(float -> float -> int) -> t -> unit`

Same as `Float.arrayLabels.sort[28.20]` or `Float.arrayLabels.stable_sort[28.20]`, whichever is faster on typical input.

## Float arrays and Sequences

`val to_seq : t -> float Seq.t`

Iterate on the floatarray, in increasing order. Modifications of the floatarray during iteration will be reflected in the sequence.

`val to_seqi : t -> (int * float) Seq.t`

Iterate on the floatarray, in increasing order, yielding indices along elements. Modifications of the floatarray during iteration will be reflected in the sequence.

`val of_seq : float Seq.t -> t`

Create an array from the generator.

`val map_to_array : f:(float -> 'a) -> t -> 'a array`

`map_to_array ~f a` applies function `f` to all the elements of `a`, and builds an array with the results returned by `f: [| f a.(0); f a.(1); ...; f a.(length a - 1) |]`.

`val map_from_array : f:'a -> float -> 'a array -> t`

`map_from_array ~f a` applies function `f` to all the elements of `a`, and builds a floatarray with the results returned by `f`.

## Arrays and concurrency safety

Care must be taken when concurrently accessing float arrays from multiple domains: accessing an array will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.
The recommended maximum number of domains which should be running simultaneously (including domains already running).

The value returned is at least 1.

```hkl
val self_index : unit -> int
```

The index of the current domain. It is an integer unique among currently-running domains, in the interval 0; N-1 where N is the peak number of domains running simultaneously so far.

The index of a terminated domain may be reused for a new domain. Use (`Domain.self ()` :> `int`) instead for an identifier unique among all domains ever created by the program.

**Since: 5.3**

```hkl
module DLS :
```

```hkl
sig
```

Domain-local Storage

```hkl
type 'a key
```

Type of a DLS key

```hkl
val new_key : ?split_from_parent: ('a -> 'a) -> (unit -> 'a) -> 'a key
```

`new_key` f returns a new key bound to initialiser f for accessing domain-local variables. If `split_from_parent` is not provided, the value for a new domain will be computed on-demand by the new domain: the first `get` call will call the initializer f and store that value.

**Warning.** f may be called several times if another call to get occurs during initialization on the same domain. Only the 'first' value computed will be used, the other now-useless values will be discarded. Your initialization function should support this situation, or contain logic to detect this case and fail.

If `split_from_parent` is provided, spawning a domain will derive the child value (for this key) from the parent value. This computation happens in the parent domain and it always happens, regardless of whether the child domain will use it. If the splitting function is expensive or requires child-side computation, consider using `'a Lazy.t' key`:

```hkl
let init () = ...
```

```hkl
let split_from_parent parent_value =
  ... parent-side computation ...;

lazy (
  ... child-side computation ...
)
```

```hkl
let key = Domain.DLS.new_key ~split_from_parent init
```

```hkl
let get () = Lazy.force (Domain.DLS.get key)
```
Atomicity

Every float array operation that accesses more than one array element is not atomic. This
includes iteration, scanning, sorting, splitting and combining arrays.

For example, consider the following program:

let size = 100_000_000
let a = Float.arrayLabels.make size 1.
let update a f () =
  Float.arrayLabels.iteri ~f: (fun i x -> Float.array.set a i (f x)) a
let d1 = Domain spawn (update a (fun x -> x +. 1.))
let d2 = Domain spawn (update a (fun x -> 2. *. x +. 1.))
let () = Domain.join d1; Domain.join d2

After executing this code, each field of the float array a is either 2., 3., 4. or 5.. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t[28.36]).

Data races

If two domains only access disjoint parts of the array, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same array element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the array elements.

Indeed, in the presence of data races, programs will not crash but the observed behaviour
may not be equivalent to any sequential interleaving of operations from different domains.
Nevertheless, even in the presence of data races, a read operation will return the value of some
prior write to that location with a few exceptions.

Tearing

Float arrays have two supplementary caveats in the presence of data races.

First, the blit operation might copy an array byte-by-byte. Data races between such a blit
operation and another operation might produce surprising values due to tearing: partial writes
interleaved with other operations can create float values that would not exist with a sequential
execution.

For instance, at the end of

let zeros = Float.array.make size 0.
let max_floats = Float.array.make size Float.max_float
In this case a part of the computation happens on the child domain; in particular, it can access `parent_value` concurrently with the parent domain, which may require explicit synchronization to avoid data races.

val get : 'a key -> 'a

`get` k returns v if a value v is associated to the key k on the calling domain's domain-local state. Sets k's value with its initialiser and returns it otherwise.

val set : 'a key -> 'a -> unit

`set` k v updates the calling domain's domain-local state to associate the key k with value v. It overwrites any previous values associated to k, which cannot be restored later.

end

## 29.15 Module Digest : Message digest.

This module provides functions to compute 'digests', also known as 'hashes', of arbitrary-length strings or files. The supported hashing algorithms are `BLAKE2` and `MD5`.

### Basic functions

The functions in this section use the `MD5` hash function to produce 128-bit digests (16 bytes). `MD5` is not cryptographically secure. Hence, these functions should not be used for security-sensitive applications. The `BLAKE2` functions below are cryptographically secure.

type t = string

The type of digests: 16-byte strings.

val compare : t -> t -> int

The comparison function for 16-byte digests, with the same specification as `compare[28.2]` and the implementation shared with `String compare[29.58]`. Along with the type `t`, this function `compare` allows the module `Digest` to be passed as argument to the functors `Set.Make[29.54]` and `Map.Make[29.35]`.

Since: 4.00

val equal : t -> t -> bool

The equal function for 16-byte digests.

Since: 4.03

val string : string -> t

Return the digest of the given string.
```kotlin
let res = Floatola copies zeros
let d1 = Domain spawn (fun () -> Floatola blit zeros 0 res 0 size)
let d2 = Domain spawn (fun () -> Floatola blit max_floats 0 res 0 size)
let () = Domain.join d1; Domain.join d2
```

the `res` float array might contain values that are neither 0. nor `max_float`.

Second, on 32-bit architectures, getting or setting a field involves two separate memory accesses. In the presence of data races, the user may observe tearing on any operation.

end

Float arrays with packed representation (labeled functions).

## 28.21 Module Format : Pretty-printing.

If you are new to this module, see the examples[28.44] below.

This module implements a pretty-printing facility to format values within 'pretty-printing boxes'[28.21] and 'semantic tags'[28.21] combined with a set of printf-like functions[28.21]. The pretty-printer splits lines at specified break hints[28.21], and indents lines according to the box structure. Similarly, semantic tags[28.21] can be used to decouple text presentation from its contents.

This pretty-printing facility is implemented as an overlay on top of abstract formatters[28.21] which provide basic output functions. Some formatters are predefined, notably:

* `Format.stdFormatter[28.21]` outputs to stdout[27.2]

* `Format.errFormatter[28.21]` outputs to stderr[27.2]

Most functions in the `Format[28.21]` module come in two variants: a short version that operates on the current domain's standard formatter as obtained using `Format.get_stdFormatter[28.21]` and the generic version prefixed by `pp_` that takes a formatter as its first argument. For the version that operates on the current domain's standard formatter, the call to `Format.get_stdFormatter[28.21]` is delayed until the last argument is received.

More formatters can be created with `Format formatter of out_channel[28.21]`, `Format formatter of buffer[28.21]`, `Format formatter of symbolic output buffer[28.21]` or using custom formatters[28.21].

**Warning:** Since formatters[28.21] contain mutable state, it is not thread-safe to use the same formatter on multiple domains in parallel without synchronization.

If multiple domains write to the same output channel using the predefined formatters (as obtained by `Format.get_stdFormatter[28.21]` or `Format.get_errFormatter[28.21]`), the output from the domains will be interleaved with each other at points where the formatters are flushed, such as with `Format.print_flush[28.21]`. This synchronization is not performed by formatters obtained from `Format formatter of out_channel[28.21]` (on the standard out channels or others).
val bytes : bytes -> t

Return the digest of the given byte sequence.

Since: 4.02

val substring : string -> int -> int -> t

Digest.substring s ofs len returns the digest of the substring of s starting at index ofs
and containing len characters.

val subbytes : bytes -> int -> int -> t

Digest.subbytes s ofs len returns the digest of the subsequence of s starting at index
ofs and containing len bytes.

Since: 4.02

val channel : in_channel -> int -> t

If len is nonnegative, Digest-channel ic len reads len characters from channel ic and
returns their digest, or raises End_of_file if end-of-file is reached before len characters are
read. If len is negative, Digest-channel ic len reads all characters from ic until
end-of-file is reached and return their digest.

val file : string -> t

Return the digest of the file whose name is given.

val output : out_channel -> t -> unit

Write a digest on the given output channel.

val input : in_channel -> t

Read a digest from the given input channel.

val to_hex : t -> string

Return the printable hexadecimal representation of the given digest.

Raises Invalid_argument if the argument is not exactly 16 bytes.

val of_hex : string -> t

Convert a hexadecimal representation back into the corresponding digest.

Since: 5.2

Raises Invalid_argument if the argument is not exactly 32 hexadecimal characters.

val from_hex : string -> t

Same function as Digest.of_hex[29.15].

Since: 4.00
## Introduction

You may consider this module as providing an extension to the `printf` facility to provide automatic line splitting. The addition of pretty-printing annotations to your regular `printf` format strings gives you fancy indentation and line breaks. Pretty-printing annotations are described below in the documentation of the function `Format.fprintf[28.21]`.

You may also use the explicit pretty-printing box management and printing functions provided by this module. This style is more basic but more verbose than the concise `fprintf` format strings.

For instance, the sequence `open_box 0; print_string "x ="; print_space (); print_int 1; close_box (); print_newline ()` that prints `x = 1` within a pretty-printing box, can be abbreviated as `printf "@[%s@ %i@]@." "x =" 1`, or even shorter `printf "@[x =@ %i@]@." 1`.

Rule of thumb for casual users of this library:

* use simple pretty-printing boxes (as obtained by `open_box 0`);

* use simple break hints as obtained by `print_cut ()` that outputs a simple break hint, or by `print_space ()` that outputs a space indicating a break hint;

* once a pretty-printing box is open, display its material with basic printing functions (e. g. `print_int` and `print_string`);

* when the material for a pretty-printing box has been printed, call `close_box ()` to close the box;

* at the end of pretty-printing, flush the pretty-printer to display all the remaining material, e.g. evaluate `print_newline ()`.

The behavior of pretty-printing commands is unspecified if there is no open pretty-printing box. Each box opened by one of the `open_` functions below must be closed using `close_box` for proper formatting. Otherwise, some of the material printed in the boxes may not be output, or may be formatted incorrectly.

In case of interactive use, each phrase is executed in the initial state of the standard pretty-printer: after each phrase execution, the interactive system closes all open pretty-printing boxes, flushes all pending text, and resets the standard pretty-printer.

Warning: mixing calls to pretty-printing functions of this module with calls to `Stdlib[27.2]` low level output functions is error prone.

The pretty-printing functions output material that is delayed in the pretty-printer queue and stacks in order to compute proper line splitting. In contrast, basic I/O output functions write directly in their output device. As a consequence, the output of a basic I/O function may appear before the output of a pretty-printing function that has been called before. For instance, `Stdlib.print_string "<"; Format.print_string "PRETTY"; Stdlib.print_string ">"; Format.print_string "TEXT";` leads to output `<>PRETTYTEXT`.

## Formatters

### type formatter

Abstract data corresponding to a pretty-printer (also called a formatter) and all its machinery. See also [28.21].
Generic interface

module type S =
sig

type t = string

The type of digests.

val hash_length : int

The length of digests, in bytes.

val compare : t -> t -> int

Compare two digests, with the same specification as compare[28.2].

val equal : t -> t -> bool

Test two digests for equality.

val string : string -> t

Return the digest of the given string.

val bytes : bytes -> t

Return the digest of the given byte sequence.

val substring : string -> int -> int -> t

substring s ofs len returns the digest of the substring of s starting at index ofs and containing len characters.

val subbytes : bytes -> int -> int -> t

subbytes s ofs len returns the digest of the subsequence of s starting at index ofs and containing len bytes.

val channel : in_channel -> int -> t

Read characters from the channel and return their digest. See Digest-channel[29.15]
for the full specification.

val file : string -> t

Return the digest of the file whose name is given.

val output : out_channel -> t -> unit

Write a digest on the given output channel.

val input : in_channel -> t
## Pretty-printing boxes

The pretty-printing engine uses the concepts of pretty-printing box and break hint to drive indentation and line splitting behavior of the pretty-printer.

Each different pretty-printing box kind introduces a specific line splitting policy:

* within an *horizontal* box, break hints never split the line (but the line may be split in a box nested deeper),

* within a *vertical* box, break hints always split the line,

* within an *horizontal/vertical* box, if the box fits on the current line then break hints never split the line, otherwise break hint always split the line,

* within a *compacting* box, a break hint never splits the line, unless there is no more room on the current line.

Note that line splitting policy is box specific: the policy of a box does not rule the policy of inner boxes. For instance, if a vertical box is nested in an horizontal box, all break hints within the vertical box will split the line.

Moreover, opening a box after the maximum indentation limit [28.21] splits the line whether or not the box would end up fitting on the line.

```rust
val pp_open_box: formatter -> int -> unit
```

```rust
val open_box: int -> unit
```

`pp_open_box` `ppf` `d` opens a new compacting pretty-printing box with offset `d` in the formatter `ppf`.

Within this box, the pretty-printer prints as much as possible material on every line.

A break hint splits the line if there is no more room on the line to print the remainder of the box.

Within this box, the pretty-printer emphasizes the box structure: if a structural box does not fit fully on a simple line, a break hint also splits the line if the splitting “moves to the left” (i.e. the new line gets an indentation smaller than the one of the current line).

This box is the general purpose pretty-printing box.

If the pretty-printer splits the line in the box, offset `d` is added to the current indentation.

```rust
val pp_close_box: formatter -> unit -> unit
```

```rust
val close_box: unit -> unit
```

Closes the most recently open pretty-printing box.

```rust
val pp_open_hbox: formatter -> unit -> unit
```

```rust
val open_hbox: unit -> unit
```

`pp_open_hbox` `ppf ()` opens a new 'horizontal' pretty-printing box.

This box prints material on a single line.

Break hints in a horizontal box never split the line. (Line splitting may still occur inside boxes nested deeper).
Read a digest from the given input channel.

val to_hex : t -> string

Return the printable hexadecimal representation of the given digest.

**Raises** Invalid_argument if the length of the argument is not hash_length,

val of_hex : string -> t

Convert a hexadecimal representation back into the corresponding digest.

**Raises** Invalid_argument if the length of the argument is not 2 * hash_length, or if
the arguments contains non-hexadecimal characters.

end

The signature for a hash function that produces digests of length `hash_length` from
character strings, byte arrays, and files.

Since: 5.2

Specific hash functions

module BLAKE128 :

S

BLAKE128 is the BLAKE2b hash function producing 128-bit (16-byte) digests. It is
cryptographically secure. However, the small size of the digests enables brute-force attacks in
2^{64} attempts.

Since: 5.2

module BLAKE256 :

S

BLAKE256 is the BLAKE2b hash function producing 256-bit (32-byte) digests. It is
cryptographically secure, and the digests are large enough to thwart brute-force attacks.

Since: 5.2

module BLAKE512 :

S

BLAKE512 is the BLAKE2b hash function producing 512-bit (64-byte) digests. It is
cryptographically secure, and the digests are large enough to thwart brute-force attacks.

Since: 5.2

module MD5 :

S

MD5 is the MD5 hash function. It produces 128-bit (16-byte) digests and is not
cryptographically secure at all. It should be used only for compatibility with earlier designs
that mandate the use of MD5.

Since: 5.2
val pp_open_vbox : formatter -> int -> unit

val open_vbox : int -> unit

pp_open_vbox ppf d opens a new 'vertical' pretty-printing box with offset d.

This box prints material on as many lines as break hints in the box.

Every break hint in a vertical box splits the line.

If the pretty-printer splits the line in the box, d is added to the current indentation.

val pp_open_hvbox : formatter -> int -> unit

val open_hvbox : int -> unit

pp_open_hvbox ppf d opens a new 'horizontal/vertical' pretty-printing box with offset d.

This box behaves as an horizontal box if it fits on a single line, otherwise it behaves as a
vertical box.

If the pretty-printer splits the line in the box, d is added to the current indentation.

val pp_open_hovbox : formatter -> int -> unit

val open_hovbox : int -> unit

pp_open_hovbox ppf d opens a new 'horizontal-or-vertical' pretty-printing box with offset d.

This box prints material as much as possible on every line.

A break hint splits the line if there is no more room on the line to print the remainder of the box.

If the pretty-printer splits the line in the box, d is added to the current indentation.

## Formatting functions

val pp_print_string : formatter -> string -> unit

val print_string : string -> unit

pp_print_string ppf s prints s in the current pretty-printing box.

val pp_print_bytes : formatter -> bytes -> unit

val print_bytes : bytes -> unit

pp_print_bytes ppf b prints b in the current pretty-printing box.

Since: 4.13

val pp_print_as : formatter -> int -> string -> unit

val print_as : int -> string -> unit

pp_print_as ppf len s prints s in the current pretty-printing box. The pretty-printer formats s as if it were of length len.

val pp_print_int : formatter -> int -> unit

val print_int : int -> unit
## 29.16 Module Dynarray : Dynamic arrays.

The Array[29.2] module provide arrays of fixed length. Dynarray[29.16] provides arrays whose length can change over time, by adding or removing elements at the end of the array.

This is typically used to accumulate elements whose number is not known in advance or changes during computation, while also providing fast access to elements at arbitrary indices.

```python
let dynarray_of_list li =
    let arr = Dynarray.create () in
    List.iter (fun v -> Dynarray.add_last arr v) li;
    arr
```

The Buffer[29.7] module provides similar features, but it is specialized for accumulating characters into a dynamically-resized string.

The Stack[29.56] module provides a last-in first-out data structure that can be easily implemented on top of dynamic arrays.

**Since: 5.2**

**Alert unsynchronized_access.** Unsynchronized accesses to dynamic arrays are a programming error.

### Unsynchronized accesses

Concurrent accesses to dynamic arrays must be synchronized (for instance with a Mutex.t[29.38]). Unsynchronized accesses to a dynamic array are a programming error that may lead to an invalid dynamic array state, on which some operations would fail with an Invalid_argument exception.

### Dynamic arrays

#### type !'a t

A dynamic array containing values of type 'a.

A dynamic array `a` provides constant-time `get` and `set` operations on indices between 0 and `Dynarray.length` - 1 included. Its `Dynarray.length`[29.16] may change over time by adding or removing elements to the end of the array.

We say that an index into a dynarray `a` is valid if it is in 0..`length` - 1 and invalid otherwise.

#### val create : unit -> 'a t

`create ()` is a new, empty array.

#### val make : int -> 'a -> 'a t

`make n x` is a new array of length `n`, filled with `x`.

**Raises** Invalid_argument if `n` < 0 or `n` > Sys.max_array_length.

#### val init : int -> (int -> 'a) -> 'a t
Print an integer in the current pretty-printing box.

```kotlin
val pp_print_float : formatter -> float -> unit
```

```kotlin
val print_float : float -> unit
```

Print a floating point number in the current pretty-printing box.

```kotlin
val pp_print_char : formatter -> char -> unit
```

```kotlin
val print_char : char -> unit
```

Print a character in the current pretty-printing box.

```kotlin
val pp_print_bool : formatter -> bool -> unit
```

```kotlin
val print_bool : bool -> unit
```

Print a boolean in the current pretty-printing box.

## Break hints

A 'break hint' tells the pretty-printer to output some space or split the line whichever way is more appropriate to the current pretty-printing box splitting rules.

Break hints are used to separate printing items and are mandatory to let the pretty-printer correctly split lines and indent items.

Simple break hints are:

* the 'space': output a space or split the line if appropriate,

* the 'cut': split the line if appropriate.

Note: the notions of space and line splitting are abstract for the pretty-printing engine, since those notions can be completely redefined by the programmer. However, in the pretty-printer default setting, "output a space" simply means printing a space character (ASCII code 32) and "split the line" means printing a newline character (ASCII code 10).

```kotlin
val pp_print_space : formatter -> unit -> unit
```

```kotlin
val print_space : unit -> unit
```

`pp_print_space ppf ()` emits a 'space' break hint: the pretty-printer may split the line at this point, otherwise it prints one space.

`pp_print_space ppf ()` is equivalent to `pp_print_break ppf 1 0`.

```kotlin
val pp_print_cut : formatter -> unit -> unit
```

```kotlin
val print_cut : unit -> unit
```

`pp_print_cut ppf ()` emits a 'cut' break hint: the pretty-printer may split the line at this point, otherwise it prints nothing.

`pp_print_cut ppf ()` is equivalent to `pp_print_break ppf 0 0`.

```kotlin
val pp_print_break : formatter -> int -> int -> unit
```

```kotlin
val print_break : int -> int -> unit
```
`init n f` is a new array `a` of length `n`, such that `get a i` is `f i`. In other words, the elements of `a` are `f 0`, then `f 1`, then `f 2...` and `f (n - 1)` last, evaluated in that order.

This is similar to `Array.init[29.2]`.

**Raises** `Invalid_argument` if `n < 0` or `n > Sys.max_array_length`.

`val get : 'a t -> int -> 'a`

`get a i` is the `i-th` element of `a`, starting with index `0`.

**Raises** `Invalid_argument` if the index is invalid.

`val set : 'a t -> int -> 'a -> unit`

`set a i x` sets the `i-th` element of `a` to be `x`.

`i` must be a valid index. `set` does not add new elements to the array – see `Dynarray.add_last[29.16]` to add an element.

**Raises** `Invalid_argument` if the index is invalid.

`val length : 'a t -> int`

`length a` is the number of elements in the array.

`val is_empty : 'a t -> bool`

`is_empty a` is `true` if `a` is empty, that is, if `length a = 0`.

`val get_last : 'a t -> 'a`

`get_last a` is the element of `a` at index `length a - 1`.

**Raises** `Invalid_argument` if `a` is empty.

`val find_last : 'a t -> 'a option`

`find_last a` is `None` if `a` is empty and `Some (get_last a)` otherwise.

`val copy : 'a t -> 'a t`

`copy a` is a shallow copy of `a`, a new array containing the same elements as `a`.

## Adding elements

Note: all operations adding elements raise `Invalid_argument` if the length needs to grow beyond `Sys.max_array_length[29.60]`.

`val add_last : 'a t -> 'a -> unit`

`add_last a x` adds the element `x` at the end of the array `a`.

`val append_array : 'a t -> 'a array -> unit`
`pp_print_break` `ppf` `nspaces` `offset` emits a 'full' break hint: the pretty-printer may split the line at this point, otherwise it prints `nspaces` spaces.

If the pretty-printer splits the line, `offset` is added to the current indentation.

`val pp_print_custom_break` :

`formatter ->`

`fits: string * int * string -> breaks: string * int * string -> unit`

`pp_print_custom_break` `ppf` `~fits:(s1, n, s2) ~breaks:(s3, m, s4)` emits a custom break hint: the pretty-printer may split the line at this point.

If it does not split the line, then the `s1` is emitted, then `n` spaces, then `s2`.

If it splits the line, then it emits the `s3` string, then an indent (according to the box rules), then an offset of `m` spaces, then the `s4` string.

While `n` and `m` are handled by `formatter_out_functions.out indent`, the strings will be handled by `formatter_out_functions.out_string`. This allows for a custom formatter that handles indentation distinctly, for example, outputs `<br/>` tags or `&nbsp;` entities.

The custom break is useful if you want to change which visible (non-whitespace) characters are printed in case of break or no break. For example, when printing a list `[a; b; c]`, you might want to add a trailing semicolon when it is printed vertically:

```
[
  a;
b;
c;
]
```

You can do this as follows:

```perl
printf "@[<v 0>[@;0 2>[@<v 0>a;@,b;@,c@]%t]@]\n"
    (pp_print_custom_break ~fits:("", 0, "") ~breaks:(";", 0, ""))
```

Since: 4.08

`val pp_force_newline` : `formatter -> unit -> unit`

`val force_newline` : `unit -> unit`

Force a new line in the current pretty-printing box.

The pretty-printer must split the line at this point,

Not the normal way of pretty-printing, since imperative line splitting may interfere with current line counters and box size calculation. Using break hints within an enclosing vertical box is a better alternative.

`val pp_print_if_newline` : `formatter -> unit -> unit`

`val print_if_newline` : `unit -> unit`
`append_array` a b adds all elements of b at the end of a, in the order they appear in b.

For example:

```h
let a = Dynarray.of_list [1;2] in
Dynarray.append_array a [|3; 4|];
assert (Dynarray.to_list a = [1; 2; 3; 4])
```

`val append_list : 'a t -> 'a list -> unit`

Like `Dynarray.append_array[29.16]` but with a list.

`val append : 'a t -> 'a t -> unit`

`append` a b is like `append_array` a b, but b is itself a dynamic array instead of a fixed-size array.

Warning: `append` a a is a programming error because it iterates on a and adds elements to it at the same time – see the Iteration [29.45] section below. It fails with `Invalid_argument`. If you really want to append a copy of a to itself, you can use `Dynarray.append_array` a (Dynarray.to_array a) which copies a into a temporary array.

`val append_seq : 'a t -> 'a Seq.t -> unit`

Like `Dynarray.append_array[29.16]` but with a sequence.

Warning: `append_seq` a (to_seq_reentrant a) simultaneously traverses a and adds element to it; the ordering of those operations is unspecified, and may result in an infinite loop – the new elements may in turn be produced by to_seq_reentrant a and get added again and again.

`val append_iter : 'a t -> ('a -> unit) -> 'x -> unit) -> 'x -> unit`

`append_iter` a iter x adds each element of x to the end of a. This is iter (add_last a) x.

For example, `append_iter` a List.iter [1;2;3] would add elements 1, 2, and then 3 at the end of a. `append_iter` a Queue.iter q adds elements from the queue q.

`val blit :`

```
src:'a t ->
src_pos:int -> dst:'a t -> dst_pos:int -> len:int -> unit
```

`blit ~src ~src_pos ~dst ~dst_pos ~len` copies `len` elements from a source dynarray `src`, starting at index `src_pos`, to a destination dynarray `dst`, starting at index `dst_pos`. It works correctly even if `src` and `dst` are the same array, and the source and destination chunks overlap.

Unlike `Array.blit[29.2]`, `Dynarray.blit[29.16]` can extend the destination array with new elements: it is valid to call `blit` even when `dst_pos + len` is larger than `length dst`. The only requirement is that `dst_pos` must be at most `length dst` (included), so that there is no gap between the current elements and the blit region.
Execute the next formatting command if the preceding line has just been split. Otherwise,
ignore the next formatting command.

## Pretty-printing termination

```hkl
val pp_print_flush : formatter -> unit -> unit
```

```hkl
val print_flush : unit -> unit
```

End of pretty-printing: resets the pretty-printer to initial state.

All open pretty-printing boxes are closed, all pending text is printed. In addition, the pretty-printer low level output device is flushed to ensure that all pending text is really displayed.

Note: never use `print_flush` in the normal course of a pretty-printing routine, since the pretty-printer uses a complex buffering machinery to properly indent the output; manually flushing those buffers at random would conflict with the pretty-printer strategy and result to poor rendering.

Only consider using `print_flush` when displaying all pending material is mandatory (for instance in case of interactive use when you want the user to read some text) and when resetting the pretty-printer state will not disturb further pretty-printing.

Warning: If the output device of the pretty-printer is an output channel, repeated calls to `print_flush` means repeated calls to `flush` [27.2] to flush the out channel; these explicit flush calls could foil the buffering strategy of output channels and could dramatically impact efficiency.

```hkl
val pp_print_newline : formatter -> unit -> unit
```

```hkl
val print_newline : unit -> unit
```

End of pretty-printing: resets the pretty-printer to initial state.

All open pretty-printing boxes are closed, all pending text is printed.

Equivalent to `Format.print_flush[28.21]` with a new line emitted on the pretty-printer low-level output device immediately before the device is flushed. See corresponding words of caution for `Format.print_flush[28.21]`.

Note: this is not the normal way to output a new line; the preferred method is using break hints within a vertical pretty-printing box.

## Margin

```hkl
val pp_set_margin : formatter -> int -> unit
```

```hkl
val setMargin : int -> unit
```

`pp_setmargin ppfd` sets the right margin to `d` (in characters): the pretty-printer splits lines that overflow the right margin according to the break hints given. Setting the margin to `d` means that the formatting engine aims at printing at most `d-1` characters per line. Nothing happens if `d` is smaller than 2. If `d` is too large, the right margin is set to the maximum
**Raises** `Invalid_argument` if `src_pos` and `len` do not designate a valid subarray of `src`, or if `dst_pos` is strictly below 0 or strictly above length `dst`.

## Removing elements

`val pop_last_opt: 'a t -> 'a option`

`pop_last_opt` a removes and returns the last element of a, or `None` if the array is empty.

`val pop_last: 'a t -> 'a`

`pop_last` a removes and returns the last element of a.

**Raises** `Not_found` on an empty array.

`val remove_last: 'a t -> unit`

`remove_last` a removes the last element of a, if any. It does nothing if a is empty.

`val truncate: 'a t -> int -> unit`

`truncate` n truncates a to have at most n elements.

It removes elements whose index is greater or equal to n. It does nothing if `n >= length a`.

`truncate` a n is equivalent to:

```
if n < 0 then invalid_argument "...";
while length a > n do
    remove_last a
done
```

**Raises** `Invalid_argument` if `n < 0`.

`val clear: 'a t -> unit`

`clear` a is `truncate` a 0, it removes all the elements of a.

## Iteration

The iteration functions traverse the elements of a dynamic array. Traversals of a are computed in increasing index order: from the element of index 0 to the element of index `length a - 1`.

It is a programming error to change the length of an array (by adding or removing elements) during an iteration on the array. Any iteration function will fail with `Invalid_argument` if it detects such a length change.

`val iter: ('a -> unit) -> 'a t -> unit`

`iter` f a calls f on each element of a.

`val iteri: (int -> 'a -> unit) -> 'a t -> unit`

`iteri` f a calls f i x for each x at index i in a.
admissible value (which is greater than 10 ^ 9). If `d` is less than the current maximum indentation limit, the maximum indentation limit is decreased while trying to preserve a minimal ratio `max_indent/margin>=50%` and if possible the current difference `margin - max_indent`.

See also `Format.pp_set_geometry[28.21]`.

```perl
val pp_get_margin : formatter -> unit -> int
```

```perl
val getMargin : unit -> int
```

Returns the position of the right margin.

## Maximum indentation limit

```perl
val pp_set_maxident : formatter -> int -> unit
```

```perl
val set_maxindent : int -> unit
```

`pp_set_maxident` `ppf d` sets the maximum indentation limit of lines to `d` (in characters): once this limit is reached, new pretty-printing boxes are rejected to the left, unless the enclosing box fully fits on the current line. As an illustration,

```perl
setMargin 10; set_maxindent 5; printf "^[123456^[7@]89A@]@."
```

yields

```
123456
789A
```

because the nested box `"^[7@]"` is opened after the maximum indentation limit (`7>5`) and its parent box does not fit on the current line. Either decreasing the length of the parent box to make it fit on a line:

```perl
printf "^[123456^[7@]89@]@."
```

or opening an intermediary box before the maximum indentation limit which fits on the current line

```perl
printf "^[123@]456@^[7@]89@]A@]@."
```

avoids the rejection to the left of the inner boxes and print respectively `"123456789"` and `"123456789A"`. Note also that vertical boxes never fit on a line whereas horizontal boxes always fully fit on the current line. Opening a box may split a line whereas the contents may have fit. If this behavior is problematic, it can be curtailed by setting the maximum indentation limit to `margin - 1`. Note that setting the maximum indentation limit to `margin` is invalid.

Nothing happens if `d` is smaller than 2.

If `d` is too large, the limit is set to the maximum admissible value (which is greater than 10 ^ 9).

If `d` is greater or equal than the current margin, it is ignored, and the current maximum indentation limit is kept.
```hkl
val map : ('a -> 'b) -> 'a t -> 'b t
```

map f a is a new array of elements of the form f x for each element x of a.

For example, if the elements of a are x0, x1, x2, then the elements of b are f x0, f x1, f x2.

```hkl
val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t
```

mapi f a is a new array of elements of the form f i x for each element x of a at index i.

For example, if the elements of a are x0, x1, x2, then the elements of b are f 0 x0, f 1 x1, f 2 x2.

```hkl
val fold_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc
```

fold_left f acc a folds f over a in order, starting with accumulator acc.

For example, if the elements of a are x0, x1, then fold f acc a is

```hkl
let acc = f acc x0 in
let acc = f acc x1 in
acc
```

```hkl
val fold_right : ('a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc
```

fold_right f a acc computes f x0 (f x1 (... (f xn acc) ...)) where x0, x1, ..., xn are the elements of a.

```hkl
val filter : ('a -> bool) -> 'a t -> 'a t
```

filter f a is a new array of all the elements of a that satisfy f. In other words, it is an array b such that, for each element x in a in order, x is added to b if f x is true.

For example, filter (fun x -> x >= 0) a is a new array of all non-negative elements of a, in order.

```hkl
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
```

filter_map f a is a new array of elements y such that f x is Some y for an element x of a.

In other words, it is an array b such that, for each element x of a in order:

* if f x = Some y, then y is added to b,

* if f x = None, then no element is added to b.

For example, filter_map int_of_string_opt inputs returns a new array of integers read from the strings in inputs, ignoring strings that cannot be converted to integers.

## Dynarray scanning

```hkl
val exists : ('a -> bool) -> 'a t -> bool
```

exists f a is true if some element of a satisfies f.

For example, if the elements of a are x0, x1, x2, then exists f a is f x0 || f x1 || f x2.
See also `Format.pp_set_geometry` [28.21].

```perl
val pp_get_max ident : formatter -> unit -> int
```

```perl
val get_max ident : unit -> int
```

Return the maximum indentation limit (in characters).

## Geometry

Geometric functions can be used to manipulate simultaneously the coupled variables, margin and maximum indentation limit.

```perl
type geometry =
{
    max ident : int ;
    margin : int ;
}
```

**Since:** 4.08

```perl
val check_geometry : geometry -> bool
```

Check if the formatter geometry is valid: `1 < max ident < margin`

**Since:** 4.08

```perl
val pp_set_geometry : formatter -> max ident:int -> margin:int -> unit
```

```perl
val set_geometry : max ident:int -> margin:int -> unit
```

```perl
val pp_safe_set_geometry : formatter -> max ident:int -> margin:int -> unit
```

```perl
val safe_set_geometry : max ident:int -> margin:int -> unit
```

`pp_set_geometry ppf ~max ident ~margin` sets both the margin and maximum indentation limit for `ppf`.

When `1 < max ident < margin`, `pp_set_geometry ppf ~max indent ~margin` is equivalent to `pp_setmargin ppf margin`; `pp_set_max indent ppf max indent`; and avoids the subtly incorrect `pp_set_max indent ppf max indent`; `pp_setmargin ppf margin`;

Outside of this domain, `pp_set_geometry` raises an invalid argument exception whereas `pp_safe_set_geometry` does nothing.

**Since:** 4.08

```perl
val pp_update_geometry : formatter -> (geometry -> geometry) -> unit
```

`pp_update_geometry ppf (fun geo -> { geo with ... })` lets you update a formatter's geometry in a way that is robust to extension of the `geometry` record with new fields.

Raises an invalid argument exception if the returned geometry does not satisfy `Format.check_geometry` [28.21].

**Since:** 4.11
val for_all : ('a -> bool) -> 'a t -> bool

for_all f a is true if all elements of a satisfy f. This includes the case where a is empty.
For example, if the elements of a are x0, x1, x2, then for_all f a is f x0 && f x1 && f x2.

val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
Same as Dynarray.exists[29.16], but for a two-argument predicate.

Since: 5.4

Raises Invalid_argument if the two arrays have different lengths.

val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
Same as Dynarray.for_all[29.16], but for a two-argument predicate.

Since: 5.4

Raises Invalid_argument if the two arrays have different lengths.

val mem : 'a -> 'a t -> bool

mem a set is true if and only if a is structurally equal to an element of set (i.e. there is an x in set such that compare a x = 0).

Since: 5.3

val memq : 'a -> 'a t -> bool
Same as Dynarray.mem[29.16], but uses physical equality instead of structural equality to compare array elements.

Since: 5.3

val find_opt : ('a -> bool) -> 'a t -> 'a option
find_opt f a returns the first element of the array a that satisfies the predicate f, or None if there is no value that satisfies f in the array a.

Since: 5.3

val find_index : ('a -> bool) -> 'a t -> int option
find_index f a returns Some i, where i is the index of the first element of the array a that satisfies f x, if there is such an element.

It returns None if there is no such element.

Since: 5.3

val find_map : ('a -> 'b option) -> 'a t -> 'b option
find_map f a applies f to the elements of a in order, and returns the first result of the form Some v, or None if none exist.

Since: 5.3
val update_geometry : (geometry -> geometry) -> unit

val pp_get_geometry : formatter -> unit -> geometry

val get_geometry : unit -> geometry

Return the current geometry of the formatter

Since: 4.08

## Maximum formatting depth

The maximum formatting depth is the maximum number of pretty-printing boxes simultaneously open.

Material inside boxes nested deeper is printed as an ellipsis (more precisely as the text returned by `Format.get_ellipse_text[28.21]()`).

val pp_set_max boxes : formatter -> int -> unit

val set_max boxes : int -> unit

`pp_set_max boxes` ppf max sets the maximum number of pretty-printing boxes simultaneously open.

Material inside boxes nested deeper is printed as an ellipsis (more precisely as the text returned by `Format.get_ellipse_text[28.21]()`).

Nothing happens if max is smaller than 2.

val pp_get_max boxes : formatter -> unit -> int

val get_max boxes : unit -> int

Returns the maximum number of pretty-printing boxes allowed before ellipsis.

val pp_over_max boxes : formatter -> unit -> bool

val over_max boxes : unit -> bool

Tests if the maximum number of pretty-printing boxes allowed have already been opened.

## Tabulation boxes

A tabulation box prints material on lines divided into cells of fixed length. A tabulation box provides a simple way to display vertical columns of left adjusted text.

This box features command `set_tab` to define cell boundaries, and command `print_tab` to move from cell to cell and split the line when there is no more cells to print on the line.

Note: printing within tabulation box is line directed, so arbitrary line splitting inside a tabulation box leads to poor rendering. Yet, controlled use of tabulation boxes allows simple printing of columns within module `Format`[28.21].

val pp_open_tbox : formatter -> unit -> unit

val open_tbox : unit -> unit
val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

Since: 5.3

## Comparison functions

Comparison functions iterate over their arguments; it is a programming error to change their length during the iteration, see the Iteration [29.45] section above.

val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool

equal eq a b holds when a and b have the same length, and for all indices i we have eq (get a i) (get b i).

Since: 5.3

val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int

compare cmp a b compares a and b according to the shortlex order, that is, shorter arrays are smaller and equal-sized arrays are compared in lexicographic order using cmp to compare elements.

For more details on comparison functions, see Array.sort [29.2].

Since: 5.3

## Conversions to other data structures

Note: the of_* functions raise Invalid_argument if the length needs to grow beyond Sys.max_array_length [29.60].

The to_* functions, except those specifically marked "reentrant", iterate on their dynarray argument. In particular it is a programming error if the length of the dynarray changes during their execution, and the conversion functions raise Invalid_argument if they observe such a change.

val of_array : 'a array -> 'a t

of_array arr returns a dynamic array corresponding to the fixed-sized array a. Operates in O(n) time by making a copy.

val to_array : 'a t -> 'a array

to_array a returns a fixed-sized array corresponding to the dynamic array a. This always allocate a new array and copies elements into it.

val of_list : 'a list -> 'a t

of_list l is the array containing the elements of l in the same order.

val to_list : 'a t -> 'a list

to_list a is a list with the elements contained in the array a.
`open_tbox ()` opens a new tabulation box.

This box prints lines separated into cells of fixed width.

Inside a tabulation box, special tabulation markers defines points of interest on the line (for instance to delimit cell boundaries). Function `Format.set_tab[28.21]` sets a tabulation marker at insertion point.

A tabulation box features specific tabulation breaks to move to next tabulation marker or split the line. Function `Format.print_tbreak[28.21]` prints a tabulation break.

`val pp_close_tbox : formatter -> unit -> unit`

`val close_tbox : unit -> unit`

Closes the most recently opened tabulation box.

`val pp_set_tab : formatter -> unit -> unit`

`val set_tab : unit -> unit`

Sets a tabulation marker at current insertion point.

`val pp_print_tab : formatter -> unit -> unit`

`val print_tab : unit -> unit`

`print_tab ()` emits a 'next' tabulation break hint: if not already set on a tabulation marker, the insertion point moves to the first tabulation marker on the right, or the pretty-printer splits the line and insertion point moves to the leftmost tabulation marker.

It is equivalent to `print_tbreak 0 0`.

`val pp_print_tbreak : formatter -> int -> int -> unit`

`val print_tbreak : int -> int -> unit`

`print_tbreak nspaces offset` emits a 'full' tabulation break hint.

If not already set on a tabulation marker, the insertion point moves to the first tabulation marker on the right and the pretty-printer prints `nspaces` spaces.

If there is no next tabulation marker on the right, the pretty-printer splits the line at this point, then insertion point moves to the leftmost tabulation marker of the box.

If the pretty-printer splits the line, `offset` is added to the current indentation.

## Ellipsis

`val pp_set_ellipsis_text : formatter -> string -> unit`

`val set_ellipsis_text : string -> unit`

Set the text of the ellipsis printed when too many pretty-printing boxes are open (a single dot, ., by default).

`val pp_get_ellipsis_text : formatter -> unit -> string`

`val get_ellipsis_text : unit -> string`

Return the text of the ellipsis.
val of_seq : 'a Seq.t -> 'a t

of_seq seq is an array containing the same elements as seq.

It traverses seq once and will terminate only if seq is finite.

val to_seq : 'a t -> 'a Seq.t

to_seq a is the sequence of elements get a 0, get a 1... get a (length a - 1).

val to_seq_reentrant : 'a t -> 'a Seq.t

to_seq_reentrant a is a reentrant variant of Dynarray.to_seq[29.16], in the sense that one
may still access its elements after the length of a has changed.

Demanding the i-th element of the resulting sequence (which can happen zero, one or several
times) will access the i-th element of a at the time of the demand. The sequence stops if a
has less than i elements at this point.

val to_seq_rev : 'a t -> 'a Seq.t

to_seq_rev a is the sequence of elements get a (1 - 1), get a (1 - 2)... get a 0,
where l is length a at the time to_seq_rev is invoked.

val to_seq_rev_reentrant : 'a t -> 'a Seq.t

to_seq_rev_reentrant a is a reentrant variant of Dynarray.to_seq_rev[29.16], in the
sense that one may still access its elements after the length of a has changed.

Elements that have been removed from the array by the time they are demanded in the
sequence are skipped.

Advanced topics for performance

Backing array, capacity

Internally, a dynamic array uses a **backing array** (a fixed-size array as provided by the `Array`[29.2] module) whose length is greater or equal to the length of the dynamic array. We define the **capacity** of a dynamic array as the length of its backing array.

The capacity of a dynamic array is relevant in advanced scenarios, when reasoning about the
performance of dynamic array programs:

* The memory usage of a dynamic array is proportional to its capacity, rather than its length.

* When there is no empty space left at the end of the backing array, adding elements requires allocating a new, larger backing array.

The implementation uses a standard exponential reallocation strategy which guarantees amortized constant-time operation; in particular, the total capacity of all backing arrays allocated over the lifetime of a dynamic array is at worst proportional to the total number of elements added.

In other words, users need not care about capacity and reallocations, and they will get reasonable behavior by default. However, in some performance-sensitive scenarios the functions below can help control memory usage or guarantee an optimal number of reallocations.

val capacity : 'a t -> int
Semantic tags

type stag = ..

Semantic tags (or simply *tags*) are user's defined annotations to associate user's specific operations to printed entities.

Common usage of semantic tags is text decoration to get specific font or text size
rendering for a display device, or marking delimitation of entities (e.g. HTML or TeX
elements or terminal escape sequences). More sophisticated usage of semantic tags
could handle dynamic modification of the pretty-printer behavior to properly print the
material within some specific tags. For instance, we can define an RGB tag like so:

type stag += RGB of {r:int;g:int;b:int}

In order to properly delimit printed entities, a semantic tag must be opened before and closed after the entity. Semantic tags must be properly nested like parentheses using `Format.pp_open_stag[28.21]` and `Format.pp_close_stag[28.21]`.

Tag specific operations occur any time a tag is opened or closed, At each occurrence, two kinds of operations are performed *tag-marking* and *tag-printing*:

* The tag-marking operation is the simpler tag specific operation: it simply writes a tag specific string into the output device of the formatter. Tag-marking does not interfere with line-splitting computation.

* The tag-printing operation is the more involved tag specific operation: it can print arbitrary material to the formatter. Tag-printing is tightly linked to the current pretty-printer operations.

Roughly speaking, tag-marking is commonly used to get a better rendering of texts in the
rendering device, while tag-printing allows fine tuning of printing routines to print the same
entity differently according to the semantic tags (i.e. print additional material or even omit
parts of the output).

More precisely: when a semantic tag is opened or closed then both and successive
'tag-printing' and 'tag-marking' operations occur:

* Tag-printing a semantic tag means calling the formatter specific function `print_open_stag` (resp. `print_close_stag`) with the name of the tag as argument: that tag-printing function can then print any regular material to the formatter (so that this material is enqueued as usual in the formatter queue for further line splitting computation).

* Tag-marking a semantic tag means calling the formatter specific function `mark_open_stag` (resp. `mark_close_stag`) with the name of the tag as argument: that tag-marking function can then return the 'tag-opening marker' (resp. 'tag-closing marker') for direct output into the output device of the formatter.
capacity a is the length of a's backing array.

```rust
val ensure_capacity: 'a t -> int -> unit
```

ensure_capacity a n makes sure that the capacity of a is at least n.

**Raises** Invalid_argument if the requested capacity is outside the range 0 .. Sys.max_array_length.

An example would be to reimplement `Dynarray.of_array[29.16]` without using `Dynarray.init[29.16]`:

```rust
let of_array arr =
    let a = Dynarray.create () in
    Dynarray.ensure_capacity a (Array.length arr);
    Array.iter (fun v -> add_last a v) arr
```

Using `ensure_capacity` guarantees that at most one reallocation will take place, instead of possibly several.

Without this `ensure_capacity` hint, the number of resizes would be logarithmic in the length of `arr`, creating a constant-factor slowdown noticeable when `arr` is large.

```rust
val ensure_extra_capacity: 'a t -> int -> unit
```

ensure_extra_capacity a n is `ensure_capacity a (length a + n)`, it makes sure that a has room for n extra items.

**Raises** Invalid_argument if the total requested capacity is outside the range 0 .. Sys.max_array_length.

A use case would be to implement `Dynarray.append_array[29.16]`:

```rust
let append_array a arr =
    ensure_extra_capacity a (Array.length arr);
    Array.iter (fun v -> add_last a v) arr
```

```rust
val fit_capacity: 'a t -> unit
```

`fit_capacity` a reallocates a backing array if necessary, so that the resulting capacity is exactly `length a`, with no additional empty space at the end. This can be useful to make sure there is no memory wasted on a long-lived array.

Note that calling `fit_capacity` breaks the amortized complexity guarantees provided by the default reallocation strategy. Calling it repeatedly on an array may have quadratic complexity, both in time and in total number of words allocated.

If you know that a dynamic array has reached its final length, which will remain fixed in the future, it is sufficient to call `to_array` and only keep the resulting fixed-size array.

`fit_capacity` is useful when you need to keep a dynamic array for eventual future resizes.
Being written directly into the output device of the formatter, semantic tag marker strings are not considered as part of the printing material that drives line splitting (in other words, the length of the strings corresponding to tag markers is considered as zero for line splitting).

Thus, semantic tag handling is in some sense transparent to pretty-printing and does not interfere with usual indentation. Hence, a single pretty-printing routine can output both simple 'verbatim' material or richer decorated output depending on the treatment of tags. By default, tags are not active, hence the output is not decorated with tag information. Once `set tags` is set to `true`, the pretty-printer engine honors tags and decorates the output accordingly.

Default tag-marking functions behave the HTML way: string tags[28.21] are enclosed in `"<"` and `">"` while other tags are ignored; hence, opening marker for tag string `"t"` is `"<t>"` and closing marker is `"</t>"`.

Default tag-printing functions just do nothing.

Tag-marking and tag-printing functions are user definable and can be set by calling `Format.set_formatter_stag_functions[28.21]`.

Semantic tag operations may be set on or off with `Format.set tags[28.21]`. Tag-marking operations may be set on or off with `Format.set_mark tags[28.21]`. Tag-printing operations may be set on or off with `Format.set_print tags[28.21]`.

**Since: 4.08**

`type tag = string`

`type stag +=`

`| String_tag of tag`

`String_tag s` is a string tag `s`. String tags can be inserted either by explicitly using the constructor `String_tag` or by using the dedicated format syntax `"@{
 ... @}"`.

**Since: 4.08**

`val pp_open_stag : formatter -> stag -> unit`

`val open_stag : stag -> unit`

`pp_open_stag ppf t` opens the semantic tag named `t`.

The `print_open_stag` tag-printing function of the formatter is called with `t` as argument; then the opening tag marker for `t`, as given by `mark_open_stag t`, is written into the output device of the formatter.

**Since: 4.08**

`val pp_close_stag : formatter -> unit -> unit`

`val close_stag : unit -> unit`

`pp_close_stag ppf ()` closes the most recently opened semantic tag `t`.

The closing tag marker, as given by `mark_close_stag t`, is written into the output device of the formatter; then the `print_close_stag` tag-printing function of the formatter is called with `t` as argument.

**Since: 4.08**
val set_capacity : 'a t -> int -> unit

set_capacity a n reallocates a backing array if necessary, so that the resulting capacity is
exactly n. In particular, all elements of index n or greater are removed.

Like Dynarray.fit_capacity[29.16], this function breaks the amortized complexity
guarantees provided by the reallocation strategy. Calling it repeatedly on an array may have
quadratic complexity, both in time and in total number of words allocated.

This is an advanced function; in particular, Dynarray.ensure_capacity[29.16] should be
preferred to increase the capacity, as it preserves those amortized guarantees.

Raises Invalid_argument if n < 0.

val reset : 'a t -> unit

reset a clears a and replaces its backing array by an empty array.

It is equivalent to set_capacity a 0 or clear a; fit_capacity a.

No leaks: preservation of memory liveness

The user-provided values reachable from a dynamic array *a* are exactly the elements in the indices 0 to *length a* - 1. In particular, no user-provided values are "leaked" by being present in the backing array at index *length a* or later.

val unsafe_to_iarray : capacity:int -> ('a t -> unit) -> 'a iarray

unsafe_to_iarray ~capacity f calls f on a new empty dynarray with the given capacity,
then turns it into an immutable array without a copy, when possible, that is, if two conditions
hold:

* the array elements are not floats, and

* after *f* returned, the array's capacity is equal to its length.

Note that the capacity argument is only a hint. For example, nothing prevents from calling
Dynarray.fit_capacity[29.16] at the end of *f*.

This function is unsafe because type safety may be broken by concurrent writes to the
dynarray from other domains, without proper synchronization, before *f* returns.

Code examples

Min-heaps for mutable priority queues

We can use dynamic arrays to implement a mutable priority queue. A priority queue provides a
function to add elements, and a function to extract the minimum element – according to some
comparison function.

(* We present our priority queues as a functor parametrized on the comparison function. *)

module Heap (Elem : Map.OrderedType) : sig
val pp_seteloags: formatter -> bool -> unit

val seteloags : bool -> unit

pp_seteloags ppf b turns on or off the treatment of semantic tags (default is off).

val pp_set_printeloags : formatter -> bool -> unit

val set_printeloags : bool -> unit

pp_set_printeloags ppf b turns on or off the tag-printing operations.

val pp_set_markeloags : formatter -> bool -> unit

val set_markeloags : bool -> unit

pp_set_markeloags ppf b turns on or off the tag-marking operations.

val pp_get_printeloags : formatter -> unit -> bool

val get_printeloags : unit -> bool

Return the current status of tag-printing operations.

val pp_get_markeloags : formatter -> unit -> bool

val get_markeloags : unit -> bool

Return the current status of tag-marking operations.

val pp_set_formatero channel : formatter -> out_channel -> unit

## Redirecting the standard formatter output

val set_formatero channel : out_channel -> unit

Redirect the standard pretty-printer output to the given channel. (All the output functions of the standard formatter are set to the default output functions printing to the given channel.)

set_formatero channel is equivalent to

Format.pp_set_formatero channel [28.21] std_formatter.

val pp_set_formatero output_functions :

formatter -> (string -> int -> int -> unit) -> (unit -> unit) -> unit

val set_formatero output_functions :

(string -> int -> int -> unit) -> (unit -> unit) -> unit

pp_set_formatero output_functions ppf out flush redirects the standard
pretty-printer output functions to the functions out and flush.

The out function performs all the pretty-printer string output. It is called with a string s, a
start position p, and a number of characters n; it is supposed to output characters p to p + n
- 1 of s.

The flush function is called whenever the pretty-printer is flushed (via conversion %!, or
pretty-printing indications @? or @., or using low level functions print_flush or
print_newline).
```fortran
type t
val create : unit -> t
val add : t -> Elem.t -> unit
val pop_min : t -> Elem.t option
end = struct
```

(* Our priority queues are implemented using the standard "min heap" data structure, a dynamic array representing a binary tree. *)

```fortran
type t = Elem.t Dynarray.t
let create = Dynarray.create
```

(* The node of index [i] has as children the nodes of index [2 * i + 1] and [2 * i + 2] -- if they are valid indices in the dynarray. *)

```fortran
let left_child i = 2 * i + 1
let right_child i = 2 * i + 2
let parent_node i = (i - 1) / 2
```

(* We use indexing operators for convenient notations. *)

```fortran
let ( .!( ) ) = Dynarray.get
let ( .!( ) <- ) = Dynarray.set
```

(* Auxiliary functions to compare and swap two elements in the dynamic array. *)

```fortran
let order h i j =
    Elem comparisons h.(i) h.(j)
```

```fortran
let swap h i j =
    let v = h.(i) in
    h.(i) <- h.(j);
    h.(j) <- v
```

(* We say that a heap respects the "heap ordering" if the value of each node is smaller than the value of its children. The algorithm manipulates arrays that respect the heap algorithm, except for one node whose value may be too small or too large.

The auxiliary functions `[heap_up]` and `[heap_down]` take such a misplaced value, and move it "up" (respectively: "down") the tree by permuting it with its parent value (respectively: a child value) until the heap ordering is restored. *)

```fortran
let rec heap_up h i =
    if i = 0 then () else
    let parent = parent_node i in
    if order h i parent < 0 then
```
```rust
val pp_get_formatter_output_functions :
    formatter -> unit -> (string -> int -> int -> unit) * (unit -> unit)

val get_formatter_output_functions :
    unit -> (string -> int -> int -> unit) * (unit -> unit)
```

Return the current output functions of the standard pretty-printer.

## Redefining formatter output

The `Format` module is versatile enough to let you completely redefine the meaning of pretty-printing output: you may provide your own functions to define how to handle indentation, line splitting, and even printing of all the characters that have to be printed!

### Redefining output functions

```rust
type formatter_out_functions =
{
    out_string : string -> int -> int -> unit ;
    out_flush : unit -> unit ;
    out_newline : unit -> unit ;
    out spaces : int -> unit ;
    out ident : int -> unit ;
```

Since: 4.06

}

The set of output functions specific to a formatter:

* the `out_string` function performs all the pretty-printer string output. It is called with a string `s`, a start position `p`, and a number of characters `n`; it is supposed to output characters `p` to `p + n - 1` of `s`.

* the `out_flush` function flushes the pretty-printer output device.

* `out_newline` is called to open a new line when the pretty-printer splits the line.

* the `out spaces` function outputs spaces when a break hint leads to spaces instead of a line split. It is called with the number of spaces to output.

* the `out ident` function performs new line indentation when the pretty-printer splits the line. It is called with the indentation value of the new line.

By default:

* fields `out_string` and `out_flush` are output device specific; (e.g. `output_string[27.2]` and `flush[27.2]` for a `out_channel[27.2]` device, or `Buffer.add_substring` and `ignore[27.2]` for a `Buffer.t` output device),

* field `out_newline` is equivalent to `out_string "\n" 0 1;`

* fields `out spaces` and `out ident` are equivalent to `out_string (String.make n ' ) 0 n.`

Since: 4.01
(swap h i parent; heap_up h parent)

and heap_down h ~len i =
let left, right = left_child i, right_child i in
if left >= len then () (* no child, stop *) else
let smallest =
  if right >= len then left (* no right child *) else
  if order h left right < 0 then left else right
in
if order h i smallest > 0 then
  (swap h i smallest; heap_down h ~len smallest)

let add h s =
let i = Dynarray.length h in
Dynarray.add_last h s;
heap_up h i

let pop_min h =
  if Dynarray.is_empty h then None
  else begin
    (* Standard trick: swap the 'best' value at index 0
       with the last value of the array. *)
    let last = Dynarray.length h - 1 in
    swap h 0 last;
    (* At this point [pop_last] returns the 'best' value,
       and leaves a heap with one misplaced element at index [0]. *)
    let best = Dynarray.pop_last h in
    (* Restore the heap ordering -- does nothing if the heap is empty. *)
    heap_down h ~len:last 0;
    Some best
  end
end

The production code from which this example was inspired includes logic to free the backing
array when the heap becomes empty, only in the case where the capacity is above a certain threshold.
This can be done by calling the following function from pop:

let shrink h =
  if Dynarray.length h = 0 && Dynarray.capacity h > 1 lsl 18 then
    Dynarray.reset h

The Heap functor can be used to implement a sorting function, by adding all elements into a
priority queue and then extracting them in order.

let heap_sort (type a) cmp li =
val pp_set_formatter_out_functions :
formatter -> formatter_out_functions -> unit

val set_formatter_out_functions : formatter_out_functions -> unit

pp_set_formatter_out_functions ppf out_funs Set all the pretty-printer output
functions of ppf to those of argument out_funs,

This way, you can change the meaning of indentation (which can be something else than just
printing space characters) and the meaning of new lines opening (which can be connected to
any other action needed by the application at hand).

Reasonable defaults for functions out-spaces and out_newline are respectively
out_funs.out_string (String.make n ' ') 0 n and out_funs.out_string "\n" 0 1.

Since: 4.01

val pp_get_formatter_out_functions :
formatter -> unit -> formatter_out_functions

val get_formatter_out_functions : unit -> formatter_out_functions

Return the current output functions of the pretty-printer, including line splitting and
indentation functions. Useful to record the current setting and restore it afterwards.

Since: 4.01

Redefining semantic tag operations

type formatter_stag_functions =
{
  mark_open_stag : stag -> string ;
  mark_close_stag : stag -> string ;
  print_open_stag : stag -> unit ;
  print_close_stag : stag -> unit ;
}

The semantic tag handling functions specific to a formatter: `mark` versions are the 'tag-marking' functions that associate a string marker to a tag in order for the pretty-printing engine to write those markers as 0 length tokens in the output device of the formatter. `print` versions are the 'tag-printing' functions that can perform regular printing when a tag is closed or opened.

Since: 4.08

val pp_set_formatter_stag_functions :
formatter -> formatter_stag_functions -> unit

val set_formatter_stag_functions : formatter_stag_functions -> unit

pp_set_formatter_stag_functions ppf tag_funs changes the meaning of opening and
closing semantic tag operations to use the functions in tag_funs when printing on ppf.

When opening a semantic tag with name `t`, the string `t` is passed to the opening tag-marking function (the `mark_open_stag` field of the record `tag_funs`), that must return the opening
```python
let module Heap = Heap(struct type t = a let compare = cmp end) in
let heap = Heap.create () in
List.iter (Heap.add heap) li;
List.map (fun _ -> Heap.pop_min heap |> Option.get) li
```

## 29.17 Module Iarray

Operations on immutable arrays. This module mirrors the API of `Array`, but omits functions that assume mutability; in addition to obviously mutating functions, it omits `copy` along with the functions `make`, `create_float`, and `make_matrix` that produce all-constant arrays. The exception is the sorting functions, which are given a copying API to replace the in-place one.

**type 'a t = 'a iarray**

An alias for the type of immutable arrays.

**val length : 'a iarray -> int**

Return the length (number of elements) of the given immutable array.

**val get : 'a iarray -> int -> 'a**

`get` a `n` returns the element number `n` of immutable array `a`. The first element has number 0. The last element has number `length a - 1`.

**Raises Invalid_argument if n is outside the range 0 to (length a - 1).**

**val init : int -> (int -> 'a) -> 'a iarray**

`init` n f returns a fresh immutable array of length `n`, with element number `i` initialized to the result of `f i`. In other terms, `init n f` tabulates the results of `f` applied to the integers 0 to `n-1`.

**Raises Invalid_argument if n < 0 or n > Sys.max_array_length.** If the return type of `f` is `float`, then the maximum size is only `Sys.max_array_length / 2`.

**val append : 'a iarray -> 'a iarray -> 'a iarray**

`append` v1 v2 returns a fresh immutable array containing the concatenation of the immutable arrays `v1` and `v2`.

**Raises Invalid_argument if length v1 + length v2 > Sys.max_array_length.**

**val concat : 'a iarray list -> 'a iarray**

Same as `Iarray.append[29.17]`, but concatenates a list of immutable arrays.

**val sub : 'a iarray -> pos:int -> len:int -> 'a iarray**

`sub` a ~`pos` ~`len` returns a fresh immutable array of length `len`, containing the elements number `pos` to `pos + len - 1` of immutable array `a`. This creates a copy of the selected portion of the immutable array.
tag marker for that name. When the next call to `close_stag ()` happens, the semantic tag name `t` is sent back to the closing tag-marking function (the `mark_close_stag` field of record `tag_funs`), that must return a closing tag marker for that name.

The `print_` field of the record contains the tag-printing functions that are called at tag opening and tag closing time, to output regular material in the pretty-printer queue.

**Since: 4.08**

```hkl
val pp_get_formatter_stag_functions :
    formatter -> unit -> formatter_stag_functions
```

```hkl
val get_formatter_stag_functions : unit -> formatter_stag_functions
```

Return the current semantic tag operation functions of the standard pretty-printer.

**Since: 4.08**

## Defining formatters

Defining new formatters permits unrelated output of material in parallel on several output devices. All the parameters of a formatter are local to the formatter: right margin, maximum indentation limit, maximum number of pretty-printing boxes simultaneously open, ellipsis, and so on, are specific to each formatter and may be fixed independently.

For instance, given a `Buffer.t[28.7]` buffer `b`, `Format formatter_of_buffer[28.21] b` returns a new formatter using buffer `b` as its output device. Similarly, given a `out_channel[27.2]` output channel `oc`, `Format formatter_of_out_channel[28.21] oc` returns a new formatter using channel `oc` as its output device.

Alternatively, given `out_funs`, a complete set of output functions for a formatter, then `Format formatter_of_out_functions[28.21] out_funs` computes a new formatter using those functions for output.

```hkl
val formatter_of_out_channel : out_channel -> formatter
    formatter_of_out_channel oc returns a new formatter writing to the corresponding
    output channel oc.
```

```hkl
val synchronized_formatter_of_out_channel :
    out_channel -> formatter Domain.DLS.key
    synchronized_formatter_of_out_channel oc returns the key to the domain-local state
    that holds the domain-local formatter for writing to the corresponding output channel oc.
```

When the formatter is used with multiple domains, the output from the domains will be interleaved with each other at points where the formatter is flushed, such as with `Format.print_flush[28.21]`.

**Alert unstable**

```hkl
val std_formatter : formatter
    The initial domain's standard formatter to write to standard output.
    It is defined as `Format formatter_of_out_channel[28.21] stdout[27.2]`.
```
**Raises** Invalid_argument if pos and len do not designate a valid subarray of a; that is, if pos < 0, or len < 0, or pos + len > length a.

val to_list : 'a iarray -> 'a list

to_list a returns the list of all the elements of a.

val of_list : 'a list -> 'a iarray

of_list l returns a fresh immutable array containing the elements of l.

**Raises** Invalid_argument if the length of l is greater than Sys.max_array_length.

## Converting to and from mutable arrays

val to_array : 'a iarray -> 'a array

to_array a returns a mutable copy of the immutable array a; that is, a fresh (mutable) array containing the same elements as a

val of_array : 'a array -> 'a iarray

of_array ma returns an immutable copy of the mutable array ma; that is, a fresh immutable array containing the same elements as ma

## Comparison

val equal : ('a -> 'a -> bool) -> 'a iarray -> 'a iarray -> bool

eq [|a1; ...; an|] [|b1; ..; bm|] holds when the two input immutable arrays have the same length, and for each pair of elements ai, bi at the same position we have eq ai bi.

val compare : ('a -> 'a -> int) -> 'a iarray -> 'a iarray -> int

Provided the function cmp defines a preorder on elements, compare cmp a b compares first a and b by their length, and then, if equal, by their elements according to the lexicographic preorder.

For more details on comparison functions, see Iarray.sort[29.17].

## Iterators

val iter : ('a -> unit) -> 'a iarray -> unit

iter f a applies function f in turn to all the elements of a. It is equivalent to f (get a 0); f (get a 1); ...; f (get a (length a - 1)); ().

val iteri : (int -> 'a -> unit) -> 'a iarray -> unit

Same as Iarray.iter[29.17], but the function is applied to the index of the element as first argument, and the element itself as second argument.
val get_std_formatter : unit -> formatter

get_std_formatter () returns the current domain's standard formatter used to write to
standard output.

Since: 5.0

val err_formatter : formatter

The initial domain's formatter to write to standard error.

It is defined as `Format.formatter_of_out_channel[28.21] stderr[27.2]`.

val get_err_formatter : unit -> formatter

get_err_formatter () returns the current domain's formatter used to write to standard error.

Since: 5.0

val formatter_of_buffer : Buffer.t -> formatter

formatter_of_buffer b returns a new formatter writing to buffer b. At the end of pretty-printing, the formatter must be flushed using `Format.pp_print_flush[28.21]` or `Format.pp_print_newline[28.21]`, to print all the pending material into the buffer.

val stdbuf : Buffer.t

The initial domain's string buffer in which `str_formatter` writes.

val get_stdbuf : unit -> Buffer.t

get_stdbuf () returns the current domain's string buffer in which the current domain's string formatter writes.

Since: 5.0

val str_formatter : formatter

The initial domain's formatter to output to the `Format.stdbuf[28.21]` string buffer.

`str_formatter` is defined as `Format.formatter_of_buffer[28.21] Format.stdbuf[28.21]`.

val get_str_formatter : unit -> formatter

The current domain's formatter to output to the current domain's string buffer.

Since: 5.0

val flush_str_formatter : unit -> string

Returns the material printed with `str_formatter` of the current domain, flushes the formatter and resets the corresponding buffer.

val make_formatter :

(string -> int -> int -> unit) -> (unit -> unit) -> formatter
val map : ('a -> 'b) -> 'a iarray -> 'b iarray
map f a applies function f to all the elements of a, and builds an immutable array with the
results returned by f: [| f (get a 0); f (get a 1); ...; f (get a (length a - 1))
|].

val mapi : (int -> 'a -> 'b) -> 'a iarray -> 'b iarray
Same as Iarray.map[29.17], but the function is applied to the index of the element as first argument, and the element itself as second argument.

val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b iarray -> 'a
fold_left f init a computes f (... (f (f init (get a 0)) (get a 1)) ...) (get
a n-1), where n is the length of the immutable array a.

val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b iarray -> 'a * 'c iarray
fold_left_map is a combination of Iarray.fold_left[29.17] and Iarray.map[29.17] that
threads an accumulator through calls to f.

val fold_right : ('b -> 'a -> 'a) -> 'b iarray -> 'a -> 'a
fold_right f a init computes f (get a 0) (f (get a 1) ( ... (f (get a (n-1))
init) ...)), where n is the length of the immutable array a.

Iterators on two arrays

val iter2 : ('a -> 'b -> unit) -> 'a iarray -> 'b iarray -> unit
iter2 f a b applies function f to all the elements of a and b.

Raises Invalid_argument if the immutable arrays are not the same size.

val map2 : ('a -> 'b -> 'c) -> 'a iarray -> 'b iarray -> 'c iarray
map2 f a b applies function f to all the elements of a and b, and builds an immutable array
with the results returned by f: [| f (get a 0) (get b 0); ...; f (get a (length a -
1)) (get b (length b - 1)) |].

Raises Invalid_argument if the immutable arrays are not the same size.

Array scanning

val for_all : ('a -> bool) -> 'a iarray -> bool
for_all f [|a1; ...; an|] checks if all elements of the immutable array satisfy the
predicate f. That is, it returns (f a1) && (f a2) && ... && (f an).

val exists : ('a -> bool) -> 'a iarray -> bool
exists f [[a1; ...; an]] checks if at least one element of the immutable array satisfies
the predicate f. That is, it returns (f a1) || (f a2) || ... || (f an).
`make_formatter out flush` returns a new formatter that outputs with function `out`, and flushes with function `flush`.

For instance,

```s
make_formatter
    (Stdlib.output oc)
    (fun () -> Stdlib.flush oc)
```

returns a formatter to the `out_channel[27.2]` oc.

```rust
val make_synchronized_formatter :
    (string -> int -> int -> unit) ->
    (unit -> unit) -> formatter Domain.DLS.key

    make_synchronized_formatter out flush
        returns the key to the domain-local state that
        holds the domain-local formatter that outputs with function out, and flushes with function
        flush.
```

When the formatter is used with multiple domains, the output from the domains will be interleaved with each other at points where the formatter is flushed, such as with `Format.print_flush[28.21]`.

**Since: 5.0**

**Alert unstable**

```rust
val formatter_of_out_functions : formatter_out_functions -> formatter

formatter_of_out_functions out_funs
    returns a new formatter that writes with the set
    of output functions out_funs.
```

See definition of type `Format formatter_out_functions[28.21]` for the meaning of argument `out_funs`.

**Since: 4.06**

## Symbolic pretty-printing

Symbolic pretty-printing is pretty-printing using a symbolic formatter, i.e. a formatter that outputs symbolic pretty-printing items.

When using a symbolic formatter, all regular pretty-printing activities occur but output material is symbolic and stored in a buffer of output items. At the end of pretty-printing, flushing the output buffer allows post-processing of symbolic output before performing low level output operations.

In practice, first define a symbolic output buffer `b` using:

* `let sob = make_symbolic_output_buffer ()`. Then define a symbolic formatter with:

* `let ppf = formatter_of_symbolic_output_buffer sob`

Use symbolic formatter `ppf` as usual, and retrieve symbolic items at end of pretty-printing by flushing symbolic output buffer `sob` with:
val for_all2 : ('a -> 'b -> bool) -> 'a iarray -> 'b iarray -> bool

Same as Iarray.for_all[29.17], but for a two-argument predicate.

**Raises** Invalid_argument if the two immutable arrays have different lengths.

val exists2 : ('a -> 'b -> bool) -> 'a iarray -> 'b iarray -> bool

Same as Iarray.exists[29.17], but for a two-argument predicate.

**Raises** Invalid_argument if the two immutable arrays have different lengths.

val mem : 'a -> 'a iarray -> bool

mem a set is true if and only if a is structurally equal to an element of l (i.e. there is an x in l such that compare a x = 0).

val memq : 'a -> 'a iarray -> bool

Same as Iarray.mem[29.17], but uses physical equality instead of structural equality to compare array elements.

val find_opt : ('a -> bool) -> 'a iarray -> 'a option

find_opt f a returns the first element of the immutable array a that satisfies the predicate f, or None if there is no value that satisfies f in the array a.

val find_index : ('a -> bool) -> 'a iarray -> int option

find_index f a returns Some i, where i is the index of the first element of the array a that satisfies f x, if there is such an element.

It returns None if there is no such element.

val find_map : ('a -> 'b option) -> 'a iarray -> 'b option

find_map f a applies f to the elements of a in order, and returns the first result of the form Some v, or None if none exist.

val find_mapi : (int -> 'a -> 'b option) -> 'a iarray -> 'b option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

## Arrays of pairs

val split : ('a * 'b) iarray -> 'a iarray * 'b iarray

split [|(a1,b1); ...; (an,bn)|] is ([|a1; ...; an|], [|b1; ...; bn|]).

val combine : 'a iarray -> 'b iarray -> ('a * 'b) iarray

combine [|a1; ...; an|] [|b1; ...; bn|] is [|(a1,b1); ...; (an,bn)|]. Raise Invalid_argument if the two immutable arrays have different lengths.
* `flush_symbolic_output_buffer` sob.

`type symbolic_output_item =`

| `Output_flush`
symbolic flush command

| `Output_newline`
symbolic newline command

| `Output_string` of `string`
`Output_string s`: symbolic output for string `s`

| `Output spaces` of `int`
`Output spaces n`: symbolic command to output `n` spaces

| `Output indent` of `int`
`Output indent i`: symbolic indentation of size `i`

Items produced by symbolic pretty-printers

Since: 4.06

`type symbolic_output_buffer`

The output buffer of a symbolic pretty-printer.

Since: 4.06

`val make_symbolic_output_buffer : unit -> symbolic_output_buffer`
`make_symbolic_output_buffer ()` returns a fresh buffer for symbolic output.

Since: 4.06

`val clear_symbolic_output_buffer : symbolic_output_buffer -> unit`
`clear_symbolic_output_buffer` sob resets buffer `sob`.

Since: 4.06

`val get_symbolic_output_buffer :`

symbolic_output_buffer -> symbolic_output_item list
`get_symbolic_output_buffer` sob returns the contents of buffer `sob`.

Since: 4.06

`val flush_symbolic_output_buffer :`

symbolic_output_buffer -> symbolic_output_item list
`flush_symbolic_output_buffer` sob returns the contents of buffer `sob` and resets buffer
`sob`. `flush_symbolic_output_buffer` sob is equivalent to `let items =
get_symbolic_output_buffer` sob in `clear_symbolic_output_buffer` sob; `items`

Since: 4.06
## Sorting

val sort : ('a -> 'a -> int) -> 'a iarray -> 'a iarray

Sort an immutable array in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, `compare[28.2]` is a suitable comparison function. The result of calling `sort` is a fresh immutable array containing the same elements as the original sorted in increasing order. Other than this fresh array, `sort` is guaranteed to run in constant heap space and (at most) logarithmic stack space.

The current implementation uses Heap Sort. It runs in constant stack space.

Specification of the comparison function: Let `a` be the immutable array and `cmp` the comparison function. The following must be true for all `x`, `y`, `z` in `a`:

* `cmp x y > 0` if and only if `cmp y x < 0`

* if `cmp x y ≥ 0` and `cmp y z ≥ 0` then `cmp x z ≥ 0`

The result of `sort`, which we'll call `a'`, contains the same elements as `a`, reordered in such a way that for all `i` and `j` valid indices of `a` (or equivalently, of `a`':

* `cmp (get a' i) (get a' j) ≥ 0` if and only if `i ≥ j`

val stable_sort : ('a -> 'a -> int) -> 'a iarray -> 'a iarray

Same as `Iarray.sort[29.17]`, but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.

The current implementation uses Merge Sort. It uses a temporary array of length `n/2`, where `n` is the length of the immutable array. It is usually faster than the current implementation of `Iarray.sort[29.17]`.

val fast_sort : ('a -> 'a -> int) -> 'a iarray -> 'a iarray

Same as `Iarray.sort[29.17]` or `Iarray.stable_sort[29.17]`, whichever is faster on typical input.

## Iterators

val to_seq : 'a iarray -> 'a Seq.t

Iterate on the immutable array, in increasing order.

val to_seqi : 'a iarray -> (int * 'a) Seq.t

Iterate on the immutable array, in increasing order, yielding indices along elements.

val of_seq : 'a Seq.t -> 'a iarray

Create an immutable array from the generator
val add_symbolic_output_item :
symbolic_output_buffer -> symbolic_output_item -> unit

add_symbolic_output_item sob itm adds item itm to buffer sob.

Since: 4.06

val formatter_of_symbolic_output_buffer : symbolic_output_buffer -> formatter
formatter_of_symbolic_output_buffer sob returns a symbolic formatter that outputs to
symbolic_output_buffer sob.

Since: 4.06

Convenience formatting functions.

val pp_print_iter :
?pp_sep:(formatter -> unit -> unit) ->
(( 'a -> unit) -> 'b -> unit) ->
(formatter -> 'a -> unit) -> formatter -> 'b -> unit
pp_print_iter ~pp_sep iter pp_v ppf v formats on ppf the iterations of iter over a
collection v of values using pp_v. Iterations are separated by pp_sep (defaults to
Format.pp_print_cut[28.21]).

Since: 5.1

val pp_print_list :
?pp_sep:(formatter -> unit -> unit) ->
(formatter -> 'a -> unit) -> formatter -> 'a list -> unit

pp_print_list ?pp_sep pp_v ppf 1 prints items of list 1, using pp_v to print each item,
and calling pp_sep between items (pp_sep defaults to Format.pp_print_cut[28.21]). Does
nothing on empty lists.

Since: 4.02

val pp_print_array :
?pp_sep:(formatter -> unit -> unit) ->
(formatter -> 'a -> unit) -> formatter -> 'a array -> unit

pp_print_array ?pp_sep pp_v ppf a prints items of array a, using pp_v to print each
item, and calling pp_sep between items (pp_sep defaults to Format.pp_print_cut[28.21]).
Does nothing on empty arrays.

If a is mutated after pp_print_array is called, the printed values may not be what is
expected because Format can delay the printing. This can be avoided by flushing ppf.

Since: 5.1

val pp_print_seq :
?pp_sep:(formatter -> unit -> unit) ->
(formatter -> 'a -> unit) ->
formatter -> 'a Seq.t -> unit
## 29.18 Module Effect : Effects.

See 'Language extensions/Effect handlers' section in the manual.

Since: 5.0

**Alert unstable.** The Effect interface may change in incompatible ways in the future.

```hkl
type 'a t = 'a eff = ..
```

The type of effects.

```hkl
exception Unhandled : 'a t -> exn
```

`` `e` is raised when effect `e` is performed and there is no handler for it.

```hkl
exception Continuation already resumed
```

Exception raised when a continuation is continued or discontinued more than once.

```hkl
val perform : 'a t -> 'a
```

`perform` `e` performs an effect `e`.

**Raises** ` object` ` e` if there is no handler for `e`.

```python
module Deep :
```

```
sig
```

Deep handlers

```hkl
type ('a, 'b) continuation = ('a, 'b) continuation
```

(`'a', 'b`) continuation is a delimited continuation that expects a `'a` value and returns a `'b` value.

```hkl
val continue : ('a, 'b) continuation -> 'a -> 'b
```

`continue` `k` `x` resumes the continuation `k` by passing `x` to `k`.

**Raises** `Continuation already resumed` if the continuation has already been resumed.

```hkl
val discontinue : ('a, 'b) continuation -> exn -> 'b
```

`discontinue` `k` `e` resumes the continuation `k` by raising the exception `e` in `k`.

**Raises** `Continuation already resumed` if the continuation has already been resumed.

```hkl
val discontinue_with_backtrace :
```

```
('a, 'b) continuation ->
```

```
exn -> Printexc/raw_backtrace -> 'b
```

`discontinue_with_backtrace` `k` `e` `bt` resumes the continuation `k` by raising the exception `e` in `k` using `bt` as the origin for the exception.

**Raises** `Continuation already resumed` if the continuation has already been resumed.
`pp_print_seq` ?`pp_sep` `pp_v` `ppf` `s` prints items of sequence `s`, using `pp_v` to print each item, and calling `pp_sep` between items (`pp_sep` defaults to `Format.pp_print_cut[28.21]`). Does nothing on empty sequences.

This function does not terminate on infinite sequences.

**Since: 4.12**

`val pp_print_text : formatter -> string -> unit`

`pp_print_text` `ppf` `s` prints `s` with spaces and newlines respectively printed using `Format.pp_print_space[28.21]` and `Format.pp_force_newline[28.21]`.

**Since: 4.02**

`val pp_print_option :`
`?none:(formatter -> unit -> unit) ->`
`(formatter -> 'a -> unit) -> formatter -> 'a` option -> `unit`

`pp_print_option` ?`none` `pp_v` `ppf` `o` prints `o` on `ppf` using `pp_v` if `o` is `Some v` and `none` if it is `None`. `none` prints nothing by default.

**Since: 4.08**

`val pp_print_result :`
`ok:(formatter -> 'a -> unit) ->`
`error:(formatter -> 'e -> unit) ->`
`formatter -> ('a, 'e)` result -> `unit`

`pp_print_result` ~`ok` ~`error` `ppf` `r` prints `r` on `ppf` using `ok` if `r` is `Ok _` and `error` if `r` is `Error _`.

**Since: 4.08**

`val pp_print_either :`
`left:(formatter -> 'a -> unit) ->`
`right:(formatter -> 'b -> unit) ->`
`formatter -> ('a, 'b)` Either.t -> `unit`

`pp_print_either` ~`left` ~`right` `ppf` `e` prints `e` on `ppf` using `left` if `e` is `Either Left` and `right` if `e` is `Either Right`.

**Since: 4.13**

## Formatted pretty-printing

Module `Format` provides a complete set of `printf` like functions for pretty-printing using format string specifications.

Specific annotations may be added in the format strings to give pretty-printing commands to the pretty-printing engine.

Those annotations are introduced in the format strings using the `@` character. For instance, `@` means a space break, `@`, means a cut, `@[` opens a new box, and `@]` closes the last open box.
```h
type ('a, 'b) handler =
{
    retc : 'a -> 'b ;
    exnc : exn -> 'b ;
    effc : 'c. 'c Effect.t -> (( 'c, 'b) continuation -> 'b) option ;
}
```

``('a, 'b) handler is a handler record with three fields – `retc` is the value handler, `exnc` handles exceptions, and `effc` handles the effects performed by the computation enclosed by the handler.

```h
val match_with : ('c -> 'a) -> 'c -> ('a, 'b) handler -> 'b

match_with f v h runs the computation f v in the handler h.
```

```h
type 'a effect_handler =
{
    effc : 'b. 'b Effect.t -> (( 'b, 'a) continuation -> 'a) option ;
}
```

`'a effect_handler` is a deep handler with an identity value handler `fun x -> x` and an exception handler that raises any exception `fun e -> raise e`.

```h
val try_with : ('b -> 'a) -> 'b -> 'a effect_handler -> 'a

try_with f v h runs the computation f v under the handler h.
```

```h
val get_callstack : ('a, 'b) continuation -> int -> Printexc/raw_backtrace

get_callstack c n returns a description of the top of the call stack on the
continuation c, with at most n entries.
```

end

```h
module Shallow :
    sig
```

```h
type ('a, 'b) continuation
```

``('a, 'b) continuation is a delimited continuation that expects a 'a value and returns
a 'b value.

```h
val fiber : ('a -> 'b) -> ('a, 'b) continuation
```

`fiber f` constructs a continuation that runs the computation `f`.

```h
type ('a, 'b) handler =
{
    retc : 'a -> 'b ;
    exnc : exn -> 'b ;
    effc : 'c. 'c Effect.t -> (( 'c, 'a) continuation -> 'b) option ;
}
```
`val fprintf: formatter -> ('a, formatter, unit) format -> 'a`

`fprintf ff fmt arg1 ... argN` formats the arguments `arg1` to `argN` according to the format string `fmt`, and outputs the resulting string on the formatter `ff`.

The format string `fmt` is a character string which contains three types of objects: plain characters and conversion specifications as specified in the `FORMAT[28.43]` module, and pretty-printing indications specific to the `Format` module.

The pretty-printing indication characters are introduced by a `@` character, and their meanings are:

* `@[:`: open a pretty-printing box. The type and offset of the box may be optionally specified with the following syntax: the `<` character, followed by an optional box type indication, then an optional integer offset, and the closing `>` character. Pretty-printing box type is one of `h`, `v`, `hv`, `b`, or `hov`. 'h' stands for an 'horizontal' pretty-printing box, 'v' stands for a 'vertical' pretty-printing box, 'hv' stands for an 'horizontal/vertical' pretty-printing box, 'b' stands for an 'horizontal-or-vertical' pretty-printing box demonstrating indentation, 'hov' stands a simple 'horizontal-or-vertical' pretty-printing box. For instance, `@[<hov 2>` opens an 'horizontal-or-vertical' pretty-printing box with indentation 2 as obtained with `open_hovbox 2`. For more details about pretty-printing boxes, see the various box opening functions `open_*box`.

* `@]`: close the most recently opened pretty-printing box.

* `@,`: output a 'cut' break hint, as with `print_cut()`.

* `@:`: output a 'space' break hint, as with `print_space()`.

* `@;`: output a 'full' break hint as with `print_break`. The `nspaces` and `offset` parameters of the break hint may be optionally specified with the following syntax: the `<` character, followed by an integer `nspaces` value, then an integer `offset`, and a closing `>` character. If no parameters are provided, the full break defaults to a 'space' break hint.

* `@.`: flush the pretty-printer and split the line, as with `print_newline()`.

* `@<n>`: print the following item as if it were of length `n`. Hence, `printf "@<0>%s" arg` prints `arg` as a zero length string. If `@<n>` is not followed by a conversion specification, then the following character of the format is printed as if it were of length `n`.

* `@{`: open a semantic tag. The name of the tag may be optionally specified with the following syntax: the `<` character, followed by an optional string specification, and the closing `>` character. The string specification is any character string that does not contain the closing character `>`'. If omitted, the tag name defaults to the empty string. For more details about semantic tags, see the functions `Format.open_stag[28.21]` and `Format.close_stag[28.21]`.

* `@}`: close the most recently opened semantic tag.

* `@?:` flush the pretty-printer as with `print_flush()`. This is equivalent to the conversion `%!`.

* `@\n`: force a newline, as with `force_newline()`, not the normal way of pretty-printing, you should prefer using break hints inside a vertical pretty-printing box.
'a', 'b') handler is a handler record with three fields – `retc` is the value handler, `exnc` handles exceptions, and `effc` handles the effects performed by the computation enclosed by the handler.

```h
val continue_with : ('c, 'a) continuation ->
                  'c -> ('a, 'b) handler -> 'b
```

`continue_with` k v h resumes the continuation k with value v with the handler h.

**Raises** `Continuation_already_resumed` if the continuation has already been resumed.

```h
val discontinue_with :
    ('c, 'a) continuation ->
    exn -> ('a, 'b) handler -> 'b
```

`discontinue_with` k e h resumes the continuation k by raising the exception e with the handler h.

**Raises** `Continuation_already_resumed` if the continuation has already been resumed.

```h
val discontinue_with_backtrace :
    ('a, 'b) continuation ->
    exn -> Printexc/raw_backtrace -> ('b, 'c) handler -> 'c
```

`discontinue_with` k e bt h resumes the continuation k by raising the exception e with the handler h using the raw backtrace bt as the origin of the exception.

**Raises** `Continuation_already_resumed` if the continuation has already been resumed.

```h
val get_callstack : ('a, 'b) continuation -> int -> Printexc/raw_backtrace
```

`get_callstack` c n returns a description of the top of the call stack on the continuation c, with at most n entries.

end

## 29.19 Module Either: Either type.

Either is the simplest and most generic sum/variant type: a value of ('a, 'b) Either.t is either a Left (v : 'a) or a Right (v : 'b).

It is a natural choice in the API of generic functions where values could fall in two different cases, possibly at different types, without assigning a specific meaning to what each case should be.

For example:

```h
List-partition_map:
    ('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list
```

If you are looking for a parametrized type where one alternative means success and the other means failure, you should use the more specific type `Result.t[29.51]`.

**Since:** 4.12
Note: To prevent the interpretation of a `@` character as a pretty-printing indication, escape it with a `%` character. Old quotation mode `@@` is deprecated since it is not compatible with formatted input interpretation of character '@'.

Example: `printf "@[%s@ %d@]@." "x =" 1` is equivalent to `open_box(); print_string "x ="; print_space(); print_int 1; close_box(); print_newline()`. It prints `x = 1` within a pretty-printing 'horizontal-or-vertical' box.

**val printf: ('a, formatter, unit) format -> 'a**

Same as `fprintf` above, but output on `get_std_formatter()`.

It is defined similarly to `fun fmt -> fprintf(get_std_formatter()) fmt` but delays calling `get_std_formatter` until after the final argument required by the `format` is received. When used with multiple domains, the output from the domains will be interleaved with each other at points where the formatter is flushed, such as with `Format.print_flush[28.21]`.

**val eprintf: ('a, formatter, unit) format -> 'a**

Same as `fprintf` above, but output on `get_err_formatter()`.

It is defined similarly to `fun fmt -> fprintf(get_err_formatter()) fmt` but delays calling `get_err_formatter` until after the final argument required by the `format` is received. When used with multiple domains, the output from the domains will be interleaved with each other at points where the formatter is flushed, such as with `Format.print_flush[28.21]`.

**val sprintf: ('a, unit, string) format -> 'a**

Same as `printf` above, but instead of printing on a formatter, returns a string containing the result of formatting the arguments. Note that the pretty-printer queue is flushed at the end of each call to `sprintf`. Note that if your format string contains a `%a`, you should use `asprintf`.

In case of multiple and related calls to `sprintf` to output material on a single string, you should consider using `fprintf` with the predefined formatter `str_formatter` and call `flush_str_formatter()` to get the final result.

Alternatively, you can use `Format.fprintf` with a formatter writing to a buffer of your own: flushing the formatter and the buffer at the end of pretty-printing returns the desired string.

**val asprintf: ('a, formatter, unit, string) format4 -> 'a**

Same as `printf` above, but instead of printing on a formatter, returns a string containing the result of formatting the arguments. The type of `asprintf` is general enough to interact nicely with `%a` conversions.

**Since: 4.01**

**val dprintf: ('a, formatter, unit, formatter -> unit) format4 -> 'a**

Same as `Format.fprintf[28.21]`, except the formatter is the last argument. `dprintf "..."` `abc` is a function of type `formatter -> unit` which can be given to a format specifier `%t`.

This can be used as a replacement for `Format.asprintf[28.21]` to delay formatting decisions. Using the string returned by `Format.asprintf[28.21]` in a formatting context forces formatting decisions to be taken in isolation, and the final string may be created
```h
type ('a, 'b) t =
```

| Left of 'a

| Right of 'b

A value of ('a, 'b) Either.t contains either a value of 'a or a value of 'b

```h
val left : 'a -> ('a, 'b) t
```

left v is Left v.

```h
val right : 'b -> ('a, 'b) t
```

right v is Right v.

```h
val is_left : ('a, 'b) t -> bool
```

is_left (Left v) is true, is_left (Right v) is false.

```h
val is_right : ('a, 'b) t -> bool
```

is_right (Left v) is false, is_right (Right v) is true.

```h
val get_left : ('a, 'b) t -> 'a
```

get_left e is v if e is Left v and raise otherwise.

Since: 5.4

Raises Invalid_argument if e is Right _.

```h
val get_right : ('a, 'b) t -> 'b
```

get_right e is v if e is Right v and raise otherwise.

Since: 5.4

Raises Invalid_argument if e is Left _.

```h
val find_left : ('a, 'b) t -> 'a option
```

find_left (Left v) is Some v, find_left (Right_) is None

```h
val find_right : ('a, 'b) t -> 'b option
```

find_right (Right v) is Some v, find_right (Left_) is None

```h
val map_left : ('a1 -> 'a2) -> ('a1, 'b) t -> ('a2, 'b) t
```

map_left f e is Left (f v) if e is Left v and e if e is Right _.

```h
val map_right : ('b1 -> 'b2) -> ('a, 'b1) t -> ('a, 'b2) t
```

map_right f e is Right (f v) if e is Right v and e if e is Left _.

```h
val map :
```

left: ('a1 -> 'a2) ->

right: ('b1 -> 'b2) -> ('a1, 'b1) t -> ('a2, 'b2) t
prematurely. `Format.dprintf[28.21]` allows delay of formatting decisions until the final
formatting context is known. For example:

```perl
let t = Format.dprintf "%i@ %i@ %i" 1 2 3 in
...
Format其中一个`printf "@[<v>%t@]" t`

**Since: 4.08**

`val ifprintf : formatter -> ('a, formatter, unit) format -> 'a`

Same as `fprintf` above, but does not print anything. Useful to ignore some material when
conditionally printing.

**Since: 3.10**

Formatted Pretty-Printing with continuations.

`val kfprintf :`
`    (formatter -> 'a) ->`
`    formatter -> ('b, formatter, unit, 'a) format4 -> 'b`

Same as `fprintf` above, but instead of returning immediately, passes the formatter to its first
argument at the end of printing.

`val kdprintf :`
`    ((formatter -> unit) -> 'a) ->`
`    ('b, formatter, unit, 'a) format4 -> 'b`

Same as `Format.dprintf[28.21]` above, but instead of returning immediately, passes the
suspended printer to its first argument at the end of printing.

**Since: 4.08**

`val ikfprintf :`
`    (formatter -> 'a) ->`
`    formatter -> ('b, formatter, unit, 'a) format4 -> 'b`

Same as `kfprintf` above, but does not print anything. Useful to ignore some material when
conditionally printing.

**Since: 3.12**

`val ksprintf : (string -> 'a) -> ('b, unit, string, 'a) format4 -> 'b`

Same as `sprintf` above, but instead of returning the string, passes it to the first argument.

`val kasprintf : (string -> 'a) -> ('b, formatter, unit, 'a) format4 -> 'b`

Same as `asprintf` above, but instead of returning the string, passes it to the first argument.

**Since: 4.03**
map ~left ~right (Left v) is Left (left v), map ~left ~right (Right v) is Right
(right v).

val fold : left:('a -> 'c) -> right:('b -> 'c) -> ('a, 'b) t -> 'c
fold ~left ~right (Left v) is left v, and fold ~left ~right (Right v) is right v.

val retract : ('a, 'a) t -> 'a
retract (Left v) is v, and retract (Right v) is v.
Since: 5.4

val iter : left:('a -> unit) -> right:('b -> unit) -> ('a, 'b) t -> unit
iter ~left ~right (Left v) is left v, and iter ~left ~right (Right v) is right v.

val for_all : left:('a -> bool) -> right:('b -> bool) -> ('a, 'b) t -> bool
for_all ~left ~right (Left v) is left v, and for_all ~left ~right (Right v) is
right v.

val equal :
left:('a -> 'a -> bool) ->
right:('b -> 'b -> bool) -> ('a, 'b) t -> ('a, 'b) t -> bool

equal ~left ~right e0 e1 tests equality of e0 and e1 using left and right to
respectively compare values wrapped by Left _ and Right _.

val compare :
left:('a -> 'a -> int) ->
right:('b -> 'b -> int) -> ('a, 'b) t -> ('a, 'b) t -> int

compare ~left ~right e0 e1 totally orders e0 and e1 using left and right to
respectively compare values wrapped by Left _ and Right _. Left _ values are smaller
than Right _ values.

## 29.20 Module Ephemeron : Ephemerons and weak hash tables.

Ephemerons and weak hash tables are useful when one wants to cache or memorize the computation of a function, as long as the arguments and the function are used, without creating memory leaks by continuously keeping old computation results that are not useful anymore because one argument or the function is freed. An implementation using `Hashtbl.t[29.26]` is not suitable because all associations would keep the arguments and the result in memory.

Ephemerons can also be used for "adding" a field to an arbitrary boxed OCaml value: you can
attach some information to a value created by an external library without memory leaks.

Ephemerons hold some keys and one or no data. They are all boxed OCaml values. The keys of an ephemeron have the same behavior as weak pointers according to the garbage collector. In fact OCaml weak pointers are implemented as ephemerons without data.
Examples

A few warmup examples to get an idea of how Format is used.

We have a list `l` of pairs `(int * bool)`, which the `t LEVEL` prints for us:

```c
# let l = List.init 20 (fun n -> n, n mod 2 = 0)
val l : (int * bool) list =
  [(0, true); (1, false); (2, true); (3, false); (4, true); (5, false);
   (6, true); (7, false); (8, true); (9, false); (10, true); (11, false);
   (12, true); (13, false); (14, true); (15, false); (16, true); (17, false);
   (18, true); (19, false)]
```

If we want to print it ourself without the toplevel magic, we can try this:

```c
# let pp_pair out (x,y) = Format.fprintf out "%d, %b" x y
val pp_pair : Format formatter -> int * bool -> unit = <fun>
# Formatprintf "l: [[<hov>%a@]]@."
  Format.(pp_print_list ~pp_sep:(fun out () -> fprintf out ";@ ") pp_pair) l
  l: [(0, true); (1, false); (2, true); (3, false); (4, true); (5, false);
      (6, true); (7, false); (8, true); (9, false); (10, true); (11, false);
      (12, true); (13, false); (14, true); (15, false); (16, true);
      (17, false); (18, true); (19, false)]
```

What this does, briefly, is:

* `pp_pair` prints a pair `bool*int` surrounded in `"(" ")"`. It takes a formatter (into which formatting happens), and the pair itself. When printing is done it returns `()`.

* `Formatprintf "l = [[<hov>%a@]]@." ... l` is like `printf`, but with additional formatting instructions (denoted with `"@"`). The pair `"@<hov>"` and `"@"` is a "horizontal-or-vertical box".

* `"@."` ends formatting with a newline. It is similar to `"\n"` but is also aware of the `Format formatter`'s state. Do not use `"\n"` with `Format`.

* `"%a"` is a formatting instruction, like `"%d"` or `"%s"` for `printf`. However, where `"%d"` prints an integer and `"%s"` prints a string, `"%a"` takes a printer (of type `Format formatter -> 'a -> unit`) and a value (of type `'a`) and applies the printer to the value. This is key to compositionality of printers.

* We build a list printer using `Format.pp_print_list ~pp_sep:(...) pp_pair`. `pp_print_list` takes an element printer and returns a list printer. The `?pp_sep` optional argument, if provided, is called in between each element to print a separator.

* Here, for a separator, we use `(fun out () -> Format.fprintf out ";@ ")`. It prints `";"`, and then `"@ "` which is a breaking space (either it prints `" "`, or it prints a newline if the box is about to overflow). This `"@ "` is responsible for the list printing splitting into several lines.
The keys and data of an ephemeron are said to be full if they point to a value, or empty if the value has never been set, has been unset, or was erased by the GC. In the function that accesses the keys or data these two states are represented by the *option type*.

The data is considered by the garbage collector alive if all the full keys are alive and if the ephemeron is alive. When one of the keys is not considered alive anymore by the GC, the data is emptied from the ephemeron. The data could be alive for another reason and in that case the GC will not free it, but the ephemeron will not hold the data anymore.

The ephemerons complicate the notion of liveness of values, because it is not anymore an equivalence with the reachability from root value by usual pointers (not weak and not ephemerons). With ephemerons the notion of liveness is constructed by the least fixpoint of: A value is alive if:

* it is a root value

* it is reachable from alive value by usual pointers

* it is the data of an alive ephemeron with all its full keys alive

**Notes:**

* All the types defined in this module cannot be marshaled using `output_value[28.2]` or the functions of the ` Marshal[29.36]` module.

Ephemerons are defined in a language agnostic way in this paper: B. Hayes, Ephemerons: A New Finalization Mechanism, OOPSLA’97

**Since:** 4.03

**Alert unsynchronized_access.** Unsynchronized accesses to weak hash tables are a programming error.

## Unsynchronized accesses

Unsynchronized accesses to a weak hash table may lead to an invalid weak hash table state. Thus, concurrent accesses to a weak hash table must be synchronized (for instance with a `Mutex.t[29.38]`).

```python
module type S =
sig
```

Propose the same interface as usual hash table. However since the bindings are weak, even if `mem h k` is true, a subsequent `find h k` may raise `Not_found` because the garbage collector can run between the two.

```python
type key
type !'a t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
```
If we omit `@`, we get an ugly single-line print:

```python
# Formateer dit: @[<hov>%a@]]@."
Format.(pp_print_list ~pp_sep:(fun out () -> fprintf out "; ") pp_pair) 1
1: [(0, true); (1, false); (2, true); (* ... *); (18, true); (19, false)]
- : unit = ()
```

Generally, it is good practice to define custom printers for important types in your program. If, for example, you were to define basic geometry types like so:

```python
type point = {
    x: float;
    y: float;
}

type rectangle = {
    ll: point; (* lower left *)
    ur: point; (* upper right *)
}
```

For debugging purpose, or to display information in logs, or on the console, it would be convenient to define printers for these types. Here is an example of to do it. Note that `%.3f` is a `float` printer up to 3 digits of precision after the dot; `%f` would print as many digits as required, which is somewhat verbose; `%h` is an hexadecimal float printer.

```python
let pp_point out (p:point) =
    Format.fprintf out "{{ @[x=%.3f;@ y=%.3f@] }}" p.x p.y

let pprectangle out (r:rectangle) =
    Format.fprintf out "{{ @[ll=%a;@ ur=%a@] }}"
    pp_point r.ll pp_point r.ur
```

In the `.mli` file, we could have:

```python
val pp_point : Format formatter -> point -> unit

val pprectangle : Format formatter -> rectangle -> unit
```

These printers can now be used with `%a` inside other printers.

```python
# Formateer dit: %a@."
    (Format.pp_print_option pprectangle)
    (Some {ll={x=1.; y=2.}; ur={x=42.; y=500.12345}})
some rectangle: { l={ x=1.000; y=2.000 }; ur={ x=42.000; y=500.123 } }

# Formateer dit: %a@."
```
```hkl
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistic
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit
```

remove all dead bindings. Done automatically during automatic resizing.

```hkl
val stats_alive : 'a t -> Hashtbl.statistic
```

same as `Hashtbl.SeededS.stats[29.26]` but only count the alive bindings

end

The output signature of the functors `Ephemeron.K1.Make[29.20]` and `Ephemeron.K2.Make[29.20]`. These hash tables are weak in the keys. If all the keys of a binding are alive the binding is kept, but if one of the keys of the binding is dead then the binding is removed.

```hkl
module type SeededS =
sig
```

```hkl
type key

type !'a t

val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistic
```
(Format.pp_option pprectangle)
None
no rectangle:

See how we combine `pp_print_option` (option printer) and our newly defined rectangle printer, like we did with `pp_print_list` earlier.

For a more extensive tutorial, see

"Using the Format module"[https://caml.inria.fr/resources/doc/guides/format.en.html].

A final note: the `Format` module is a starting point. The OCaml ecosystem has libraries that makes formatting easier and more expressive, with more combinators, more concise names, etc. An example of such a library is `Fmt`[https://erratique.ch/software/fmt].

Automatic deriving of pretty-printers from type definitions is also possible, using `https://github.com/ocaml-ppx/ppx_deriving[ppx_deriving.show]` or similar ppx derivers.

## 28.22 Module Fun : Function manipulation.

Since: 4.08

### Combinators

val id : 'a -> 'a

`id` is the identity function. For any argument `x`, `id x` is `x`.

val const : 'a -> 'b -> 'a

`const c` is a function that always returns the value `c`. For any argument `x`, `(const c) x` is `c`.

val flip : ('a -> 'b -> 'c) -> 'b -> 'a -> 'c

`flip f` reverses the argument order of the binary function `f`. For any arguments `x` and `y`, `(flip f) x y` is `f y x`.

val negate : ('a -> bool) -> 'a -> bool

`negate p` is the negation of the predicate function `p`. For any argument `x`, `(negate p) x` is not (`p x`).

### Exception handling

val protect : finally:(unit -> unit) -> (unit -> 'a) -> 'a

`protect ~finally work` invokes `work()` and then `finally()` before `work()` returns with its value or an exception. In the latter case the exception is re-raised after `finally()`. If `finally()` raises an exception, then the exception `Fun.Finally_raised[28.22]` is raised instead.
```hkl
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
```

```hkl
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
```

```hkl
val of_seq : (key * 'a) Seq.t -> 'a t
```

```hkl
val clean : 'a t -> unit
```

remove all dead bindings. Done automatically during automatic resizing.

```hkl
val stats_alive : 'a t -> Hashtbl.statsistics
```

same as `Hashtbl.SeededS.stats[29.26]` but only count the alive bindings

```hkl
end
```

The output signature of the functors `Ephemeron.K1.MakeSeeded[29.20]` and `Ephemeron.K2.MakeSeeded[29.20]`.

```hkl
module K1 :
```

```hkl
sig
```

```hkl
type ('k, 'd) t
```

an ephemeron with one key

```hkl
val make : 'k -> 'd -> ('k, 'd) t
```

`Ephemeron.K1.make k d` creates an ephemeron with key `k` and data `d`.

```hkl
val query : ('k, 'd) t -> 'k -> 'd option
```

`Ephemeron.K1.query eph` key returns `Some x` (where `x` is the ephemeron's data) if key is physically equal to `eph`'s key, and `None` if `eph` is empty or key is not equal to `eph`'s key.

```hkl
module Make :
```

```hkl
functor (H : Hashtbl.HashedType) -> Ephemeron.S with type key = H.t
```

Functor building an implementation of a weak hash table

```hkl
module MakeSeeded :
```

```hkl
functor (H : Hashtbl.SeededHashedType) -> Ephemeron.SeededS with type key = H.t
```

Functor building an implementation of a weak hash table. The seed is similar to the one of `Hashtbl.MakeSeeded[29.26]`.

```hkl
module Bucket :
```

```hkl
sig
```

```hkl
type ('k, 'd) t
```

A bucket is a mutable "list" of ephemerons.
`protect` can be used to enforce local invariants whether `work()` returns normally or raises an exception. However, it does not protect against unexpected exceptions raised inside `finally()` such as `Out_of_memory[27.2]`, `Stack_overflow[27.2]`, or asynchronous exceptions raised by signal handlers (e.g. `Sys.Break[28.55]`).

Note: It is a *programming error* if other kinds of exceptions are raised by `finally`, as any exception raised in `work()` will be lost in the event of a `Fun.Finally_Raised[28.22]` exception. Therefore, one should make sure to handle those inside the `finally`.

### exception Finally_Raised of exn

`Finally_Raised exn` is raised by `protect ~finally work` when `finally` raises an exception `exn`. This exception denotes either an unexpected exception or a programming error. As a general rule, one should not catch a `Finally_Raised` exception except as part of a catch-all handler.

## 28.23 Module Gc: Memory management control and statistics; finalised values.

`type stat =`
```h
{ minor_words : float ;
    Number of words allocated in the minor heap since the program was started.
```

`promoted_words : float ;`
Number of words allocated in the minor heap that survived a minor collection and were moved to the major heap since the program was started.

`major_words : float ;`
Number of words allocated in the major heap, including the promoted words, since the program was started.

`minor_collections : int ;`
Number of minor collections since the program was started.

`major_collections : int ;`
Number of major collection cycles completed since the program was started.

`heap_words : int ;`
Total size of the major heap, in words.

`heap_chunk : int ;`
Number of contiguous pieces of memory that make up the major heap. This metrics is currently not available in OCaml 5: the field value is always 0.

`live_words : int ;`
val make : unit -> ('k, 'd) t

Create a new bucket.

val add : ('k, 'd) t -> 'k -> 'd -> unit

Add an ephemeron to the bucket.

val remove : ('k, 'd) t -> 'k -> unit

remove b k removes from b the most-recently added ephemeron with key k, or does
nothing if there is no such ephemeron.

val find : ('k, 'd) t -> 'k -> 'd option

Returns the data of the most-recently added ephemeron with the given key, or None if there is no such ephemeron.

val length : ('k, 'd) t -> int

Returns an upper bound on the length of the bucket.

val clear : ('k, 'd) t -> unit

Remove all ephemerons from the bucket.

end

end

Ephemerons with one key.

module K2 :

sig

type ('k1, 'k2, 'd) t

an ephemeron with two keys

val make : 'k1 -> 'k2 -> 'd -> ('k1, 'k2, 'd) t

Same as Ephemeron.K1.make[29.20]

val query : ('k1, 'k2, 'd) t -> 'k1 -> 'k2 -> 'd option

Same as Ephemeron.K1.query[29.20]

module Make :

functor (H1 : Hashtbl.HashedType) -> functor (H2 : Hashtbl.HashedType) ->

Ephemeron.S with type key = H1.t * H2.t

Functor building an implementation of a weak hash table

module MakeSeeded :

functor (H1 : Hashtbl.SeededHashedType) -> functor (H2 : Hashtbl.SeededHashedType)

-> Ephemeron.SeededS with type key = H1.t * H2.t
Number of words of live data in the major heap, including the header words.

Note that "live" words refers to every word in the major heap that isn't currently known to be collectable, which includes words that have become unreachable by the program after the start of the previous gc cycle. It is typically much simpler and more predictable to call `Gc.full_major[28.23]` (or `Gc.compact[28.23]`) then computing gc stats, as then "live" words has the simple meaning of "reachable by the program". One caveat is that a single call to `Gc.full_major[28.23]` will not reclaim values that have a finaliser from `Gcoppise[28.23]` (this does not apply to `Gcoppise_last[28.23]`). If this caveat matters, simply call `Gc.full_major[28.23]` twice instead of once.

live_blocks : int ;

Number of live blocks in the major heap.

See `live_words` for a caveat about what "live" means.

free_words : int ;

Number of words in the free list.

free_blocks : int ;

Number of blocks in the free list. This metrics is currently not available in OCaml 5: the field value is always 0.

largest_free : int ;

Size (in words) of the largest block in the free list. This metrics is currently not available in OCaml 5: the field value is always 0.

fragments : int ;

Number of wasted words due to fragmentation. These are 1-words free blocks placed between two live blocks. They are not available for allocation.

compactions : int ;

Number of heap compactions since the program was started.

top_heap_words : int ;

Maximum size reached by the major heap, in words.

stack_size : int ;

Current size of the stack, in words. This metrics is currently not available in OCaml 5: the field value is always 0.

Since: 3.12

forced_major_collections : int ;

Number of forced full major collections completed since the program was started.

Since: 4.12

}
Functor building an implementation of a weak hash table. The seed is similar to the one of `Hashtbl.MakeSeeded[29.26]`.

module Bucket :

sig

type ('k1, 'k2, 'd) t

A bucket is a mutable "list" of ephemerons.

val make : unit -> ('k1, 'k2, 'd) t

Create a new bucket.

val add : ('k1, 'k2, 'd) t -> 'k1 -> 'k2 -> 'd -> unit

Add an ephemeron to the bucket.

val remove : ('k1, 'k2, 'd) t -> 'k1 -> 'k2 -> unit

remove b k1 k2 removes from b the most-recently added ephemeron with keys k1 and k2, or does nothing if there is no such ephemeron.

val find : ('k1, 'k2, 'd) t -> 'k1 -> 'k2 -> 'd option

Returns the data of the most-recently added ephemeron with the given keys, or `None` if there is no such ephemeron.

val length : ('k1, 'k2, 'd) t -> int

Returns an upper bound on the length of the bucket.

val clear : ('k1, 'k2, 'd) t -> unit

Remove all ephemerons from the bucket.

end

end

Ephemerons with two keys.

module Kn :

sig

type ('k, 'd) t

an ephemeron with an arbitrary number of keys of the same type

val make : 'k array -> 'd -> ('k, 'd) t

Same as `Ephemeron.K1.make[29.20]`

val query : ('k, 'd) t -> 'k array -> 'd option

Same as `Ephemeron.K1.query[29.20]`