{"name":"core/vec.nu","source":"// stdlib/core/vec.nu — owned growable Vec[A]\n//\n// Vec[A] is an opaque generic handle around a heap-allocated control\n// block {data, len, cap}. The handle is passed by value; all mutations\n// go through the heap pointer, so the caller's handle stays valid\n// across pushes (even when the buffer is reallocated). Aliasing\n// behaviour mirrors String — two Vec handles pointing at the same\n// buffer see each other's mutations.\n//\n// The type parameter A is *phantom* — the control block layout does\n// not depend on A, only element size (`Z A`) does. Mixing Vec[i] and\n// Vec[s] through type coercion is undefined at runtime; the compiler\n// keeps them distinct by mangling `%Vec__i64` vs `%Vec__str`.\n//\n// Control block layout (3 × i64 = 24 bytes, accessed via nurl_vctl_get/_set):\n//   word 0: data pointer (ptrtoint'd to i64; 0 when no buffer allocated)\n//   word 1: len\n//   word 2: cap\n//\n// Ownership:\n//   vec_new / vec_with_cap → an owned Vec, dropped with its elements by\n//   its owner at scope exit (docs/MEMORY.md §7.6). `vec_free` releases it\n//   early; `vec_free_with` lends each element to a closure first.\n//\n// The type-var name is `A` (not `T`) because the boolean literal `T`\n// collides with whole-identifier substitution at monomorphisation time.\n//\n// API:\n//   ( vec_new [A] )                → ( Vec A )   empty, no alloc\n//   ( vec_with_cap [A] n )         → ( Vec A )   preallocated\n//   ( vec_borrow_raw [A] p n )     → ( Vec A )   BORROWED view of p[0..n):\n//                                                reads see the caller's\n//                                                buffer, the first growth\n//                                                detaches into an owned\n//                                                copy (copy-on-write), and\n//                                                vec_free releases only the\n//                                                handle — never p. Caller\n//                                                keeps p alive and stable\n//                                                for as long as the view\n//                                                is read. Element writes\n//                                                (vec_set/swap/…) before a\n//                                                detach go THROUGH to p.\n//   ( vec_borrow_into [A] v p n )  → v          re-point an EXISTING handle\n//                                                (e.g. a struct field) at\n//                                                p[0..n) as a view, freeing\n//                                                what it owned\n//   ( vec_zeroed [A] n )           → ( Vec A )   n zero-filled elements,\n//                                                len == n, one calloc\n//   ( vec_unstash [A] kind n )     → ( Vec A )   an empty Vec from the\n//                                                per-thread stash `kind`,\n//                                                with the buffer it had;\n//                                                vec_with_cap n on a miss\n//   ( vec_stash [A] kind v max )   → v          drop v's elements and park\n//                                                it, buffer and all, for\n//                                                the next vec_unstash of\n//                                                `kind` (see \"Recycling\")\n//   ( vec_len [A] v )              → i          current length\n//   ( vec_cap [A] v )              → i          current capacity\n//   ( vec_is_empty [A] v )         → b          len == 0\n//   ( vec_data [A] v )             → *A         borrowed raw pointer\n//   ( vec_get [A] v i )            → ? A        None if idx out of range\n//   ( vec_set [A] v i x )          → b          drops the old element; F if idx out of range\n//   ( vec_push [A] v x )           → v          grows buffer if needed\n//   ( vec_pop [A] v )              → ? A        None if empty\n//   ( vec_insert [A] v idx x )     → b          F if idx out of range; idx == len → push\n//   ( vec_remove [A] v idx )       → ? A        None if idx out of range\n//   ( vec_clear [A] v )            → v          drops the elements, len=0, keeps cap\n//   ( vec_truncate [A] v n )       → b          keep the first n, drop the rest\n//   ( vec_set_len [A] v n )        → b          commit raw-pointer writes\n//                                                up to index n; F when n\n//                                                is negative or > current\n//                                                cap (no-op then). Used\n//                                                by FFI bridges that fill\n//                                                a Vec via vec_data + the\n//                                                runtime (TCP, file IO,\n//                                                Vec[u]-backed crypto).\n//   ( vec_swap [A] v i j )         → b          swaps two slots\n//   ( vec_retain [A] v keep )      → v          keep : (@ b A) — drop the\n//                                                rest, in place\n//   ( vec_put_back [A] v i x )     → v          x, read out of slot i and\n//                                                updated, goes back\n//   ( vec_reverse [A] v )          → v          in-place reverse\n//   ( vec_reserve [A] v n )        → v          ensure cap ≥ len + n\n//   ( vec_resize_zeroed [A] v n )  → b          set len to exactly n;\n//                                                a longer n zero-fills the\n//                                                new tail in one memset\n//   ( vec_shrink_to_fit [A] v )    → v          release unused capacity\n//   ( vec_extend [A] dst src )     → v          copies of src's elements onto\n//                                                dst (deep for owned elements)\n//   ( vec_append [A] dst src )     → v          MOVE every element of src onto\n//                                                dst; src is consumed (any A)\n//\n//   Equality (closure-based, mirrors HashMap eq_fn convention):\n//   ( vec_contains [A] v target eq_fn ) → b     eq_fn : (@ b A A)\n//   ( vec_index_of [A] v target eq_fn ) → ? i   first index or None\n//   ( vec_eq [A] a b eq_fn )            → b     element-wise equal lengths + eq_fn\n//   ( vec_free [A] v )             → v          release buffer; call once\n//   ( vec_free_with [A] v drop )   → v          drop : (@ v A) — call drop\n//                                                per element in [0..len)\n//                                                before releasing buffer.\n//                                                Use for Vec[String] etc.\n//\n//   Higher-order (element-preserving — caller still owns the Vec):\n//   ( vec_each [A] v f )           → v          f : (@ v A)\n//   ( vec_fold [A B] v init f )    → B          f : (@ B B A)\n//\n//   Higher-order (allocate a new Vec — same single-owner caveats apply\n//   to element types: bitwise-copy is safe for i/f/b/raw-s/slice, NOT\n//   for owned String/Vec/HashMap; for those build manually):\n//   ( vec_map [A B] v f )          → ( Vec B )  f : (@ B A)\n//   ( vec_filter [A] v pred )      → ( Vec A )  pred : (@ b A); trivial\n//   ( vec_filter_with [A] v pred clone ) → ( Vec A )  owned-safe filter —\n//                                                clone : (@ A A) clones\n//                                                every kept element\n//\n//   Higher-order (search — no allocation):\n//   ( vec_find [A] v pred )        → ? A        first match or None\n//   ( vec_any  [A] v pred )        → b          short-circuit\n//   ( vec_all  [A] v pred )        → b          short-circuit on first F\n//\n//   Clone (mirrors the vec_free / vec_free_with split):\n//   ( vec_clone [A] v )            → ( Vec A )  a copy owning copies of the\n//                                                elements (deep for String,\n//                                                Vec, owning structs)\n//   ( vec_clone_with [A] v clone ) → ( Vec A )  copy via clone : (@ A A)\n\n: Vec [A] { s ctl }\n\n// ── Internal helpers ────────────────────────────────────────────────\n\n@ __vec_data_raw s ctl → s {\n    ^ # s ( nurl_vctl_get ctl 0 )\n}\n\n@ __vec_len_raw s ctl → i {\n    ^ ( nurl_vctl_get ctl 1 )\n}\n\n@ __vec_cap_raw s ctl → i {\n    ^ ( nurl_vctl_get ctl 2 )\n}\n\n// A borrowed view (vec_borrow_raw) keeps cap == -1: the buffer is not\n// ours to grow, shrink or free. Every path that would touch the\n// allocation checks this first; readers never need to.\n@ __vec_is_borrowed s ctl → b {\n    ^ < ( __vec_cap_raw ctl ) 0\n}\n\n// ── Allocation sizes ────────────────────────────────────────────────\n// Every size the library allocates for a caller's count is checked: a\n// count whose byte size cannot be represented panics before anything is\n// allocated — a size that wrapped would hand back a tiny buffer that the\n// count then writes past. The checks sit on growth paths only.\n//\n//   ( alloc_size size n )              →  i   n * size, or the panic\n//   ( alloc_count_add a b )            →  i   a + b, or the panic\n//   ( alloc_grow_cap cap need )        →  i   doubled from cap until need fits\n//   ( alloc_grow_pow2 cap need first ) →  i   …a power of two, from `first`\n\n// Never return: defined ahead of their callers (the noreturn registry).\n@ __alloc_size_panic i size i n → v {\n    ( nurl_eprint `allocation too large: ` ) ( nurl_eprint_int n )\n    ( nurl_eprint ` items of ` ) ( nurl_eprint_int size )\n    ( nurl_eprintln ` bytes cannot be represented` )\n    ( nurl_panic `allocation size overflow` )\n}\n\n@ __alloc_count_panic i a i b → v {\n    ( nurl_eprint `allocation too large: ` ) ( nurl_eprint_int a )\n    ( nurl_eprint ` + ` ) ( nurl_eprint_int b )\n    ( nurl_eprintln ` items cannot be represented` )\n    ( nurl_panic `allocation size overflow` )\n}\n\n// The byte size of `n` items of `size` bytes each, or the panic: a\n// negative count, or a product past what a size can hold.\ninline @ alloc_size i size i n → i {\n    // (Both under 2^31: the product fits — no division on the common path.)\n    ? & & >= n 0 < n 2147483648 < size 2147483648 { ^ * size n } {}\n    ? | < n 0 & > size 0 > n / 9223372036854775807 size { ( __alloc_size_panic size n ) } {}\n    ^ * size n\n}\n\n// `a + b` for two counts (a length and what is added to it), or the panic.\ninline @ alloc_count_add i a i b → i {\n    ? | | < a 0 < b 0 > a - 9223372036854775807 b { ( __alloc_count_panic a b ) } {}\n    ^ + a b\n}\n\n// The capacity a growing buffer doubles to from `cap` (4 when empty)\n// until it holds `need` — `need` itself where doubling would overflow.\ninline @ alloc_grow_cap i cap i need → i {\n    : ~ i c ? > cap 0 cap 4\n    // (Up to 2^62 every doubling below `need` fits: one test, not one per\n    // doubling.)\n    ? > need 4611686018427387904 { ^ ? > c need c need } {}\n    ~ < c need { = c * c 2 }\n    ^ c\n}\n\n// …a power of two from `first` (a hash table's), or the panic when `need`\n// is past the largest one.\ninline @ alloc_grow_pow2 i cap i need i first → i {\n    ? > need 4611686018427387904 { ( __alloc_size_panic 1 need ) } {}\n    : ~ i c ? > cap 0 cap first\n    ~ < c need { = c * c 2 }\n    ^ c\n}\n\n// Grow the underlying buffer so that cap >= need. Uses nurl_realloc;\n// safe to call when the current data pointer is null (cap == 0).\n// (Callers test `cap < need` first: this is the slow path, and a call per\n// push / reserve / string seal that only found room cost 8 % of an HTTP\n// server's user time.)\n@ __vec_grow [A] s ctl i need → v {\n    : i cap ( __vec_cap_raw ctl )\n    ? < cap 0 {\n        // Borrowed view: the first growth DETACHES — copy the live\n        // elements into a fresh owned buffer and leave the source\n        // untouched. From here on this is an ordinary owned Vec.\n        : i len ( __vec_len_raw ctl )\n        : i new_cap ( alloc_grow_cap 4 ? > len need len need )\n        : s fresh ( nurl_alloc ( alloc_size Z A new_cap ) )\n        : i copy_bytes * Z A len\n        ? > copy_bytes 0 { ( nurl_memcpy fresh ( __vec_data_raw ctl ) copy_bytes ) } {}\n        ( nurl_vctl_set ctl 0 # i fresh )\n        ( nurl_vctl_set ctl 2 new_cap )\n        ^\n    } {}\n    ? < cap need {\n        // (Checked: a capacity past what memory can hold panics here,\n        // before anything is allocated — alloc_size.)\n        : i new_cap ( alloc_grow_cap cap need )\n        : s cur ( __vec_data_raw ctl )\n        : i bytes ( alloc_size Z A new_cap )\n        // If `cur` lives in the same alloc as ctl (the packed-string\n        // layout from string_from_bytes_packed — data sits at ctl+24),\n        // realloc() would walk into the middle of another malloc block\n        // and crash. Detect that, malloc-copy-out into a fresh buffer\n        // instead; the next free of this Vec then frees both blocks\n        // (the packed-aware vec_free below skips the in-ctl buffer).\n        : i ctl_end + # i ctl 24\n        ? & != 0 # i cur == # i cur ctl_end {\n            : s fresh ( nurl_alloc bytes )\n            : i len ( __vec_len_raw ctl )\n            : i copy_bytes * Z A len\n            ? > copy_bytes 0 { ( nurl_memcpy fresh cur copy_bytes ) } {}\n            ( nurl_vctl_set ctl 0 # i fresh )\n            ( nurl_vctl_set ctl 2 new_cap )\n        } {\n            ? == 0 # i cur {\n                // First growth: nurl_alloc, not realloc(NULL, n) — the\n                // runtime's small-allocation cache sits behind\n                // nurl_alloc/nurl_free, and a Vec's first buffer is the\n                // most recycled block shape there is.\n                : s fresh ( nurl_alloc bytes )\n                ( nurl_vctl_set ctl 0 # i fresh )\n                ( nurl_vctl_set ctl 2 new_cap )\n            } {\n                : s fresh ( nurl_realloc cur bytes )\n                ( nurl_vctl_set ctl 0 # i fresh )\n                ( nurl_vctl_set ctl 2 new_cap )\n            }\n        }\n    } {}\n}\n\n// ── Constructors ────────────────────────────────────────────────────\n\n@ vec_new [A] → ( Vec A ) {\n    : s ctl ( nurl_zalloc 24 )\n    ^ @ ( Vec A ) { ctl }\n}\n\n@ vec_with_cap [A] i n → ( Vec A ) {\n    : s ctl ( nurl_zalloc 24 )\n    : i want ? > n 0 n 0\n    ? > want 0 { ( __vec_grow [A] ctl want ) } {}\n    ^ @ ( Vec A ) { ctl }\n}\n\n// A BORROWED view of `p[0..n)`: a Vec handle whose data pointer is the\n// caller's buffer. Reads (`vec_len`, `vec_data`, `vec_get`, iteration,\n// `bytes_extend_bytes`, the socket writers …) work unchanged and see the\n// caller's bytes with no copy. The first operation that needs capacity\n// (`vec_push`, `vec_extend`, `vec_reserve`, …) detaches: it copies the\n// live elements into a fresh owned buffer and the handle becomes an\n// ordinary owned Vec (copy-on-write). `vec_free` on an undetached view\n// releases only the 24-byte handle, never `p`.\n//\n// The contract is the caller's: `p` must stay alive and unchanged for as\n// long as the view is read — the borrow checker cannot see through a\n// raw pointer. Element writes made through the view before it detaches\n// (`vec_set`, `vec_swap`, `vec_reverse`, raw `vec_data` stores) land in\n// `p`, exactly like two handles on one buffer do today.\n//\n// Why: the HTTP server's large-body path. A handler serving a\n// precomputed buffer (a static asset, an mmap, a cache entry) used to\n// pay a full copy of it into the response (`response_set_body_bytes`);\n// hyper's `Bytes::clone` is a refcount bump. With a view the response\n// body is the caller's buffer and the write path reads it in place.\n// `n <= 0` (or a null `p`) is an ordinary empty owned Vec.\n@ vec_borrow_raw [A] * A p i n → ( Vec A ) {\n    : s ctl ( nurl_zalloc 24 )\n    ( __vec_point_at ctl # i p n )\n    ^ @ ( Vec A ) { ctl }\n}\n\n// Re-point an EXISTING handle at `p[0..n)` as a borrowed view, releasing\n// whatever buffer it owned. This is how a Vec that lives in a struct\n// field becomes a view: struct values travel by copy, so assigning a\n// fresh handle into `. r body` inside a helper would change only the\n// helper's copy and leave the caller holding a freed one — the control\n// block is the shared thing, so it is the control block that changes.\n@ vec_borrow_into [A] ( Vec A ) v * A p i n → v {\n    : s ctl . v ctl\n    : s data ( __vec_data_raw ctl )\n    : i ctl_end + # i ctl 24\n    ? & ! ( __vec_is_borrowed ctl ) & != 0 # i data != # i data ctl_end { ( nurl_free data ) } {}\n    ( __vec_point_at ctl # i p n )\n}\n\n// Write a borrowed view into a control block; an empty or null range is\n// the empty owned state (data 0, len 0, cap 0).\n@ __vec_point_at s ctl i p i n → v {\n    ? & > n 0 != 0 p {\n        ( nurl_vctl_set ctl 0 p )\n        ( nurl_vctl_set ctl 1 n )\n        ( nurl_vctl_set ctl 2 -1 )\n    } {\n        ( nurl_vctl_set ctl 0 0 )\n        ( nurl_vctl_set ctl 1 0 )\n        ( nurl_vctl_set ctl 2 0 )\n    }\n}\n\n// ── Recycling ───────────────────────────────────────────────────────\n// A per-thread stash of EMPTY control blocks that keep their buffers\n// (stdlib/runtime_core.c §9a′), for objects built and dropped at a steady\n// rate — the HTTP server's response header Vec and body, the router's\n// Params. `vec_stash` empties a Vec (its elements are dropped) and parks\n// it; the next `vec_unstash` of the same kind on that thread takes it back\n// with its capacity, so a steady stream of same-shaped objects stops\n// allocating. It is a cache, not a container: a kind holds a bounded\n// number of blocks, and one it refuses — kind full, buffer past `max`\n// bytes, NURL_STASH=0 — is released as dropping the Vec releases it.\n// Elements never sit in the stash, so its kinds need not agree on the\n// element type, only on what their users expect back (an empty Vec).\n//\n// Kinds in use (0..7): 0 HttpResponse headers, 1 HttpResponse body,\n// 2 header Strings (string_stash), 3 router Params.\n& `libc` @ nurl_stash_pop i kind → s\n\n& `libc` @ nurl_stash_push i kind s ctl → i\n\n// Grow the buffer behind a raw control block to hold `need` elements —\n// vec_reserve for library code that works on the block without binding\n// a handle (core/string.nu's recycled-String paths).\n@ _vec_ctl_reserve [A] s ctl i need → v {\n    ? < ( __vec_cap_raw ctl ) need { ( __vec_grow [A] ctl need ) } {}\n}\n\n@ vec_unstash [A] i kind i n → ( Vec A ) {\n    : s ctl ( nurl_stash_pop kind )\n    ? == # i ctl 0 { ^ ( vec_with_cap [A] n ) } {}\n    ? < ( __vec_cap_raw ctl ) n { ( __vec_grow [A] ctl n ) } {}\n    ^ @ ( Vec A ) { ctl }\n}\n\n@ vec_stash [A] i kind sink ( Vec A ) v i max → v {\n    : s ctl . v ctl\n    : s data ( __vec_data_raw ctl )\n    // A packed String buffer (data inside the control block) stays with\n    // its block's ordinary release.\n    ? & != 0 # i data == # i data + # i ctl 24 { ^ } {}\n    ? ( __vec_is_borrowed ctl ) {\n        // A view owns no buffer: it parks as the empty owned state.\n        ( __vec_point_at ctl 0 0 )\n    } {\n        ( vec_clear [A] v )\n        ? > ( alloc_size Z A ( __vec_cap_raw ctl ) ) max {\n            ( nurl_free data )\n            ( __vec_point_at ctl 0 0 )\n        } {}\n    }\n    ? != 0 ( nurl_stash_push kind ctl ) { ( mem_forget v ) } {}\n}\n\n// `n` zero-filled elements in ONE allocation, with `len` already at n —\n// the calloc-shaped sibling of `vec_with_cap`. Reaching the same state\n// by pushing a zero n times costs n bounds checks, n length stores and\n// log2(n) reallocations, and it writes every page; this hands the size\n// straight to `nurl_zalloc`, so a large buffer arrives as untouched\n// zero pages from the kernel and costs nothing until it is written.\n//\n// Bitwise zero has to be a valid A — the same trivial-element-type rule\n// as `vec_extend` / `vec_map`. `n <= 0` is an empty Vec with no buffer.\n@ vec_zeroed [A] i n → ( Vec A ) {\n    : s ctl ( nurl_zalloc 24 )\n    ? > n 0 {\n        : s data ( nurl_zalloc ( alloc_size Z A n ) )\n        ( nurl_vctl_set ctl 0 # i data )\n        ( nurl_vctl_set ctl 1 n )\n        ( nurl_vctl_set ctl 2 n )\n    } {}\n    ^ @ ( Vec A ) { ctl }\n}\n\n// ── Inspectors ──────────────────────────────────────────────────────\n\n@ vec_len [A] ( Vec A ) v → i {\n    ^ ( __vec_len_raw . v ctl )\n}\n\n// For a borrowed view the capacity is its length: nothing beyond the\n// live elements may be written without detaching.\n@ vec_cap [A] ( Vec A ) v → i {\n    : s ctl . v ctl\n    ? ( __vec_is_borrowed ctl ) { ^ ( __vec_len_raw ctl ) } {}\n    ^ ( __vec_cap_raw ctl )\n}\n\n@ vec_is_empty [A] ( Vec A ) v → b {\n    ^ == ( __vec_len_raw . v ctl ) 0\n}\n\n@ vec_data [A] ( Vec A ) v → *A {\n    ^ # *A ( nurl_peek . v ctl 0 )\n}\n\n// ── Access ──────────────────────────────────────────────────────────\n\n@ vec_get [A] ( Vec A ) v i idx → ?A {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? >= # u64 idx # u64 len { ^ @ ?A { F # A 0 } } {}\n    : *A data # *A ( nurl_vctl_data ctl )\n    : A x . data idx\n    ^ @ ?A { T x }\n}\n\n// One panic carrying the whole story — \"index out of bounds: the index is\n// 5 but the length is 2\" — printed once, and what a recover frame sees\n// (runtime_core.c; noreturn, so the check stays a loop exit).\n& `c` @ nurl_panic_index i idx i len in s what in s at → v\n\n// Never returns: defined ahead of its callers so they are compiled knowing\n// that (the noreturn registry), and the optimiser can treat the check as a\n// loop exit.\n@ __vec_index_panic i idx i len → v {\n    ( nurl_panic_index idx len `length` `` )\n}\n\n// …naming the caller's location, `at` (\"file:line:col\").\n@ __vec_index_panic_at i idx i len s at → v {\n    ( nurl_panic_index idx len `length` at )\n}\n\n// The element at `idx` — the indexing a loop over a Vec wants, with no\n// raw pointer: a bounds check (which the optimiser lifts out of a counted\n// loop) and a panic naming the index and the length when it fails. Like\n// vec_get's payload, an owning element comes back as a borrow of the Vec.\n@ vec_at [A] ( Vec A ) v i idx → A {\n    ^ ( vec_at_loc [A] v idx `` )\n}\n\n// What every `( vec_at [T] v i )` call compiles to: vec_at, with the\n// CALLER's location — \"main.nu:7:24\", passed by nurlc as a constant — so\n// an index past the end names the line that asked for it (\"\" names none).\n// Inlined, the constant costs nothing until the check fails.\n@ vec_at_loc [A] ( Vec A ) v i idx s at → A {\n    // Both loads ahead of the check: on every path through the function,\n    // so the optimiser can lift them, and the check with them, out of a\n    // loop.\n    : s ctl . v ctl\n    : *A data # *A ( nurl_vctl_data ctl )\n    : i len ( __vec_len_raw ctl )\n    ? >= # u64 idx # u64 len { ( __vec_index_panic_at idx len at ) } {}\n    ^ . data idx\n}\n\n// Store `x` at `idx` (dropping the element it replaces); panics like vec_at\n// when `idx` is out of range — vec_set's bounds check without the `b` to\n// thread through when an out-of-range index is a bug, not a case.\n@ vec_put [A] ( Vec A ) v i idx A x → v {\n    ( vec_put_loc [A] v idx x `` )\n}\n\n// What every `( vec_put [T] v i x )` call compiles to (see vec_at_loc).\n@ vec_put_loc [A] ( Vec A ) v i idx A x s at → v {\n    : s ctl . v ctl\n    : *A data # *A ( nurl_vctl_data ctl )\n    : i len ( __vec_len_raw ctl )\n    ? >= # u64 idx # u64 len { ( __vec_index_panic_at idx len at ) } {}\n    : A old . data idx\n    ( mem_take old )\n    = . data idx x\n}\n\n// Run `f` on the element at `idx` in place: nothing is copied, moved or\n// dropped, so a large record or one that owns buffers is changed where it\n// lives. F, and `f` does not run, when `idx` is out of range. `v` is taken\n// `inout`, so a closure that could reach `v` (capturing it, or the record\n// it is a field of) is rejected: nothing can grow or shrink the Vec under\n// the element `f` is holding.\n@ vec_update [A] inout ( Vec A ) v i idx ( @ v inout A ) f → b {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? >= # u64 idx # u64 len { ^ F } {}\n    : ~ * A data # *A ( nurl_vctl_data ctl )\n    ( f . data idx )\n    ^ T\n}\n\n// vec_update with a result: `f`'s, or `none` (and `f` does not run) when\n// `idx` is out of range.\n@ vec_apply [A R] inout ( Vec A ) v i idx R none ( @ R inout A ) f → R {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? >= # u64 idx # u64 len { ^ none } {}\n    : ~ * A data # *A ( nurl_vctl_data ctl )\n    ^ ( f . data idx )\n}\n\n// The element `x` replaces is dropped (vec_replace hands it back instead).\n@ vec_set [A] ( Vec A ) v i idx A x → b {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? >= # u64 idx # u64 len { ^ F } {}\n    : *A data # *A ( nurl_vctl_data ctl )\n    : A old . data idx\n    ( mem_take old )\n    = . data idx x\n    ^ T\n}\n\n// Put `x` at `idx` and hand the element it replaces back, owned — bind it\n// and it is dropped with the binding. `F` (and `x` is not stored) when\n// `idx` is out of range.\n@ vec_replace [A] ( Vec A ) v i idx A x → ?A {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? >= # u64 idx # u64 len { ^ @ ?A { F # A 0 } } {}\n    : *A data # *A ( nurl_vctl_data ctl )\n    : A old . data idx\n    ( mem_take old )  // the element leaves the container\n    = . data idx x\n    ^ @ ?A { T old }\n}\n\n// ── Mutation ────────────────────────────────────────────────────────\n\n@ vec_push [A] ( Vec A ) v A x → v {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    // Only call into __vec_grow when the buffer is actually full: the\n    // grow path is too big to inline, and paying a call per push showed\n    // up at ~6 % of a parse-heavy profile. The common push is then a\n    // load, a compare, a store and a length bump.\n    ? >= len ( __vec_cap_raw ctl ) { ( __vec_grow [A] ctl + len 1 ) } {}\n    : *A data # *A ( nurl_vctl_data ctl )\n    = . data len x\n    ( nurl_vctl_set ctl 1 + len 1 )\n}\n\n// Append the low `w` bytes (1..8) of `x` to a byte Vec, least significant\n// first (`be`: most significant first) — one capacity check and one\n// length bump for the whole word, so a serializer writing u32/u64 fields\n// does not pay eight pushes per field.\n@ vec_push_word_u8 ( Vec u ) v i x i w b be → v {\n    ? | < w 1 > w 8 { ^ } {}\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? > + len w ( __vec_cap_raw ctl ) { ( __vec_grow [u] ctl + len w ) } {}\n    : *u data # *u ( nurl_vctl_data ctl )\n    : ~ i k 0\n    ~ < k w {\n        : i sh * 8 ? be - - w 1 k k\n        = . data + len k # u & >> x sh 255\n        = k + k 1\n    }\n    ( nurl_vctl_set ctl 1 + len w )\n}\n\n// Insert `x` at index `idx`, shifting existing [idx..len) right by one.\n// Valid indices: [0..len]. idx == len behaves like vec_push. Returns\n// false if idx is out of range. Out-of-range insert is a no-op.\n@ vec_insert [A] ( Vec A ) v i idx A x → b {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? | < idx 0 > idx len { ^ F } {}\n    ? < ( __vec_cap_raw ctl ) + len 1 { ( __vec_grow [A] ctl + len 1 ) } {}\n    : *A data # *A ( nurl_vctl_data ctl )\n    // Shift right [idx..len) → [idx+1..len+1). Walk from the tail to\n    // keep adjacent slots from clobbering each other.\n    : ~ i i len\n    ~ > i idx {\n        = . data i . data - i 1\n        = i - i 1\n    }\n    = . data idx x\n    ( nurl_vctl_set ctl 1 + len 1 )\n    ^ T\n}\n\n// Remove the element at `idx`, shifting the tail down by one. Returns\n// the removed element wrapped in Some, or None if idx is out of range.\n@ vec_remove [A] ( Vec A ) v i idx → ?A {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? >= # u64 idx # u64 len { ^ @ ?A { F # A 0 } } {}\n    : *A data # *A ( nurl_vctl_data ctl )\n    : A x . data idx\n    ( mem_take x )  // the element leaves the container\n    : ~ i i idx\n    ~ < i - len 1 {\n        = . data i . data + i 1\n        = i + i 1\n    }\n    ( nurl_vctl_set ctl 1 - len 1 )\n    ^ @ ?A { T x }\n}\n\n@ vec_pop [A] ( Vec A ) v → ?A {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? == len 0 { ^ @ ?A { F # A 0 } } {}\n    : i last - len 1\n    : *A data # *A ( nurl_vctl_data ctl )\n    : A x . data last\n    ( mem_take x )  // the element leaves the container\n    ( nurl_vctl_set ctl 1 last )\n    ^ @ ?A { T x }\n}\n\n@ vec_clear [A] ( Vec A ) v → v {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : *A data # *A ( nurl_vctl_data ctl )\n    // Length first, so a drop that reaches `v` sees it empty.\n    ( nurl_vctl_set ctl 1 0 )\n    // The elements leave with the length: each is dropped (a no-op, and no\n    // loop, for elements that own nothing).\n    : ~ i k 0\n    ~ < k len {\n        : A e . data k\n        ( mem_take e )\n        = k + k 1\n    }\n}\n\n// Shorten `v` to its first `n` elements; the ones past `n` are dropped\n// (vec_set_len would forget them). F when `n` is negative or past the end.\n@ vec_truncate [A] ( Vec A ) v i n → b {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? | < n 0 > n len { ^ F } {}\n    : *A data # *A ( nurl_vctl_data ctl )\n    // Length first, so a drop that reaches `v` sees it short.\n    ( nurl_vctl_set ctl 1 n )\n    : ~ i k n\n    ~ < k len {\n        : A e . data k\n        ( mem_take e )\n        = k + k 1\n    }\n    ^ T\n}\n\n// Commit a raw write that the caller performed via `vec_data` directly\n// — used by FFI bridges (TCP read, binary file IO, hash digest sinks)\n// that hand the Vec's data pointer to the runtime and then need to\n// promote `len` from 0 to the number of bytes the runtime stored.\n//\n// Returns F (no-op) if `n` is negative or larger than the current cap.\n// Caller is responsible for ensuring slots [0..n) are initialised\n// before calling — `vec_set_len` does NOT zero-fill.\n@ vec_set_len [A] ( Vec A ) v i n → b {\n    ? < n 0 { ^ F } {}\n    : s ctl . v ctl\n    // A borrowed view can only shrink: its writable extent is its length.\n    : i cap ? ( __vec_is_borrowed ctl ) ( __vec_len_raw ctl ) ( __vec_cap_raw ctl )\n    ? > n cap { ^ F } {}\n    ( nurl_vctl_set ctl 1 n )\n    ^ T\n}\n\n// Fresh Vec[i] pre-filled with [lo, lo+1, ..., hi-1]. hi <= lo is a\n// fresh empty Vec[i]. Single allocation, no per-element grow. Useful\n// when sorting an index permutation.\n@ vec_iota i lo i hi → ( Vec i ) {\n    : i n ? > hi lo - hi lo 0\n    : ( Vec i ) v ( vec_with_cap [i] n )\n    ? > n 0 {\n        : *i data ( vec_data [i] v )\n        : ~ i k 0\n        ~ < k n {\n            = . data k + lo k\n            = k + k 1\n        }\n        : b _ok ( vec_set_len [i] v n )\n    } {}\n    ^ v\n}\n\n@ vec_swap [A] ( Vec A ) v i i_idx i j_idx → b {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? | | | < i_idx 0 >= i_idx len < j_idx 0 >= j_idx len { ^ F } {}\n    ? == i_idx j_idx { ^ T } {}\n    : *A data # *A ( nurl_vctl_data ctl )\n    : A a . data i_idx\n    : A b . data j_idx\n    = . data i_idx b\n    = . data j_idx a\n    ^ T\n}\n\n@ vec_reverse [A] ( Vec A ) v → v {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? > len 1 {\n        : *A data # *A ( nurl_vctl_data ctl )\n        : ~ i i 0\n        : ~ i j - len 1\n        ~ < i j {\n            : A a . data i\n            : A b . data j\n            = . data i b\n            = . data j a\n            = i + i 1\n            = j - j 1\n        }\n    } {}\n}\n\n// ── Capacity ────────────────────────────────────────────────────────\n\n// Ensure cap ≥ len + n. n ≤ 0 is a no-op. Allocates lazily; safe on a\n// fresh Vec with cap == 0.\n@ vec_reserve [A] ( Vec A ) v i n → v {\n    ? > n 0 {\n        : s ctl . v ctl\n        : i len ( __vec_len_raw ctl )\n        ? < ( __vec_cap_raw ctl ) + len n { ( __vec_grow [A] ctl + len n ) } {}\n    } {}\n}\n\n// Set the length to exactly `n`. Growing zero-fills the new tail with a\n// single `nurl_memset` instead of a push-a-zero loop; shrinking only\n// lowers the length, running no per-element drop, so the same\n// trivial-element-type rule as `vec_extend` applies. Returns F — and\n// changes nothing — for a negative `n`.\n@ vec_resize_zeroed [A] ( Vec A ) v i n → b {\n    ? < n 0 { ^ F } {}\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? <= n len { ( nurl_vctl_set ctl 1 n ) ^ T } {}\n    ? < ( __vec_cap_raw ctl ) n { ( __vec_grow [A] ctl n ) } {}\n    : s data ( __vec_data_raw ctl )\n    : s tail # s + # i data * Z A len\n    ( nurl_memset tail 0 * Z A - n len )\n    ( nurl_vctl_set ctl 1 n )\n    ^ T\n}\n\n// Release any unused capacity. If len == 0 the buffer is freed entirely\n// (cap → 0, data → null). Otherwise the buffer is realloc'd down to len.\n@ vec_shrink_to_fit [A] ( Vec A ) v → v {\n    : s ctl . v ctl\n    // Not our buffer to resize or free.\n    ? ( __vec_is_borrowed ctl ) { ^ } {}\n    : i len ( __vec_len_raw ctl )\n    : i cap ( __vec_cap_raw ctl )\n    ? == len 0 {\n        : s data ( __vec_data_raw ctl )\n        ? != 0 # i data { ( nurl_free data ) } {}\n        ( nurl_vctl_set ctl 0 0 )\n        ( nurl_vctl_set ctl 2 0 )\n    } {\n        ? < len cap {\n            : s cur ( __vec_data_raw ctl )\n            : s fresh ( nurl_realloc cur * Z A len )\n            ( nurl_vctl_set ctl 0 # i fresh )\n            ( nurl_vctl_set ctl 2 len )\n        } {}\n    }\n}\n\n// Append copies of `src[off .. off+n)` to `dst`, as vec_extend below.\n//\n// The whole-vector form makes a caller who has only a sub-range build a\n// temporary Vec to pass it — a full copy of the data, plus an\n// allocation and a free, to move bytes it already had. net/tcpstack.nu\n// hits this on every outgoing segment (TCP carries no length field, so\n// the segments arrive as offsets into one buffer), which is the wrong\n// place to be allocating.\n//\n// Out-of-range requests are clamped rather than trapped: `off` past the\n// end appends nothing, and a length running past the end appends what\n// is there. A caller computing a range from a parsed header should not\n// have to re-verify what the vector can already answer.\n@ vec_extend_range [A] ( Vec A ) dst ( Vec A ) src i off i n → v {\n    : s sctl . src ctl\n    : i slen ( __vec_len_raw sctl )\n    : i start ? < off 0 0 off\n    ? >= start slen { ^ } {}\n    : i want ? < n 0 0 n\n    : i cnt ? > + start want slen - slen start want\n    ? <= cnt 0 { ^ } {}\n    : s dctl . dst ctl\n    : i dlen ( __vec_len_raw dctl )\n    ? < ( __vec_cap_raw dctl ) + dlen cnt { ( __vec_grow [A] dctl + dlen cnt ) } {}\n    : *A ddata # *A ( nurl_vctl_data dctl )\n    : *A sdata # *A ( nurl_vctl_data sctl )\n    : ~ i i 0\n    ~ < i cnt {\n        = . ddata + dlen i ( mem_dup . sdata + start i )\n        = i + i 1\n    }\n    ( nurl_vctl_set dctl 1 + dlen cnt )\n}\n\n// Append a copy of every element of `src` to `dst`: an element that owns\n// something (a String, a Vec, an owning struct) is copied deep\n// (`mem_dup`), anything else as is — so `src` keeps its elements. To MOVE\n// them instead, use vec_append.\n@ vec_extend [A] ( Vec A ) dst ( Vec A ) src → v {\n    : s sctl . src ctl\n    : i n ( __vec_len_raw sctl )\n    ? > n 0 {\n        : s dctl . dst ctl\n        : i dlen ( __vec_len_raw dctl )\n        ? < ( __vec_cap_raw dctl ) + dlen n { ( __vec_grow [A] dctl + dlen n ) } {}\n        : *A ddata # *A ( nurl_vctl_data dctl )\n        : *A sdata # *A ( nurl_vctl_data sctl )\n        : ~ i i 0\n        ~ < i n {\n            = . ddata + dlen i ( mem_dup . sdata i )\n            = i + i 1\n        }\n        ( nurl_vctl_set dctl 1 + dlen n )\n    } {}\n}\n\n// The elements themselves, bitwise: vec_append's move.\n@ __vec_extend_move [A] ( Vec A ) dst ( Vec A ) src → v {\n    : s sctl . src ctl\n    : i n ( __vec_len_raw sctl )\n    ? > n 0 {\n        : s dctl . dst ctl\n        : i dlen ( __vec_len_raw dctl )\n        ? < ( __vec_cap_raw dctl ) + dlen n { ( __vec_grow [A] dctl + dlen n ) } {}\n        : *A ddata # *A ( nurl_vctl_data dctl )\n        : *A sdata # *A ( nurl_vctl_data sctl )\n        : ~ i i 0\n        ~ < i n {\n            = . ddata + dlen i . sdata i\n            = i + i 1\n        }\n        ( nurl_vctl_set dctl 1 + dlen n )\n    } {}\n}\n\n// Move every element of `src` onto the end of `dst`, then release `src`'s\n// buffer: the elements change owner, nothing is cloned or dropped. This is\n// the vec_extend for element types that own something — one memcpy-shaped\n// loop and one free, where extend-then-free would drop what it just copied.\n@ vec_append [A] ( Vec A ) dst sink ( Vec A ) src → v {\n    ( __vec_extend_move [A] dst src )\n    // The elements live in `dst` now; `src` leaves empty.\n    ( nurl_vctl_set . src ctl 1 0 )\n}\n\n// ── Cleanup ─────────────────────────────────────────────────────────\n\n// Early release: exactly what dropping `v` does — its elements are dropped\n// (for elements that own nothing that is no work), then the buffer and the\n// handle (docs/MEMORY.md §7.6). The `sink` parameter is dropped on the way\n// out; a borrowed view (vec_borrow_raw) releases only its handle, and a\n// packed String buffer is freed with its control block (nurl_vec_drop).\n@ vec_free [A] sink ( Vec A ) v → v {}\n\n// Early release with a last look: `drop` is lent every live element in\n// [0..len), then `v` goes exactly as `vec_free` releases it — its elements\n// with it. The hook only borrows (a closure's parameters always do, docs/\n// MEMORY.md §7.4): it is for teardown the element type does not do itself\n// — closing a raw C handle, logging — never for releasing what `v` owns.\n@ vec_free_with [A] sink ( Vec A ) v ( @ v A ) drop → v {\n    : s ctl . v ctl\n    // A borrowed view owns neither the elements nor the buffer: no hook.\n    ? ( __vec_is_borrowed ctl ) { ^ } {}\n    : i len ( __vec_len_raw ctl )\n    : s data ( __vec_data_raw ctl )\n    ? != 0 # i data {\n        : *A buf # *A data\n        : ~ i i 0\n        ~ < i len {\n            ( drop . buf i )\n            = i + i 1\n        }\n    } {}\n}\n\n// ── Clone ───────────────────────────────────────────────────────────\n\n// A copy of `v` owning copies of its elements: an element that owns\n// something (a String, a Vec, an owning struct) is copied deep\n// (`mem_dup`), anything else as is. `vec_clone_with` is for a copy made\n// some other way than the element type's own.\n@ vec_clone [A] ( Vec A ) v → ( Vec A ) {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : ( Vec A ) out ( vec_with_cap [A] len )\n    ? > len 0 {\n        : *A src # *A ( nurl_vctl_data ctl )\n        : *A dst ( vec_data [A] out )\n        : ~ i i 0\n        ~ < i len {\n            = . dst i ( mem_dup . src i )\n            = i + i 1\n        }\n        : b _ok ( vec_set_len [A] out len )\n    } {}\n    ^ out\n}\n\n// Deep copy: a fresh Vec whose elements are produced by calling `clone`\n// on every element of `v` in order. `clone` must return an element that\n// owns its own heap storage independently of the source — for Vec[String]\n// pass `\\ String s → String { ^ ( string_clone s ) }`, for Vec[Json]\n// `\\ Json j → Json { ^ ( json_clone j ) }`, etc. The source Vec is left\n// untouched; the caller owns both Vecs and frees each with the matching\n// `vec_free_with`.\n@ vec_clone_with [A] ( Vec A ) v ( @ A A ) clone → ( Vec A ) {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : ( Vec A ) out ( vec_with_cap [A] len )\n    ? > len 0 {\n        : *A src # *A ( nurl_vctl_data ctl )\n        : ~ i i 0\n        ~ < i len {\n            : A x . src i\n            ( vec_push [A] out ( clone x ) )\n            = i + i 1\n        }\n    } {}\n    ^ out\n}\n\n// ── Higher-order ────────────────────────────────────────────────────\n\n@ vec_each [A] ( Vec A ) v ( @ v A ) f → v {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    ? > len 0 {\n        : *A data # *A ( nurl_vctl_data ctl )\n        : ~ i i 0\n        ~ < i len {\n            ( f . data i )\n            = i + i 1\n        }\n    } {}\n}\n\n@ vec_fold [A B] ( Vec A ) v B init ( @ B B A ) f → B {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ B acc init\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        = acc ( f acc x )\n        = i + i 1\n    }\n    ^ acc\n}\n\n// Map every element through `f` into a fresh Vec[B]. The source Vec is\n// not modified; the caller owns both. Element bytes are copied bitwise\n// — safe for trivial element types (i, f, b, raw s pointers, fat-ptr\n// slices). For owned types like String, vec_map would alias buffers\n// across two Vecs and break the single-owner invariant; build a Vec\n// manually with vec_each + vec_push and an explicit clone.\n@ vec_map [A B] ( Vec A ) v ( @ B A ) f → ( Vec B ) {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : ( Vec B ) out ( vec_with_cap [B] len )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        ( vec_push [B] out ( f x ) )\n        = i + i 1\n    }\n    ^ out\n}\n\n// Keep elements where `pred` returns T. Same trivial-element caveat as\n// vec_map: the kept elements are bitwise-copied into the output Vec.\n@ vec_filter [A] ( Vec A ) v ( @ b A ) pred → ( Vec A ) {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : ( Vec A ) out ( vec_new [A] )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        ? ( pred x ) { ( vec_push [A] out x ) } {}\n        = i + i 1\n    }\n    ^ out\n}\n\n// Owned-safe filter: keep elements where `pred` returns T, but push a\n// `clone` of each kept element into the output instead of a bitwise\n// alias. The result Vec owns its elements independently of `v`, so both\n// can be freed with `vec_free_with` without a double-free. Use this for\n// Vec[String] / Vec[Json] / nested containers; `vec_filter` stays the\n// faster path for trivial element types.\n@ vec_filter_with [A] ( Vec A ) v ( @ b A ) pred ( @ A A ) clone → ( Vec A ) {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : ( Vec A ) out ( vec_new [A] )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        ? ( pred x ) { ( vec_push [A] out ( clone x ) ) } {}\n        = i + i 1\n    }\n    ^ out\n}\n\n// First element matching `pred`, or None.\n@ vec_find [A] ( Vec A ) v ( @ b A ) pred → ?A {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        ? ( pred x ) { ^ @ ?A { T x } } {}\n        = i + i 1\n    }\n    ^ @ ?A { F # A 0 }\n}\n\n// True if any element satisfies `pred`. Short-circuits.\n@ vec_any [A] ( Vec A ) v ( @ b A ) pred → b {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        ? ( pred x ) { ^ T } {}\n        = i + i 1\n    }\n    ^ F\n}\n\n// True if `target` is present in `v` (according to `eq_fn`). Short-circuits.\n// Use the same eq closures HashMap takes (`eq_int`, `eq_string`) or a custom\n// one. For trivial element types the closure body is just `== a b`.\n@ vec_contains [A] ( Vec A ) v A target ( @ b A A ) eq_fn → b {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        ? ( eq_fn x target ) { ^ T } {}\n        = i + i 1\n    }\n    ^ F\n}\n\n// First byte index where `target` occurs in `v`, or None. Same eq_fn\n// convention as vec_contains.\n@ vec_index_of [A] ( Vec A ) v A target ( @ b A A ) eq_fn → ?i {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        ? ( eq_fn x target ) { ^ @ ?i { T i } } {}\n        = i + i 1\n    }\n    ^ @ ?i { F 0 }\n}\n\n// Length-equal + element-wise equality under `eq_fn`. Short-circuits.\n@ vec_eq [A] ( Vec A ) a ( Vec A ) b ( @ b A A ) eq_fn → b {\n    : s actl . a ctl\n    : s bctl . b ctl\n    : i la ( __vec_len_raw actl )\n    : i lb ( __vec_len_raw bctl )\n    ? != la lb { ^ F } {}\n    : *A da # *A ( nurl_vctl_data actl )\n    : *A db # *A ( nurl_vctl_data bctl )\n    : ~ i i 0\n    ~ < i la {\n        : A x . da i\n        : A y . db i\n        : b ok ( eq_fn x y )\n        ? ! ok { ^ F } {}\n        = i + i 1\n    }\n    ^ T\n}\n\n// True if every element satisfies `pred`. Short-circuits on first F.\n@ vec_all [A] ( Vec A ) v ( @ b A ) pred → b {\n    : s ctl . v ctl\n    : i len ( __vec_len_raw ctl )\n    : *A data # *A ( nurl_vctl_data ctl )\n    : ~ i i 0\n    ~ < i len {\n        : A x . data i\n        : b ok ( pred x )\n        ? ! ok { ^ F } {}\n        = i + i 1\n    }\n    ^ T\n}\n\n// ── In place ────────────────────────────────────────────────────────\n\n// Keep the elements `keep` answers T for, in order; the others are\n// dropped. In place: the same buffer and control block, so every copy of\n// the handle sees the result, and nothing is allocated.\n@ vec_retain [A] ( Vec A ) v ( @ b A ) keep → v {\n    : i n ( vec_len [A] v )\n    : *A data ( vec_data [A] v )\n    : ~ i w 0\n    : ~ i r 0\n    ~ < r n {\n        : A x . data r\n        ? ( keep x ) {\n            ? != w r { = . data w x } {}\n            = w + w 1\n        } {\n            ( mem_take x )  // the slot gives it up: dropped here\n        }\n        = r + r 1\n    }\n    : b _l ( vec_set_len [A] v w )\n}\n\n// Write `x` — the element of slot `idx`, read out (vec_at) and updated —\n// back into that slot. It IS the slot's value, so nothing is dropped and\n// nothing is copied: the check-in of a table that lends its records out\n// by value.\n@ vec_put_back [A] ( Vec A ) v i idx A x → v {\n    : *A data ( vec_data [A] v )\n    ( mem_put_back x )\n    = . data idx x\n}\n\n// ── Publish-once ────────────────────────────────────────────────────\n\n& `c` @ nurl_once_slot i id i candidate → i\n\n// A table the whole program shares, built lazily by whichever thread gets\n// there first: `v` is offered for the runtime's publish-once slot `slot`\n// (stdlib/runtime_core.c; the slot registry is in stdlib/std/tls_server.nu).\n// The first Vec published there stays for the program's life; a later one\n// is dropped here. The published Vec comes back as its word, for a global\n// to cache and to lend out as `# ( Vec A ) w`.\n@ vec_publish_once [A] i slot sink ( Vec A ) v → i {\n    : i mine # i . v ctl\n    : i won ( nurl_once_slot slot mine )\n    ? == won mine { ( mem_forget v ) } {}\n    ^ won\n}\n","bytes":47344}