runtime 1.0.0
Checked CEL programs, owned values, and reusable execution stacks
Loading...
Searching...
No Matches
cel::dyn_segment Class Reference

Checks stack effects while constructing a move-only ordinary operation sequence. Operations consume older-first exact operands and report runtime failures with exceptions. Successful finish freezes captures and descriptors independently of builder lifetime. Owned callbacks retain their captures; referenced external state stays caller-owned. Destruction releases unfinished captures and metadata. Complexity: destruction takes O(owned captures, metadata, and client destructor work). Emission costs include amortized O(1) instruction bookkeeping and, on logical stack growth, O(current stack depth) metadata transfer in addition to each operation's stated costs. Example: dyn_segment b; b.just(value::from(2.0)); auto p = std::move(b).finish();. See the runtime.hpp example for complete construction, preparation, reservation, and execution. More...

#include <cel/runtime/dyn_segment.hpp>

Public Member Functions

 dyn_segment ()=default
 Creates an empty checked stack. Example: dyn_segment builder;.
 dyn_segment (stack_origin origin)
 Creates an empty dependent fragment at the supplied ambient origin. A nonzero byte or depth origin prevents independent execution or preparation after finish. This constructor does no accounting; subsequent emission reports unrepresentable absolute cursor/depth with std::overflow_error. Example: dyn_segment branch(parent.before_top());.
 dyn_segment (const dyn_segment &)=delete
 Disallows copying mutable construction ownership.
dyn_segment & operator= (const dyn_segment &)=delete
 Disallows copied assignment.
 dyn_segment (dyn_segment &&) noexcept=default
 Transfers construction ownership. Use the source only for destruction or assignment after moving.
dyn_segment & operator= (dyn_segment &&) noexcept=default
 Transfers construction ownership, releasing prior captures and metadata. Use the source only for destruction or assignment after moving, including self-move. Complexity: O(old captures and metadata).
stack_origin origin () const noexcept
 Returns the retained ambient origin. Example: builder.origin() == stack_origin{}.
std::span< const value_type > operand_types (std::size_t arity) const noexcept
 Borrows the requested local logical operand suffix in older-first order. Returns an empty view for zero arity or underflow; ambient origins are not operands. Does not allocate, mutate construction, finish code, or invoke callbacks. Mutation, move, or destruction of this builder invalidates the view. Copying a descriptor from the view retains its immutable metadata independently. Example: auto inputs = builder.operand_types(2); if (inputs.size() != 2) return;.
stack_origin snapshot () const
 Returns the current absolute logical cursor and live-slot depth. Throws overflow_error if ambient plus local depth overflows. Example: auto ambient = builder.snapshot();.
stack_origin origin_below (std::size_t count) const
 Returns the absolute origin below count local operands without mutation or allocation. Zero returns the current cursor/depth; the full local depth returns origin(). Throws invalid_argument on local underflow and overflow_error on depth overflow. Example: builder.make_tuple(2, builder.origin_below(2));.
stack_origin before_top () const
 Returns the origin immediately below the top local operand. Throws invalid_argument if no local operand exists. Example: dyn_segment then_body(builder.before_top());.
void make_tuple (std::size_t count, stack_origin ambient)
 Packs count source-ordered operands into an exact owning tuple at ambient. Count zero emits source unit. Execution transfers children without cloning them. Throws invalid_argument for missing operands or wrong byte/depth origin before effects. Throws overflow_error for canonical layout/accounting overflow. Complexity: O(count + compared metadata) construction; O(count + outer bytes) execution. Example: builder.make_tuple(2, stack_origin{});.
void make_array (std::size_t count, value_type element, stack_origin ambient)
 Packs exact element operands into one owning packed array, including typed empty arrays. Requires element ownership capability even when count is zero; execution transfers children. Throws invalid_argument for count, complete element mismatch, ownership, or ambient origin. Throws overflow_error for extent/accounting overflow. Complexity: O(count + compared metadata) construction; O(count + element bytes) execution. Example: builder.make_array(0, value_type::leaf<double>(), {});.
void make_record (value_type record, stack_origin ambient)
 Packs record operands already ordered by the canonical schema. Follows the source-order overload's ownership, validation, and allocation contracts. Complexity: O(fields + compared metadata). Example: builder.make_record(schema, {});.
