unit uutlInterfaces; {$mode objfpc}{$H+} {$modeswitch nestedprocvars} interface uses Classes, SysUtils; type //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic IutlEqualityComparer = interface function EqualityCompare(const i1, i2: T): Boolean; end; generic TutlEqualityComparer = class(TInterfacedObject, specialize IutlEqualityComparer) public function EqualityCompare(const i1, i2: T): Boolean; end; generic TutlEventEqualityComparer = class(TInterfacedObject, specialize IutlEqualityComparer) public type TEqualityEvent = function(const i1, i2: T): Boolean; TEqualityEventO = function(const i1, i2: T): Boolean of object; TEqualityEventN = function(const i1, i2: T): Boolean is nested; private type TEqualityEventType = (eetNormal, eetObject, eetNested); private fEvent: TEqualityEvent; fEventO: TEqualityEventO; fEventN: TEqualityEventN; fEventType: TEqualityEventType; public function EqualityCompare(const i1, i2: T): Boolean; constructor Create(const aEvent: TEqualityEvent); overload; constructor Create(const aEvent: TEqualityEventO); overload; constructor Create(const aEvent: TEqualityEventN); overload; { HINT: you need to activate "$modeswitch nestedprocvars" when you want to use nested callbacks } end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic IutlComparer = interface function Compare(const i1, i2: T): Integer; end; generic TutlComparer = class(TInterfacedObject, specialize IutlComparer) public function Compare(const i1, i2: T): Integer; end; generic TutlEventComparer = class(TInterfacedObject, specialize IutlComparer) public type TEvent = function(const i1, i2: T): Integer; TEventO = function(const i1, i2: T): Integer of object; TEventN = function(const i1, i2: T): Integer is nested; private type TEventType = (etNormal, etObject, etNested); private fEvent: TEvent; fEventO: TEventO; fEventN: TEventN; fEventType: TEventType; public function Compare(const i1, i2: T): Integer; constructor Create(const aEvent: TEvent); overload; constructor Create(const aEvent: TEventO); overload; constructor Create(const aEvent: TEventN); overload; { HINT: you need to activate "$modeswitch nestedprocvars" when you want to use nested callbacks } end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic IutlReadOnlyList = interface(IUnknown) function GetCount: Integer; function GetItem(const aIndex: Integer): T; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// generic IutlList = interface(specialize IutlReadOnlyList) procedure SetItem(const aIndex: Integer; const aItem: T); end; operator < (const i1, i2: TObject): Boolean; inline; operator > (const i1, i2: TObject): Boolean; inline; implementation //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// operator < (const i1, i2: TObject): Boolean; begin result := Pointer(i1) < Pointer(i2); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// operator > (const i1, i2: TObject): Boolean; begin result := Pointer(i1) > Pointer(i2); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlEqualityComparer////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TutlEqualityComparer.EqualityCompare(const i1, i2: T): Boolean; begin result := (i1 = i2); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TutlEventEqualityComparer.EqualityCompare(const i1, i2: T): Boolean; begin case fEventType of eetNormal: result := fEvent(i1, i2); eetObject: result := fEventO(i1, i2); eetNested: result := fEventN(i1, i2); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlEventEqualityComparer.Create(const aEvent: TEqualityEvent); begin inherited Create; fEvent := aEvent; fEventType := eetNormal; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlEventEqualityComparer.Create(const aEvent: TEqualityEventO); begin inherited Create; fEventO := aEvent; fEventType := eetObject; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlEventEqualityComparer.Create(const aEvent: TEqualityEventN); begin inherited Create; fEventN := aEvent; fEventType := eetNested; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlComparer////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TutlComparer.Compare(const i1, i2: T): Integer; begin if (i1 < i2) then result := -1 else if (i1 > i2) then result := 1 else result := 0; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TutlEventComparer.Compare(const i1, i2: T): Integer; begin case fEventType of etNormal: result := fEvent(i1, i2); etObject: result := fEventO(i1, i2); etNested: result := fEventN(i1, i2); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlEventComparer.Create(const aEvent: TEvent); begin inherited Create; fEvent := aEvent; fEventType := etNormal; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlEventComparer.Create(const aEvent: TEventO); begin inherited Create; fEventO := aEvent; fEventType := etObject; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TutlEventComparer.Create(const aEvent: TEventN); begin inherited Create; fEventN := aEvent; fEventType := etNested; end; end.