unitRecComparer;interfaceusesGenerics.Defaults;typeTRecordEqualityComparer<T:record>=class(TEqualityComparer<T>)privateclassvarEqualityComparer_Vtable:array[0..4]ofPointer;EqualityComparer_Instance:Pointer;Equals:function(constleft,right:T):Boolean;GetHashCode:function(Self:Pointer):Integer;classfunctionEqualsProxy(inst:Pointer;constleft,right:T):Boolean;static;classfunctionGetHashCodeProxy(inst:Pointer;constvalue:T):Integer;static;publicclassconstructorCreate;classfunctionDefault:IEqualityComparer<T>;static;end;functionNopAddref(inst:Pointer):Integer;stdcall;functionNopRelease(inst:Pointer):Integer;stdcall;functionNopQueryInterface(inst:Pointer;constIID:TGUID;outObj):HResult;stdcall;implementationusesRtti;functionNopAddref(inst:Pointer):Integer;stdcall;beginResult:=-1;end;functionNopRelease(inst:Pointer):Integer;stdcall;beginResult:=-1;end;functionNopQueryInterface(inst:Pointer;constIID:TGUID;outObj):HResult;stdcall;beginResult:=E_NOINTERFACE;end;{TRecordEqualityComparer<T>}classconstructorTRecordEqualityComparer<T>.Create;varctx:TRttiContext;m:TRttiMethod;p:Pointer;beginEqualityComparer_Vtable[0]:=@NopQueryInterface;EqualityComparer_Vtable[1]:=@NopAddref;EqualityComparer_Vtable[2]:=@NopRelease;EqualityComparer_Vtable[3]:=@TRecordEqualityComparer<T>.EqualsProxy;EqualityComparer_Vtable[4]:=@TRecordEqualityComparer<T>.GetHashCodeProxy;EqualityComparer_Instance:=@EqualityComparer_Vtable;// TODO check signature for compatibilitym:=ctx.GetType(TypeInfo(T)).GetMethod('&op_Equality');ifAssigned(m)thenEquals:=m.CodeAddress;m:=ctx.GetType(TypeInfo(T)).GetMethod('GetHashCode');ifAssigned(m)thenGetHashCode:=m.CodeAddress;end;classfunctionTRecordEqualityComparer<T>.Default:IEqualityComparer<T>;beginAssert(GetTypeKind(T)=tkRecord);Assert(Assigned(Equals));Assert(Assigned(GetHashCode));IInterface(Result):=nil;Pointer(Result):=@EqualityComparer_Instance;end;classfunctionTRecordEqualityComparer<T>.EqualsProxy(inst:Pointer;constleft,right:T):Boolean;beginResult:=Equals(left,right);end;classfunctionTRecordEqualityComparer<T>.GetHashCodeProxy(inst:Pointer;constvalue:T):Integer;beginResult:=GetHashCode(@value);end;end.
HTTPSSSH
You can clone a snippet to your computer for local editing.
Learn more.