void make_record (value_type record, std::span< const std::size_t > permutation, stack_origin ambient)
 Packs source-position to schema-position fields without reordering expression execution. Each permutation[i] gives the schema position of source operand i, one entry per field. Copies the map and retains record; neither input must outlive construction. Throws invalid_argument for non-record, wrong origin/types, or incomplete/nonbijective map. Throws overflow_error for extent/accounting overflow. Validation precedes publication. Complexity: O(fields + compared metadata) construction; O(fields + outer bytes) execution. Example: builder.make_record(schema, std::array<std::size_t, 2>{1, 0}, {});.
void project_tuple (std::size_t index)
 Transfers one tuple field while retiring the consumed tuple and siblings, without clones. Throws invalid_argument for a wrong operand category or index before publication. Complexity: O(compared metadata) construction; O(siblings + ownership work) execution. Example: builder.project_tuple(0);.
void project_record (std::string_view name)
 Transfers the named record field and retires the consumed owner and siblings. Throws invalid_argument for non-record or missing field before publication. Complexity: O(names + compared metadata) construction; O(siblings + ownership work) execution. Example: builder.project_record("enabled");.
void index_array ()
 Consumes an array followed by an f64 index and transfers only the selected element. Throws invalid_argument for operand shape before publication; execution throws out_of_range for nonfinite, negative, fractional, unrepresentable, or out-of-bounds indices. Complexity: O(compared metadata) construction; O(siblings + ownership work) execution. Example: builder.just(value::from(0.0)); builder.index_array();.
void make_range (range_kind kind)
 Packs source-ordered f64 endpoints into the complete specified range; full consumes none. Throws invalid_argument for kind or wrong operands; overflow_error for canonical accounting. No floating iteration semantics are supplied. Complexity: O(compared endpoint metadata) construction and O(1) execution. Example: builder.make_range(range_kind::range_full);.
void if_else (dyn_segment then_body, dyn_segment else_body)
 Consumes bool and executes only one exact one-result dependent fragment. Bodies must originate immediately below the condition and each leave exactly one result. All reads in both bodies are registered and preflighted before parent execution effects. Throws invalid_argument for condition, origin, result/read mismatch before publication. Throws overflow_error for accounting. Reservations use the maximum of both bodies' demands. Complexity: O(P + B * (P + B) + compared metadata) time and O(P + B) read space, for P parent reads and B combined body reads; O(selected body work) execution. Example: builder.if_else(std::move(yes), std::move(no));.
void logical_and (dyn_segment rhs)
 Executes bool rhs only if the bool left operand is true. Follows if_else's origins, shared-read preflight, exceptions, and maximum-demand contracts. Complexity: follows if_else for parent/rhs read merging; O(selected rhs work) execution. Example: builder.logical_and(std::move(rhs));.
void logical_or (dyn_segment rhs)
 Executes bool rhs only if the bool left operand is false. Follows if_else's origins, shared-read preflight, exceptions, and maximum-demand contracts. Complexity: follows if_else for parent/rhs read merging; O(selected rhs work) execution. Example: builder.logical_or(std::move(rhs));.
void push_closure (compiled_segment body, std::span< const value_type > parameters)
 Emits an installed callable retaining explicit parameters and independent frozen code. Precondition: body has not been moved from. Throws invalid_argument for dependent body, invalid parameters, or undeclared/wrong reads. Throws overflow_error for canonical accounting. Results admit all complete owning types. Complexity: O(parameters + compared metadata) construction; O(1) carrier clone execution. Example: builder.push_closure(std::move(body).finish(), parameters);.
void invoke_closure (std::size_t arity)
 Consumes an installed callee followed by source-ordered complete declared arguments. Binds exact ownership once; stages all owners in one stable canonical frame before user code. Throws invalid_argument for arity/signature/carrier mismatch before publication. Exceptions retire staged owners and preserve the caller prefix and original exception. Same-carrier exclusion starts before staging and remains held through guarded cleanup. Known direct callee requirements are included; signature-only external costs are not inferred. Complexity: O(arity + compared metadata) construction; O(arguments + callee work) execution. Invocation allocates packed outer staging, pointer tables, and result storage, not scalar boxes. Example: builder.invoke_closure(2);.
