import { type MapValueToSnippet } from '../../data/snippet.ts';
import { type DualFn, type ResolutionCtx } from '../../types.ts';
import { type BaseData } from '../../data/wgslTypes.ts';
type MapValueToDataType<T> = {
    [K in keyof T]: BaseData;
};
type AnyFn = (...args: never[]) => unknown;
interface DualImplOptions<T extends AnyFn> {
    readonly name: string | undefined;
    readonly normalImpl: T | string;
    readonly codegenImpl: (ctx: ResolutionCtx, args: MapValueToSnippet<Parameters<T>>, returnType: BaseData) => string;
    readonly signature: {
        argTypes: (BaseData | BaseData[])[];
        returnType: BaseData;
    } | ((...inArgTypes: MapValueToDataType<Parameters<T>>) => {
        argTypes: (BaseData | BaseData[])[];
        returnType: BaseData;
    });
    /**
     * Whether the function should skip trying to execute the "normal" implementation if
     * all arguments are known at compile time.
     * @default false
     */
    readonly noComptime?: boolean | undefined;
    readonly ignoreImplicitCastWarning?: boolean | undefined;
    /**
     * Whether calling this function is a side-effect in itself, irrespective of
     * its arguments. Examples:
     *
     * - `discard` -> `true` - it discards the fragment.
     * - `workgroupBarrier()` -> `true` - the barrier synchronizes threads.
     * - `sin(x)`, `abs(x)` -> `false` - these are purely value-producing; the
     *   call itself has no observable effect beyond the returned value.
     *
     * When `false`, the result inherits side-effects from its arguments: it
     * only has `possibleSideEffects: true` if at least one argument does.
     */
    readonly sideEffects: boolean;
}
export declare class MissingCpuImplError extends Error {
    constructor(message: string | undefined);
}
export declare function dualImpl<T extends AnyFn>(options: DualImplOptions<T>): DualFn<T>;
export {};
