tur/sized-buf
SizedBuf: flat contiguous memory layout for sized types.
Wraps a single flat int64_t array with a runtime length. The handle is :int at the C level; the public Turmeric type is (SizedBuf n) -- a phantom-indexed defopaque whose n parameter lets call sites pin and unify buffer lengths statically. Two (SizedBuf n) values appearing in the same signature must share their n, so the SZ8 cross-parameter unifier rejects mismatched literal sizes at compile time (e.g. (sized-buf-copy! (.. : (SizedBuf (Static 2))) (.. : (SizedBuf (Static 3))))).
Since: Phase SZ2; phantom n lift Phase SZ8/P3.
SizedBuf
(defopaque SizedBuf [n] :int)
sized-buf-new
(sized-buf-new [n])
allocate a heap (SizedBuf n) of n elements (uninitialized).
| k | number of elements to allocate |
A fresh (SizedBuf n) where n is polymorphic; pin it via
ascription, e.g. (:: (sized-buf-new 4) (SizedBuf (Static 4))).
The pinned index is load-bearing (it unifies across shared-n
parameters like a declared return type), but nothing checks it
against k -- the ascription is the caller's claim.
(let [b (sized-buf-new 4)] ...)
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-new-zeroed
(sized-buf-new-zeroed [n])
allocate a heap (SizedBuf n), all elements zero.
| k | number of elements to allocate |
A fresh (SizedBuf n) initialised to all zeros.
(let [b (sized-buf-new-zeroed 4)] ...)
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-free
(sized-buf-free [n])
free a heap-allocated (SizedBuf n) and its data.
Do NOT call on a stack SizedBuf (from sized-buf-with-stack); those are freed automatically when the scoped function returns.
| b | (SizedBuf n) from sized-buf-new or sized-buf-new-zeroed |
nil
(sized-buf-free b)
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-len
(sized-buf-len [n])
return the element count of a (SizedBuf n).
| b | (SizedBuf n) |
Runtime element count as :int. The static n index pins the
length at compile time when the call site supplies a literal Size.
(sized-buf-len (sized-buf-new 8)) ; => 8
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-get
(sized-buf-get [n])
bounds-checked element read; aborts on out-of-range index.
| b | (SizedBuf n) | |
| i | zero-based index (0 <= i < sized-buf-len b) |
The int64 value at position i.
(sized-buf-get b 0) ; => first element
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-set!
(sized-buf-set! [n])
bounds-checked element write; aborts on out-of-range index.
Modifies the element in place and returns the same buffer pointer so operations can be chained.
| b | (SizedBuf n) | |
| i | zero-based index | |
| v | value to store |
The same buffer (SizedBuf n) (for chaining).
(sized-buf-set! b 0 42)
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-fill!
(sized-buf-fill! [n])
set every element to v; returns the same buffer.
| b | (SizedBuf n) | |
| v | value to store in every slot |
The same buffer (SizedBuf n).
(sized-buf-fill! b 0) ; zero-fill
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-copy!
(sized-buf-copy! [n])
copy all elements from src into dst via memcpy.
Both buffers share the size parameter n, so the elaborator rejects mismatched literal lengths at compile time via the SZ8 cross-parameter unifier. The runtime length-check is still performed as a defence-in-depth fallback for unsized callers.
| dst | destination (SizedBuf n) | |
| src | source (SizedBuf n) (same n) |
The destination (SizedBuf n).
(sized-buf-copy! dst src)
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-sum
(sized-buf-sum [n])
sum all elements of a (SizedBuf n).
| b | (SizedBuf n) |
Integer sum of all elements; 0 for an empty buffer.
(sized-buf-sum b) ; => sum of elements
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-min
(sized-buf-min [n])
minimum element of a non-empty (SizedBuf n); aborts if empty.
| b | (SizedBuf n) (must have at least one element) |
Minimum int64 element value.
(sized-buf-min b) ; => smallest element
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-max
(sized-buf-max [n])
maximum element of a non-empty (SizedBuf n); aborts if empty.
| b | (SizedBuf n) (must have at least one element) |
Maximum int64 element value.
(sized-buf-max b) ; => largest element
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-size
(sized-buf-size [n])
return the runtime length of a (SizedBuf n) as a Size expression.
| b | (SizedBuf n) |
A (Static k) where k is the runtime buffer length.
(size-eval (sized-buf-size b)) ; => length of b
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
sized-buf-with-stack
(sized-buf-with-stack [n f])
scoped computation over a stack-allocated buffer.
Allocates n int64_t elements on the current stack frame via alloca, zero-fills them, wraps them in a transient SizedBuf header, and calls f with that buffer. The callback receives a raw int handle (NOT a typed (SizedBuf n)) because the inline-C body needs a fixed ABI; cast into the typed view inside the callback via (:: raw :SizedBuf) if you need projection-typed access.
The buffer is automatically reclaimed when this function returns; f must not let the buffer pointer escape.
| n | number of elements (should be a static/small constant) | |
| f | a non-capturing function (int -> int) that receives the raw | |
| buffer handle |
The integer value returned by f.
(defn sum-init-buf [b] :int (sized-buf-set! (:: b :SizedBuf) 0 10) (sized-buf-sum (:: b :SizedBuf))) (sized-buf-with-stack 3 sum-init-buf)
Since: Phase SZ2
sized-buf-compute
(sized-buf-compute [n])
compute a result from a buffer, choosing stack or heap.
When n <= 64 (SIZED_BUF_STACK_THRESHOLD) a stack buffer is used; larger n falls back to heap. The buffer is filled with values 0..n-1 (the index of each element) and then the sum is returned. This function demonstrates the allocation dispatch strategy.
| n | number of elements |
Sum of 0 + 1 + ... + (n-1).
(sized-buf-compute 5) ; => 10 (0+1+2+3+4)
Since: Phase SZ2
sized-buf-from-sized-vec
(sized-buf-from-sized-vec [n])
convert a SizedVec (linked list) to a (SizedBuf n) (flat array).
Traverses the linked list once to count elements, allocates a flat buffer, then fills it. The resulting buffer uses tight contiguous layout.
| v | a SizedVec value (the int64-carried GADT root handle) |
A heap-allocated (SizedBuf n) with the same elements in the same
order. Pin n via ascription on the result when a static length
is known statically.
(let [b (sized-buf-from-sized-vec v)] (println (sized-buf-sum b)))
Since: Phase SZ2; (SizedBuf n) lift Phase SZ8/P3
Internal definitions
__sized-buf-new-raw__sized-buf-new-zeroed-raw__sized-buf-free-raw__sized-buf-len-raw__sized-buf-get-raw__sized-buf-set!-raw__sized-buf-fill!-raw__sized-buf-copy!-raw__sized-buf-sum-raw__sized-buf-min-raw__sized-buf-max-raw__sized-buf-from-sized-vec-raw__sized-buf-stack-threshold