void push_argument (std::size_t index, value_type type)
 Emits a read that clones a borrowed positional input when the program executes. Repeated declarations must have identical complete shapes and ownership plans. Throws invalid_argument for incompatible repeated declarations or missing clone capability. Throws std::overflow_error for canonical frame extent or depth overflow. Complexity: O(emitted read count + compared metadata) construction time, plus O(current stack depth) metadata transfer on capacity growth. Example: builder.push_argument(0, value_type::leaf<double>());.
void just (value literal)
 Retains a literal owner and emits an independent clone on every execution. Callable components share code under value's copy semantics rather than copying captures. Throws invalid_argument if the complete value cannot be cloned. Throws std::overflow_error for canonical frame extent or depth overflow. Complexity: O(metadata admission) time, plus O(current stack depth) metadata transfer on capacity growth; retains one owner. Example: builder.just(value::from(true));.
template<class R, class... Args, class F>
requires (detail::exact_callback<F, R, Args...>())
void op (F &&callback)
 Emits an arbitrary-arity const callback with exact declared operands and result. R is a trusted concrete adapter type or void; void consumes without producing a value. Named callback parameters must match Args after cv/reference removal. Generic callbacks must expose a specialization with provably exact Args that deduction from its complete function-pointer signature also selects. Ambiguous/uninspectable callbacks require with_signature's exact member selection. Callbacks return R or a reference to R; no implicit result conversion is admitted. Callbacks may reference caller-owned state; freezing does not make it thread-safe. Lvalue callbacks are copied; rvalue callbacks are moved into owned decayed storage. Callback captures must have nonthrowing destructors; referenced objects must outlive uses. Execution consumes the declared operands, invokes the callback, then publishes its result. Callback exceptions propagate through the execution interface after suffix cleanup. Over-aligned callback operands use reference parameters on MSVC. Throws invalid_argument for current stack mismatch before publishing an opcode. Throws std::overflow_error for canonical frame extent or depth overflow. Complexity: O(arity + compared metadata + capture construction) time, plus O(current stack depth) metadata transfer on capacity growth. Example: builder.op<double, double>([](double n) { return n * 2.0; });.
template<class R, class F>
requires (detail::exact_callback<F, R>())
void op0 (F &&callback)
 Emits a zero-operand callback; void produces no value, otherwise pushes one result. Follows op's callback, validation, and exception contract. Complexity: O(capture construction), plus O(current stack depth) on metadata growth. Example: builder.op0<double>([] { return 2.0; });.
template<class R, class A, class F>
requires (detail::exact_callback<F, R, A>())
void op1 (F &&callback)
 Consumes one exact operand and pushes R unless R is void. Follows op's callback, validation, and exception contract. Complexity: O(compared metadata + capture construction). Example: builder.op1<bool, bool>([](bool b) { return !b; });.
template<class R, class A, class B, class F>
requires (detail::exact_callback<F, R, A, B>())
void op2 (F &&callback)
 Consumes two operands older-first and pushes R unless R is void. Follows op's callback, validation, and exception contract. Complexity: O(compared metadata + capture construction). Example: builder.op2<double, double, double>([](double a, double b) { return a - b; });.
template<class R, class A, class B, class C, class F>
requires (detail::exact_callback<F, R, A, B, C>())
void op3 (F &&callback)
 Consumes three source-order operands and pushes R unless R is void. Follows op's callback, validation, and exception contract. Complexity: O(compared metadata + capture construction). Example: builder.op3<double, double, double, double>( [](double a, double b, double c) { return a + b + c; });.
compiled_segment finish () &&
 Freezes exactly one result, mapping an empty final stack to source unit. Retains the ambient origin; finishing does not make a dependent fragment independent. Throws invalid_argument for leftover operands instead of discarding them. Complexity: O(1), except allocation and source-unit emission. Example: auto program = std::move(builder).finish();.

Detailed Description

Checks stack effects while constructing a move-only ordinary operation sequence. Operations consume older-first exact operands and report runtime failures with exceptions. Successful finish freezes captures and descriptors independently of builder lifetime. Owned callbacks retain their captures; referenced external state stays caller-owned. Destruction releases unfinished captures and metadata. Complexity: destruction takes O(owned captures, metadata, and client destructor work). Emission costs include amortized O(1) instruction bookkeeping and, on logical stack growth, O(current stack depth) metadata transfer in addition to each operation's stated costs. Example: dyn_segment b; b.just(value::from(2.0)); auto p = std::move(b).finish();. See the runtime.hpp example for complete construction, preparation, reservation, and execution.


The documentation for this class was generated from the following file: