import { MetaContext, MetaObject } from '../../MetaContext'; export const $EQUAL = '$equal'; export type Equal = (lhs: T, rhs: T) => boolean; export type $Equal = { [$EQUAL]: Equal }; export const withEqual = MetaContext>(MetaContextBase: TMetaContextBase) => class extends MetaContextBase { [$EQUAL](lhs: T, rhs: T) { const $lhs = this.resolveValue(lhs); if ($lhs !== this.resolveValue(rhs)) return false; return $lhs[$EQUAL](lhs, rhs, this) as boolean; } }; export type GenericEqual = (lhs: T, rhs: T, equalfn: Equal, context: any) => boolean; export function deepEqual(genericEqual: GenericEqual) { return function $equal(this: MetaObject, lhs: T, rhs: T, context: MetaContext & $Equal) { const equalfn = context[$EQUAL]; return (this[$EQUAL] = function $equal(lhs: T, rhs: T, context: MetaContext) { return genericEqual(lhs, rhs, equalfn, context); })(lhs, rhs, context); }; } export function primitiveEqual(lhs: T, rhs: T) { return lhs === rhs; } export function primitiveWrapperEqual(lhs: T, rhs: T) { return lhs.valueOf() === rhs.valueOf(); }