import { $internal, $ownSnippet, $resolve } from '../shared/symbols.ts';
import type { DualFn, SelfResolvable } from '../types.ts';
import { type ResolvedSnippet, type Snippet } from './snippet.ts';
import { type Ptr } from './wgslTypes.ts';
interface ref<T> {
    readonly [$internal]: {
        type: 'ref';
    };
    /**
     * Derefences the reference, and gives access to the underlying value.
     *
     * @example ```ts
     * const boid = Boid({ pos: d.vec3f(3, 2, 1) });
     * const posRef = d.ref(boid.pos);
     *
     * // Actually updates `boid.pos`
     * posRef.$ = d.vec3f(1, 2, 3);
     * console.log(boid.pos); // Output: vec3f(1, 2, 3)
     * ```
     */
    $: T;
}
/**
 * A reference to a value `T`. Can be passed to other functions to give them
 * mutable access to the underlying value.
 *
 * Conceptually, it represents a WGSL pointer.
 */
export type _ref<T> = T extends object ? T & ref<T> : ref<T>;
type RefFn = DualFn<(<T>(value: T) => _ref<T>)> & {
    [$internal]: true;
};
export declare const _ref: RefFn;
export declare function isRef<T>(value: unknown): value is ref<T>;
export declare function INTERNAL_createRef<T>(value: T): ref<T>;
/**
 * The result of calling `d.ref(...)`. The code responsible for
 * generating shader code can check if the value of a snippet is
 * an instance of `RefOperator`, and act accordingly.
 */
export declare class RefOperator implements SelfResolvable {
    #private;
    readonly [$internal]: true;
    readonly snippet: Snippet;
    constructor(snippet: Snippet, ptrType: Ptr | undefined);
    get [$ownSnippet](): Snippet;
    [$resolve](): ResolvedSnippet;
}
export declare function derefSnippet(snippet: Snippet): Snippet;
export {};
