import { Equal, Every, Some } from "../helpers";
import { Compose, Fn, PartialApply, unset } from "../core/Core";
export declare namespace Booleans {
    type ExtendsImpl<a, b> = [a] extends [b] ? true : false;
    interface ExtendsFn extends Fn {
        return: this["args"] extends [infer first, infer second, ...any] ? ExtendsImpl<first, second> : never;
    }
    export type Extends<a = unset, b = unset> = PartialApply<ExtendsFn, b extends unset ? [unset, a] : [a, b]>;
    type NotImpl<a> = a extends true ? false : true;
    interface NotFn extends Fn {
        return: this["args"] extends [infer first, ...any] ? NotImpl<first> : never;
    }
    export type Not<a = unset> = PartialApply<NotFn, [a]>;
    interface EqualsFn extends Fn {
        return: this["args"] extends [infer a, infer b, ...any] ? Equal<a, b> : never;
    }
    export type Equals<a = unset, b = unset> = PartialApply<EqualsFn, [a, b]>;
    export type NotEqual<a = unset, b = unset> = Compose<[
        Not,
        PartialApply<EqualsFn, [a, b]>
    ]>;
    export type DoesNotExtend<a = unset, b = unset> = Compose<[
        Not,
        PartialApply<ExtendsFn, [a, b]>
    ]>;
    interface AndFn extends Fn {
        return: this["args"] extends [
            infer first extends boolean,
            infer second extends boolean,
            ...any
        ] ? Every<[first, second]> : never;
    }
    export type And<a = unset, b = unset> = PartialApply<AndFn, [a, b]>;
    interface OrFn extends Fn {
        return: this["args"] extends [
            infer first extends boolean,
            infer second extends boolean,
            ...any
        ] ? Some<[first, second]> : never;
    }
    export type Or<a = unset, b = unset> = PartialApply<OrFn, [a, b]>;
    interface XOrFn extends Fn {
        return: this["args"] extends [
            infer first extends boolean,
            infer second extends boolean,
            ...any
        ] ? first extends second ? false : true : never;
    }
    export type XOr<a = unset, b = unset> = PartialApply<XOrFn, [a, b]>;
    export {};
}
