12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416 |
- {
- This file is part of the Free Pascal/NewPascal run time library.
- Copyright (c) 2014 by Maciej Izak (hnb)
- member of the NewPascal development team (http://newpascal.org)
- Copyright(c) 2004-2018 DaThoX
- It contains the generics collections library
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- Acknowledgment
- Thanks to Sphere 10 Software (http://sphere10.com) for sponsoring
- many new types and major refactoring of entire library
- Thanks to mORMot (http://synopse.info) project for the best implementations
- of hashing functions like crc32c and xxHash32 :)
- **********************************************************************}
- unit Generics.Defaults;
- {$MODE DELPHI}{$H+}
- {$POINTERMATH ON}
- {$MACRO ON}
- {$COPERATORS ON}
- {$HINTS OFF}
- {$WARNINGS OFF}
- {$NOTES OFF}
- {$OVERFLOWCHECKS OFF}
- {$RANGECHECKS OFF}
- interface
- uses
- Classes, SysUtils, Generics.Hashes, TypInfo, Variants, Math, Generics.Strings, Generics.Helpers;
- type
- IComparer<T> = interface
- function Compare(const Left, Right: T): Integer; overload;
- end;
- TOnComparison<T> = function(const Left, Right: T): Integer of object;
- TComparisonFunc<T> = function(const Left, Right: T): Integer;
- TComparer<T> = class(TInterfacedObject, IComparer<T>)
- public
- class function Default: IComparer<T>; static;
- function Compare(const ALeft, ARight: T): Integer; virtual; abstract; overload;
- class function Construct(const AComparison: TOnComparison<T>): IComparer<T>; overload;
- class function Construct(const AComparison: TComparisonFunc<T>): IComparer<T>; overload;
- end;
- TDelegatedComparerEvents<T> = class(TComparer<T>)
- private
- FComparison: TOnComparison<T>;
- public
- function Compare(const ALeft, ARight: T): Integer; override;
- constructor Create(AComparison: TOnComparison<T>);
- end;
- TDelegatedComparerFunc<T> = class(TComparer<T>)
- private
- FComparison: TComparisonFunc<T>;
- public
- function Compare(const ALeft, ARight: T): Integer; override;
- constructor Create(AComparison: TComparisonFunc<T>);
- end;
- IEqualityComparer<T> = interface
- function Equals(const ALeft, ARight: T): Boolean;
- function GetHashCode(const AValue: T): UInt32;
- end;
- IExtendedEqualityComparer<T> = interface(IEqualityComparer<T>)
- procedure GetHashList(const AValue: T; AHashList: PUInt32); // for double hashing and more
- end;
- ShortString1 = string[1];
- ShortString2 = string[2];
- ShortString3 = string[3];
- { TAbstractInterface }
- TInterface = class
- public
- function QueryInterface(constref {%H-}IID: TGUID;{%H-} out Obj): HResult; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual;
- function _AddRef: LongInt; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual; abstract;
- function _Release: LongInt; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual; abstract;
- end;
- { TRawInterface }
- TRawInterface = class(TInterface)
- public
- function _AddRef: LongInt; override;
- function _Release: LongInt; override;
- end;
- { TComTypeSizeInterface }
- // INTERNAL USE ONLY!
- TComTypeSizeInterface = class(TInterface)
- public
- // warning ! self as PSpoofInterfacedTypeSizeObject
- function _AddRef: LongInt; override;
- // warning ! self as PSpoofInterfacedTypeSizeObject
- function _Release: LongInt; override;
- end;
- { TSingletonImplementation }
- TSingletonImplementation = class(TRawInterface, IInterface)
- public
- function QueryInterface(constref IID: TGUID; out Obj): HResult; override;
- end;
- TCompare = class
- protected
- // warning ! self as PSpoofInterfacedTypeSizeObject
- class function _Binary(const ALeft, ARight): Integer;
- // warning ! self as PSpoofInterfacedTypeSizeObject
- class function _DynArray(const ALeft, ARight: Pointer): Integer;
- public
- class function Integer(const ALeft, ARight: Integer): Integer;
- class function Int8(const ALeft, ARight: Int8): Integer;
- class function Int16(const ALeft, ARight: Int16): Integer;
- class function Int32(const ALeft, ARight: Int32): Integer;
- class function Int64(const ALeft, ARight: Int64): Integer;
- class function UInt8(const ALeft, ARight: UInt8): Integer;
- class function UInt16(const ALeft, ARight: UInt16): Integer;
- class function UInt32(const ALeft, ARight: UInt32): Integer;
- class function UInt64(const ALeft, ARight: UInt64): Integer;
- class function Single(const ALeft, ARight: Single): Integer;
- class function Double(const ALeft, ARight: Double): Integer;
- class function Extended(const ALeft, ARight: Extended): Integer;
- class function Currency(const ALeft, ARight: Currency): Integer;
- class function Comp(const ALeft, ARight: Comp): Integer;
- class function Binary(const ALeft, ARight; const ASize: SizeInt): Integer;
- class function DynArray(const ALeft, ARight: Pointer; const AElementSize: SizeInt): Integer;
- class function ShortString1(const ALeft, ARight: ShortString1): Integer;
- class function ShortString2(const ALeft, ARight: ShortString2): Integer;
- class function ShortString3(const ALeft, ARight: ShortString3): Integer;
- class function &String(const ALeft, ARight: string): Integer;
- class function ShortString(const ALeft, ARight: ShortString): Integer;
- class function AnsiString(const ALeft, ARight: AnsiString): Integer;
- class function WideString(const ALeft, ARight: WideString): Integer;
- class function UnicodeString(const ALeft, ARight: UnicodeString): Integer;
- class function Method(const ALeft, ARight: TMethod): Integer;
- class function Variant(const ALeft, ARight: PVariant): Integer;
- class function Pointer(const ALeft, ARight: PtrUInt): Integer;
- end;
- { TEquals }
- TEquals = class
- protected
- // warning ! self as PSpoofInterfacedTypeSizeObject
- class function _Binary(const ALeft, ARight): Boolean;
- // warning ! self as PSpoofInterfacedTypeSizeObject
- class function _DynArray(const ALeft, ARight: Pointer): Boolean;
- public
- class function Integer(const ALeft, ARight: Integer): Boolean;
- class function Int8(const ALeft, ARight: Int8): Boolean;
- class function Int16(const ALeft, ARight: Int16): Boolean;
- class function Int32(const ALeft, ARight: Int32): Boolean;
- class function Int64(const ALeft, ARight: Int64): Boolean;
- class function UInt8(const ALeft, ARight: UInt8): Boolean;
- class function UInt16(const ALeft, ARight: UInt16): Boolean;
- class function UInt32(const ALeft, ARight: UInt32): Boolean;
- class function UInt64(const ALeft, ARight: UInt64): Boolean;
- class function Single(const ALeft, ARight: Single): Boolean;
- class function Double(const ALeft, ARight: Double): Boolean;
- class function Extended(const ALeft, ARight: Extended): Boolean;
- class function Currency(const ALeft, ARight: Currency): Boolean;
- class function Comp(const ALeft, ARight: Comp): Boolean;
- class function Binary(const ALeft, ARight; const ASize: SizeInt): Boolean;
- class function DynArray(const ALeft, ARight: Pointer; const AElementSize: SizeInt): Boolean;
- class function &Class(const ALeft, ARight: TObject): Boolean;
- class function ShortString1(const ALeft, ARight: ShortString1): Boolean;
- class function ShortString2(const ALeft, ARight: ShortString2): Boolean;
- class function ShortString3(const ALeft, ARight: ShortString3): Boolean;
- class function &String(const ALeft, ARight: String): Boolean;
- class function ShortString(const ALeft, ARight: ShortString): Boolean;
- class function AnsiString(const ALeft, ARight: AnsiString): Boolean;
- class function WideString(const ALeft, ARight: WideString): Boolean;
- class function UnicodeString(const ALeft, ARight: UnicodeString): Boolean;
- class function Method(const ALeft, ARight: TMethod): Boolean;
- class function Variant(const ALeft, ARight: PVariant): Boolean;
- class function Pointer(const ALeft, ARight: PtrUInt): Boolean;
- end;
- THashServiceClass = class of THashService;
- TExtendedHashServiceClass = class of TExtendedHashService;
- THashFactoryClass = class of THashFactory;
- TExtendedHashFactoryClass = class of TExtendedHashFactory;
- { TComparerService }
- {$DEFINE STD_RAW_INTERFACE_METHODS :=
- QueryInterface: @TRawInterface.QueryInterface;
- _AddRef : @TRawInterface._AddRef;
- _Release : @TRawInterface._Release
- }
- {$DEFINE STD_COM_TYPESIZE_INTERFACE_METHODS :=
- QueryInterface: @TComTypeSizeInterface.QueryInterface;
- _AddRef : @TComTypeSizeInterface._AddRef;
- _Release : @TComTypeSizeInterface._Release
- }
- TGetHashListOptions = set of (ghloHashListAsInitData);
- THashFactory = class
- private type
- PPEqualityComparerVMT = ^PEqualityComparerVMT;
- PEqualityComparerVMT = ^TEqualityComparerVMT;
- TEqualityComparerVMT = packed record
- QueryInterface: CodePointer;
- _AddRef: CodePointer;
- _Release: CodePointer;
- Equals: CodePointer;
- GetHashCode: CodePointer;
- __Reserved: CodePointer; // initially or TExtendedEqualityComparerVMT compatibility
- // (important when ExtendedEqualityComparer is calling Binary method)
- __ClassRef: THashFactoryClass; // hidden field in VMT. For class ref THashFactoryClass
- end;
- private
- (***********************************************************************************************************************
- Hashes
- (**********************************************************************************************************************)
- class function Int8 (const AValue: Int8 ): UInt32; overload;
- class function Int16 (const AValue: Int16 ): UInt32; overload;
- class function Int32 (const AValue: Int32 ): UInt32; overload;
- class function Int64 (const AValue: Int64 ): UInt32; overload;
- class function UInt8 (const AValue: UInt8 ): UInt32; overload;
- class function UInt16 (const AValue: UInt16 ): UInt32; overload;
- class function UInt32 (const AValue: UInt32 ): UInt32; overload;
- class function UInt64 (const AValue: UInt64 ): UInt32; overload;
- class function Single (const AValue: Single ): UInt32; overload;
- class function Double (const AValue: Double ): UInt32; overload;
- class function Extended (const AValue: Extended ): UInt32; overload;
- class function Currency (const AValue: Currency ): UInt32; overload;
- class function Comp (const AValue: Comp ): UInt32; overload;
- // warning ! self as PSpoofInterfacedTypeSizeObject
- class function Binary (const AValue ): UInt32; overload;
- // warning ! self as PSpoofInterfacedTypeSizeObject
- class function DynArray (const AValue: Pointer ): UInt32; overload;
- class function &Class (const AValue: TObject ): UInt32; overload;
- class function ShortString1 (const AValue: ShortString1 ): UInt32; overload;
- class function ShortString2 (const AValue: ShortString2 ): UInt32; overload;
- class function ShortString3 (const AValue: ShortString3 ): UInt32; overload;
- class function ShortString (const AValue: ShortString ): UInt32; overload;
- class function AnsiString (const AValue: AnsiString ): UInt32; overload;
- class function WideString (const AValue: WideString ): UInt32; overload;
- class function UnicodeString(const AValue: UnicodeString): UInt32; overload;
- class function Method (const AValue: TMethod ): UInt32; overload;
- class function Variant (const AValue: PVariant ): UInt32; overload;
- class function Pointer (const AValue: Pointer ): UInt32; overload;
- public
- const MAX_HASHLIST_COUNT = 1;
- const HASH_FUNCTIONS_COUNT = 1;
- const HASHLIST_COUNT_PER_FUNCTION: array[1..HASH_FUNCTIONS_COUNT] of Integer = (1);
- const HASH_FUNCTIONS_MASK_SIZE = 1;
- class function GetHashService: THashServiceClass; virtual; abstract;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; virtual; abstract; reintroduce;
- end;
- TExtendedHashFactory = class(THashFactory)
- private type
- PPExtendedEqualityComparerVMT = ^PExtendedEqualityComparerVMT;
- PExtendedEqualityComparerVMT = ^TExtendedEqualityComparerVMT;
- TExtendedEqualityComparerVMT = packed record
- QueryInterface: CodePointer;
- _AddRef: CodePointer;
- _Release: CodePointer;
- Equals: CodePointer;
- GetHashCode: CodePointer;
- GetHashList: CodePointer;
- __ClassRef: TExtendedHashFactoryClass; // hidden field in VMT. For class ref THashFactoryClass
- end;
- private
- (***********************************************************************************************************************
- Hashes 2
- (**********************************************************************************************************************)
- class procedure Int8 (const AValue: Int8 ; AHashList: PUInt32); overload;
- class procedure Int16 (const AValue: Int16 ; AHashList: PUInt32); overload;
- class procedure Int32 (const AValue: Int32 ; AHashList: PUInt32); overload;
- class procedure Int64 (const AValue: Int64 ; AHashList: PUInt32); overload;
- class procedure UInt8 (const AValue: UInt8 ; AHashList: PUInt32); overload;
- class procedure UInt16 (const AValue: UInt16 ; AHashList: PUInt32); overload;
- class procedure UInt32 (const AValue: UInt32 ; AHashList: PUInt32); overload;
- class procedure UInt64 (const AValue: UInt64 ; AHashList: PUInt32); overload;
- class procedure Single (const AValue: Single ; AHashList: PUInt32); overload;
- class procedure Double (const AValue: Double ; AHashList: PUInt32); overload;
- class procedure Extended (const AValue: Extended ; AHashList: PUInt32); overload;
- class procedure Currency (const AValue: Currency ; AHashList: PUInt32); overload;
- class procedure Comp (const AValue: Comp ; AHashList: PUInt32); overload;
- // warning ! self as PSpoofInterfacedTypeSizeObject
- class procedure Binary (const AValue ; AHashList: PUInt32); overload;
- // warning ! self as PSpoofInterfacedTypeSizeObject
- class procedure DynArray (const AValue: Pointer ; AHashList: PUInt32); overload;
- class procedure &Class (const AValue: TObject ; AHashList: PUInt32); overload;
- class procedure ShortString1 (const AValue: ShortString1 ; AHashList: PUInt32); overload;
- class procedure ShortString2 (const AValue: ShortString2 ; AHashList: PUInt32); overload;
- class procedure ShortString3 (const AValue: ShortString3 ; AHashList: PUInt32); overload;
- class procedure ShortString (const AValue: ShortString ; AHashList: PUInt32); overload;
- class procedure AnsiString (const AValue: AnsiString ; AHashList: PUInt32); overload;
- class procedure WideString (const AValue: WideString ; AHashList: PUInt32); overload;
- class procedure UnicodeString(const AValue: UnicodeString; AHashList: PUInt32); overload;
- class procedure Method (const AValue: TMethod ; AHashList: PUInt32); overload;
- class procedure Variant (const AValue: PVariant ; AHashList: PUInt32); overload;
- class procedure Pointer (const AValue: Pointer ; AHashList: PUInt32); overload;
- public
- class procedure GetHashList(AKey: Pointer; ASize: SizeInt; AHashList: PUInt32; AOptions: TGetHashListOptions = []); virtual; abstract;
- end;
- TComparerService = class abstract
- private type
- TSelectMethod = function(ATypeData: PTypeData; ASize: SizeInt): Pointer of object;
- private
- class function SelectIntegerEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; virtual; abstract;
- class function SelectFloatEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; virtual; abstract;
- class function SelectShortStringEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; virtual; abstract;
- class function SelectBinaryEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; virtual; abstract;
- class function SelectDynArrayEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; virtual; abstract;
- private type
- PSpoofInterfacedTypeSizeObject = ^TSpoofInterfacedTypeSizeObject;
- TSpoofInterfacedTypeSizeObject = record
- VMT: Pointer;
- RefCount: LongInt;
- Size: SizeInt;
- end;
- PInstance = ^TInstance;
- TInstance = record
- class function Create(ASelector: Boolean; AInstance: Pointer): TComparerService.TInstance; static;
- class function CreateSelector(ASelectorInstance: CodePointer): TComparerService.TInstance; static;
- case Selector: Boolean of
- false: (Instance: Pointer);
- true: (SelectorInstance: CodePointer);
- end;
- PComparerVMT = ^TComparerVMT;
- TComparerVMT = packed record
- QueryInterface: CodePointer;
- _AddRef: CodePointer;
- _Release: CodePointer;
- Compare: CodePointer;
- end;
- TSelectFunc = function(ATypeData: PTypeData; ASize: SizeInt): Pointer;
- private
- class function CreateInterface(AVMT: Pointer; ASize: SizeInt): PSpoofInterfacedTypeSizeObject; static;
- class function SelectIntegerComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; static;
- class function SelectInt64Comparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; static;
- class function SelectFloatComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; static;
- class function SelectShortStringComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; static;
- class function SelectBinaryComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; static;
- class function SelectDynArrayComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; static;
- private const
- UseBinaryMethods: set of TTypeKind = [tkUnknown, tkSet, tkFile, tkArray, tkRecord, tkObject];
- // IComparer VMT
- Comparer_Int8_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Int8);
- Comparer_Int16_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Int16 );
- Comparer_Int32_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Int32 );
- Comparer_Int64_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Int64 );
- Comparer_UInt8_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.UInt8 );
- Comparer_UInt16_VMT: TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.UInt16);
- Comparer_UInt32_VMT: TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.UInt32);
- Comparer_UInt64_VMT: TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.UInt64);
- Comparer_Single_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Single );
- Comparer_Double_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Double );
- Comparer_Extended_VMT: TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Extended);
- Comparer_Currency_VMT: TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Currency);
- Comparer_Comp_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Comp );
- Comparer_Binary_VMT : TComparerVMT = (STD_COM_TYPESIZE_INTERFACE_METHODS; Compare: @TCompare._Binary );
- Comparer_DynArray_VMT: TComparerVMT = (STD_COM_TYPESIZE_INTERFACE_METHODS; Compare: @TCompare._DynArray);
- Comparer_ShortString1_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.ShortString1 );
- Comparer_ShortString2_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.ShortString2 );
- Comparer_ShortString3_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.ShortString3 );
- Comparer_ShortString_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.ShortString );
- Comparer_AnsiString_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.AnsiString );
- Comparer_WideString_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.WideString );
- Comparer_UnicodeString_VMT: TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.UnicodeString);
- Comparer_Method_VMT : TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Method );
- Comparer_Variant_VMT: TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Variant);
- Comparer_Pointer_VMT: TComparerVMT = (STD_RAW_INTERFACE_METHODS; Compare: @TCompare.Pointer);
- // Instances
- Comparer_Int8_Instance : Pointer = @Comparer_Int8_VMT ;
- Comparer_Int16_Instance : Pointer = @Comparer_Int16_VMT ;
- Comparer_Int32_Instance : Pointer = @Comparer_Int32_VMT ;
- Comparer_Int64_Instance : Pointer = @Comparer_Int64_VMT ;
- Comparer_UInt8_Instance : Pointer = @Comparer_UInt8_VMT ;
- Comparer_UInt16_Instance: Pointer = @Comparer_UInt16_VMT;
- Comparer_UInt32_Instance: Pointer = @Comparer_UInt32_VMT;
- Comparer_UInt64_Instance: Pointer = @Comparer_UInt64_VMT;
- Comparer_Single_Instance : Pointer = @Comparer_Single_VMT ;
- Comparer_Double_Instance : Pointer = @Comparer_Double_VMT ;
- Comparer_Extended_Instance: Pointer = @Comparer_Extended_VMT;
- Comparer_Currency_Instance: Pointer = @Comparer_Currency_VMT;
- Comparer_Comp_Instance : Pointer = @Comparer_Comp_VMT ;
- //Comparer_Binary_Instance : Pointer = @Comparer_Binary_VMT ; // dynamic instance
- //Comparer_DynArray_Instance: Pointer = @Comparer_DynArray_VMT; // dynamic instance
- Comparer_ShortString1_Instance : Pointer = @Comparer_ShortString1_VMT ;
- Comparer_ShortString2_Instance : Pointer = @Comparer_ShortString2_VMT ;
- Comparer_ShortString3_Instance : Pointer = @Comparer_ShortString3_VMT ;
- Comparer_ShortString_Instance : Pointer = @Comparer_ShortString_VMT ;
- Comparer_AnsiString_Instance : Pointer = @Comparer_AnsiString_VMT ;
- Comparer_WideString_Instance : Pointer = @Comparer_WideString_VMT ;
- Comparer_UnicodeString_Instance: Pointer = @Comparer_UnicodeString_VMT;
- Comparer_Method_Instance : Pointer = @Comparer_Method_VMT ;
- Comparer_Variant_Instance: Pointer = @Comparer_Variant_VMT;
- Comparer_Pointer_Instance: Pointer = @Comparer_Pointer_VMT;
- ComparerInstances: array[TTypeKind] of TInstance =
- (
- // tkUnknown
- (Selector: True; SelectorInstance: @TComparerService.SelectBinaryComparer),
- // tkInteger
- (Selector: True; SelectorInstance: @TComparerService.SelectIntegerComparer),
- // tkChar
- (Selector: False; Instance: @Comparer_UInt8_Instance),
- // tkEnumeration
- (Selector: True; SelectorInstance: @TComparerService.SelectIntegerComparer),
- // tkFloat
- (Selector: True; SelectorInstance: @TComparerService.SelectFloatComparer),
- // tkSet
- (Selector: True; SelectorInstance: @TComparerService.SelectBinaryComparer),
- // tkMethod
- (Selector: False; Instance: @Comparer_Method_Instance),
- // tkSString
- (Selector: True; SelectorInstance: @TComparerService.SelectShortStringComparer),
- // tkLString - only internal use / deprecated in compiler
- (Selector: False; Instance: @Comparer_AnsiString_Instance), // <- unsure
- // tkAString
- (Selector: False; Instance: @Comparer_AnsiString_Instance),
- // tkWString
- (Selector: False; Instance: @Comparer_WideString_Instance),
- // tkVariant
- (Selector: False; Instance: @Comparer_Variant_Instance),
- // tkArray
- (Selector: True; SelectorInstance: @TComparerService.SelectBinaryComparer),
- // tkRecord
- (Selector: True; SelectorInstance: @TComparerService.SelectBinaryComparer),
- // tkInterface
- (Selector: False; Instance: @Comparer_Pointer_Instance),
- // tkClass
- (Selector: False; Instance: @Comparer_Pointer_Instance),
- // tkObject
- (Selector: True; SelectorInstance: @TComparerService.SelectBinaryComparer),
- // tkWChar
- (Selector: False; Instance: @Comparer_UInt16_Instance),
- // tkBool
- (Selector: True; SelectorInstance: @TComparerService.SelectIntegerComparer),
- // tkInt64
- (Selector: False; Instance: @Comparer_Int64_Instance),
- // tkQWord
- (Selector: False; Instance: @Comparer_UInt64_Instance),
- // tkDynArray
- (Selector: True; SelectorInstance: @TComparerService.SelectDynArrayComparer),
- // tkInterfaceRaw
- (Selector: False; Instance: @Comparer_Pointer_Instance),
- // tkProcVar
- (Selector: False; Instance: @Comparer_Pointer_Instance),
- // tkUString
- (Selector: False; Instance: @Comparer_UnicodeString_Instance),
- // tkUChar - WTF? ... http://bugs.freepascal.org/view.php?id=24609
- (Selector: False; Instance: @Comparer_UInt16_Instance), // <- unsure maybe Comparer_UInt32_Instance
- // tkHelper
- (Selector: False; Instance: @Comparer_Pointer_Instance),
- // tkFile
- (Selector: True; SelectorInstance: @TComparerService.SelectBinaryComparer), // <- unsure what type?
- // tkClassRef
- (Selector: False; Instance: @Comparer_Pointer_Instance),
- // tkPointer
- (Selector: False; Instance: @Comparer_Pointer_Instance)
- );
- public
- class function LookupComparer(ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer; static;
- end;
- THashService = class(TComparerService)
- public
- class function LookupEqualityComparer(ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer; virtual; abstract;
- end;
- TExtendedHashService = class(THashService)
- public
- class function LookupEqualityComparer(ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer; override;
- class function LookupExtendedEqualityComparer(ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer; virtual; abstract;
- end;
- {$DEFINE HASH_FACTORY := PPEqualityComparerVMT(Self)^.__ClassRef}
- {$DEFINE EXTENDED_HASH_FACTORY := PPExtendedEqualityComparerVMT(Self)^.__ClassRef}
- { THashService }
- THashService<T: THashFactory> = class(THashService)
- private
- class function SelectIntegerEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- class function SelectFloatEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- class function SelectShortStringEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- class function SelectBinaryEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- class function SelectDynArrayEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- private const
- // IEqualityComparer VMT templates
- {$WARNINGS OFF}
- EqualityComparer_Int8_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Int8 ; GetHashCode: @THashFactory.Int8 );
- EqualityComparer_Int16_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Int16 ; GetHashCode: @THashFactory.Int16 );
- EqualityComparer_Int32_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Int32 ; GetHashCode: @THashFactory.Int32 );
- EqualityComparer_Int64_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Int64 ; GetHashCode: @THashFactory.Int64 );
- EqualityComparer_UInt8_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UInt8 ; GetHashCode: @THashFactory.UInt8 );
- EqualityComparer_UInt16_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UInt16; GetHashCode: @THashFactory.UInt16);
- EqualityComparer_UInt32_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UInt32; GetHashCode: @THashFactory.UInt32);
- EqualityComparer_UInt64_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UInt64; GetHashCode: @THashFactory.UInt64);
- EqualityComparer_Single_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Single ; GetHashCode: @THashFactory.Single );
- EqualityComparer_Double_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Double ; GetHashCode: @THashFactory.Double );
- EqualityComparer_Extended_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Extended; GetHashCode: @THashFactory.Extended);
- EqualityComparer_Currency_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Currency; GetHashCode: @THashFactory.Currency);
- EqualityComparer_Comp_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Comp ; GetHashCode: @THashFactory.Comp );
- EqualityComparer_Binary_VMT : THashFactory.TEqualityComparerVMT = (STD_COM_TYPESIZE_INTERFACE_METHODS; Equals: @TEquals._Binary ; GetHashCode: @THashFactory.Binary );
- EqualityComparer_DynArray_VMT: THashFactory.TEqualityComparerVMT = (STD_COM_TYPESIZE_INTERFACE_METHODS; Equals: @TEquals._DynArray; GetHashCode: @THashFactory.DynArray);
- EqualityComparer_Class_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.&Class; GetHashCode: @THashFactory.&Class);
- EqualityComparer_ShortString1_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.ShortString1 ; GetHashCode: @THashFactory.ShortString1 );
- EqualityComparer_ShortString2_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.ShortString2 ; GetHashCode: @THashFactory.ShortString2 );
- EqualityComparer_ShortString3_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.ShortString3 ; GetHashCode: @THashFactory.ShortString3 );
- EqualityComparer_ShortString_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.ShortString ; GetHashCode: @THashFactory.ShortString );
- EqualityComparer_AnsiString_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.AnsiString ; GetHashCode: @THashFactory.AnsiString );
- EqualityComparer_WideString_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.WideString ; GetHashCode: @THashFactory.WideString );
- EqualityComparer_UnicodeString_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UnicodeString; GetHashCode: @THashFactory.UnicodeString);
- EqualityComparer_Method_VMT : THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Method ; GetHashCode: @THashFactory.Method );
- EqualityComparer_Variant_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Variant; GetHashCode: @THashFactory.Variant);
- EqualityComparer_Pointer_VMT: THashFactory.TEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Pointer; GetHashCode: @THashFactory.Pointer);
- {.$WARNINGS ON} // do not enable warnings ever in this unit, or you will get many warnings about uninitialized TEqualityComparerVMT fields
- private class var
- // IEqualityComparer VMT
- FEqualityComparer_Int8_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Int16_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Int32_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Int64_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_UInt8_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_UInt16_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_UInt32_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_UInt64_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Single_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Double_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Extended_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Currency_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Comp_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Binary_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_DynArray_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Class_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_ShortString1_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_ShortString2_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_ShortString3_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_ShortString_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_AnsiString_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_WideString_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_UnicodeString_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Method_VMT : THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Variant_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Pointer_VMT: THashFactory.TEqualityComparerVMT;
- FEqualityComparer_Int8_Instance : Pointer;
- FEqualityComparer_Int16_Instance : Pointer;
- FEqualityComparer_Int32_Instance : Pointer;
- FEqualityComparer_Int64_Instance : Pointer;
- FEqualityComparer_UInt8_Instance : Pointer;
- FEqualityComparer_UInt16_Instance : Pointer;
- FEqualityComparer_UInt32_Instance : Pointer;
- FEqualityComparer_UInt64_Instance : Pointer;
- FEqualityComparer_Single_Instance : Pointer;
- FEqualityComparer_Double_Instance : Pointer;
- FEqualityComparer_Extended_Instance : Pointer;
- FEqualityComparer_Currency_Instance : Pointer;
- FEqualityComparer_Comp_Instance : Pointer;
- //FEqualityComparer_Binary_Instance : Pointer; // dynamic instance
- //FEqualityComparer_DynArray_Instance : Pointer; // dynamic instance
- FEqualityComparer_ShortString1_Instance : Pointer;
- FEqualityComparer_ShortString2_Instance : Pointer;
- FEqualityComparer_ShortString3_Instance : Pointer;
- FEqualityComparer_ShortString_Instance : Pointer;
- FEqualityComparer_AnsiString_Instance : Pointer;
- FEqualityComparer_WideString_Instance : Pointer;
- FEqualityComparer_UnicodeString_Instance: Pointer;
- FEqualityComparer_Method_Instance : Pointer;
- FEqualityComparer_Variant_Instance : Pointer;
- FEqualityComparer_Pointer_Instance : Pointer;
- FEqualityComparerInstances: array[TTypeKind] of TInstance;
- private
- class constructor Create;
- public
- class function LookupEqualityComparer(ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer; override;
- end;
- { TExtendedHashService }
- TExtendedHashService<T: TExtendedHashFactory> = class(TExtendedHashService)
- private
- class function SelectIntegerEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- class function SelectFloatEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- class function SelectShortStringEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- class function SelectBinaryEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- class function SelectDynArrayEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer; override;
- private const
- // IExtendedEqualityComparer VMT templates
- {$WARNINGS OFF}
- ExtendedEqualityComparer_Int8_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Int8 ; GetHashCode: @THashFactory.Int8 ; GetHashList: @TExtendedHashFactory.Int8 );
- ExtendedEqualityComparer_Int16_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Int16 ; GetHashCode: @THashFactory.Int16 ; GetHashList: @TExtendedHashFactory.Int16 );
- ExtendedEqualityComparer_Int32_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Int32 ; GetHashCode: @THashFactory.Int32 ; GetHashList: @TExtendedHashFactory.Int32 );
- ExtendedEqualityComparer_Int64_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Int64 ; GetHashCode: @THashFactory.Int64 ; GetHashList: @TExtendedHashFactory.Int64 );
- ExtendedEqualityComparer_UInt8_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UInt8 ; GetHashCode: @THashFactory.UInt8 ; GetHashList: @TExtendedHashFactory.UInt8 );
- ExtendedEqualityComparer_UInt16_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UInt16; GetHashCode: @THashFactory.UInt16; GetHashList: @TExtendedHashFactory.UInt16);
- ExtendedEqualityComparer_UInt32_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UInt32; GetHashCode: @THashFactory.UInt32; GetHashList: @TExtendedHashFactory.UInt32);
- ExtendedEqualityComparer_UInt64_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UInt64; GetHashCode: @THashFactory.UInt64; GetHashList: @TExtendedHashFactory.UInt64);
- ExtendedEqualityComparer_Single_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Single ; GetHashCode: @THashFactory.Single ; GetHashList: @TExtendedHashFactory.Single );
- ExtendedEqualityComparer_Double_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Double ; GetHashCode: @THashFactory.Double ; GetHashList: @TExtendedHashFactory.Double );
- ExtendedEqualityComparer_Extended_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Extended; GetHashCode: @THashFactory.Extended; GetHashList: @TExtendedHashFactory.Extended);
- ExtendedEqualityComparer_Currency_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Currency; GetHashCode: @THashFactory.Currency; GetHashList: @TExtendedHashFactory.Currency);
- ExtendedEqualityComparer_Comp_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Comp ; GetHashCode: @THashFactory.Comp ; GetHashList: @TExtendedHashFactory.Comp );
- ExtendedEqualityComparer_Binary_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_COM_TYPESIZE_INTERFACE_METHODS; Equals: @TEquals._Binary ; GetHashCode: @THashFactory.Binary ; GetHashList: @TExtendedHashFactory.Binary );
- ExtendedEqualityComparer_DynArray_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_COM_TYPESIZE_INTERFACE_METHODS; Equals: @TEquals._DynArray; GetHashCode: @THashFactory.DynArray; GetHashList: @TExtendedHashFactory.DynArray);
- ExtendedEqualityComparer_Class_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.&Class; GetHashCode: @THashFactory.&Class; GetHashList: @TExtendedHashFactory.&Class);
- ExtendedEqualityComparer_ShortString1_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.ShortString1 ; GetHashCode: @THashFactory.ShortString1 ; GetHashList: @TExtendedHashFactory.ShortString1 );
- ExtendedEqualityComparer_ShortString2_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.ShortString2 ; GetHashCode: @THashFactory.ShortString2 ; GetHashList: @TExtendedHashFactory.ShortString2 );
- ExtendedEqualityComparer_ShortString3_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.ShortString3 ; GetHashCode: @THashFactory.ShortString3 ; GetHashList: @TExtendedHashFactory.ShortString3 );
- ExtendedEqualityComparer_ShortString_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.ShortString ; GetHashCode: @THashFactory.ShortString ; GetHashList: @TExtendedHashFactory.ShortString );
- ExtendedEqualityComparer_AnsiString_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.AnsiString ; GetHashCode: @THashFactory.AnsiString ; GetHashList: @TExtendedHashFactory.AnsiString );
- ExtendedEqualityComparer_WideString_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.WideString ; GetHashCode: @THashFactory.WideString ; GetHashList: @TExtendedHashFactory.WideString );
- ExtendedEqualityComparer_UnicodeString_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.UnicodeString; GetHashCode: @THashFactory.UnicodeString; GetHashList: @TExtendedHashFactory.UnicodeString);
- ExtendedEqualityComparer_Method_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Method ; GetHashCode: @THashFactory.Method ; GetHashList: @TExtendedHashFactory.Method );
- ExtendedEqualityComparer_Variant_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Variant; GetHashCode: @THashFactory.Variant; GetHashList: @TExtendedHashFactory.Variant);
- ExtendedEqualityComparer_Pointer_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT = (STD_RAW_INTERFACE_METHODS; Equals: @TEquals.Pointer; GetHashCode: @THashFactory.Pointer; GetHashList: @TExtendedHashFactory.Pointer);
- {.$WARNINGS ON} // do not enable warnings ever in this unit, or you will get many warnings about uninitialized TEqualityComparerVMT fields
- private class var
- // IExtendedEqualityComparer VMT
- FExtendedEqualityComparer_Int8_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Int16_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Int32_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Int64_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_UInt8_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_UInt16_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_UInt32_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_UInt64_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Single_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Double_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Extended_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Currency_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Comp_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Binary_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_DynArray_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Class_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_ShortString1_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_ShortString2_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_ShortString3_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_ShortString_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_AnsiString_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_WideString_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_UnicodeString_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Method_VMT : TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Variant_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Pointer_VMT: TExtendedHashFactory.TExtendedEqualityComparerVMT;
- FExtendedEqualityComparer_Int8_Instance : Pointer;
- FExtendedEqualityComparer_Int16_Instance : Pointer;
- FExtendedEqualityComparer_Int32_Instance : Pointer;
- FExtendedEqualityComparer_Int64_Instance : Pointer;
- FExtendedEqualityComparer_UInt8_Instance : Pointer;
- FExtendedEqualityComparer_UInt16_Instance : Pointer;
- FExtendedEqualityComparer_UInt32_Instance : Pointer;
- FExtendedEqualityComparer_UInt64_Instance : Pointer;
- FExtendedEqualityComparer_Single_Instance : Pointer;
- FExtendedEqualityComparer_Double_Instance : Pointer;
- FExtendedEqualityComparer_Extended_Instance : Pointer;
- FExtendedEqualityComparer_Currency_Instance : Pointer;
- FExtendedEqualityComparer_Comp_Instance : Pointer;
- //FExtendedEqualityComparer_Binary_Instance : Pointer; // dynamic instance
- //FExtendedEqualityComparer_DynArray_Instance : Pointer; // dynamic instance
- FExtendedEqualityComparer_ShortString1_Instance : Pointer;
- FExtendedEqualityComparer_ShortString2_Instance : Pointer;
- FExtendedEqualityComparer_ShortString3_Instance : Pointer;
- FExtendedEqualityComparer_ShortString_Instance : Pointer;
- FExtendedEqualityComparer_AnsiString_Instance : Pointer;
- FExtendedEqualityComparer_WideString_Instance : Pointer;
- FExtendedEqualityComparer_UnicodeString_Instance: Pointer;
- FExtendedEqualityComparer_Method_Instance : Pointer;
- FExtendedEqualityComparer_Variant_Instance : Pointer;
- FExtendedEqualityComparer_Pointer_Instance : Pointer;
- // all instances
- FExtendedEqualityComparerInstances: array[TTypeKind] of TInstance;
- private
- class constructor Create;
- public
- class function LookupExtendedEqualityComparer(ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer; override;
- end;
- TOnEqualityComparison<T> = function(const ALeft, ARight: T): Boolean of object;
- TEqualityComparisonFunc<T> = function(const ALeft, ARight: T): Boolean;
- TOnHasher<T> = function(const AValue: T): UInt32 of object;
- TOnExtendedHasher<T> = procedure(const AValue: T; AHashList: PUInt32) of object;
- THasherFunc<T> = function(const AValue: T): UInt32;
- TExtendedHasherFunc<T> = procedure(const AValue: T; AHashList: PUInt32);
- TEqualityComparer<T> = class(TInterfacedObject, IEqualityComparer<T>)
- public
- class function Default: IEqualityComparer<T>; static; overload;
- class function Default(AHashFactoryClass: THashFactoryClass): IEqualityComparer<T>; static; overload;
- class function Construct(const AEqualityComparison: TOnEqualityComparison<T>;
- const AHasher: TOnHasher<T>): IEqualityComparer<T>; overload;
- class function Construct(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AHasher: THasherFunc<T>): IEqualityComparer<T>; overload;
- function Equals(const ALeft, ARight: T): Boolean; virtual; overload; abstract;
- function GetHashCode(const AValue: T): UInt32; virtual; overload; abstract;
- end;
- { TDelegatedEqualityComparerEvent }
- TDelegatedEqualityComparerEvents<T> = class(TEqualityComparer<T>)
- private
- FEqualityComparison: TOnEqualityComparison<T>;
- FHasher: TOnHasher<T>;
- public
- function Equals(const ALeft, ARight: T): Boolean; override;
- function GetHashCode(const AValue: T): UInt32; override;
- constructor Create(const AEqualityComparison: TOnEqualityComparison<T>;
- const AHasher: TOnHasher<T>);
- end;
- TDelegatedEqualityComparerFunc<T> = class(TEqualityComparer<T>)
- private
- FEqualityComparison: TEqualityComparisonFunc<T>;
- FHasher: THasherFunc<T>;
- public
- function Equals(const ALeft, ARight: T): Boolean; override;
- function GetHashCode(const AValue: T): UInt32; override;
- constructor Create(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AHasher: THasherFunc<T>);
- end;
- { TExtendedEqualityComparer }
- TExtendedEqualityComparer<T> = class(TEqualityComparer<T>, IExtendedEqualityComparer<T>)
- public
- class function Default: IExtendedEqualityComparer<T>; static; overload; reintroduce;
- class function Default(AExtenedHashFactoryClass: TExtendedHashFactoryClass): IExtendedEqualityComparer<T>; static; overload; reintroduce;
- class function Construct(const AEqualityComparison: TOnEqualityComparison<T>;
- const AHasher: TOnHasher<T>; const AExtendedHasher: TOnExtendedHasher<T>): IExtendedEqualityComparer<T>; overload; reintroduce;
- class function Construct(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AHasher: THasherFunc<T>; const AExtendedHasher: TExtendedHasherFunc<T>): IExtendedEqualityComparer<T>; overload; reintroduce;
- class function Construct(const AEqualityComparison: TOnEqualityComparison<T>;
- const AExtendedHasher: TOnExtendedHasher<T>): IExtendedEqualityComparer<T>; overload; reintroduce;
- class function Construct(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AExtendedHasher: TExtendedHasherFunc<T>): IExtendedEqualityComparer<T>; overload; reintroduce;
- procedure GetHashList(const AValue: T; AHashList: PUInt32); virtual; abstract;
- end;
- TDelegatedExtendedEqualityComparerEvents<T> = class(TExtendedEqualityComparer<T>)
- private
- FEqualityComparison: TOnEqualityComparison<T>;
- FHasher: TOnHasher<T>;
- FExtendedHasher: TOnExtendedHasher<T>;
- function GetHashCodeMethod(const AValue: T): UInt32;
- public
- function Equals(const ALeft, ARight: T): Boolean; override;
- function GetHashCode(const AValue: T): UInt32; override;
- procedure GetHashList(const AValue: T; AHashList: PUInt32); override;
- constructor Create(const AEqualityComparison: TOnEqualityComparison<T>;
- const AHasher: TOnHasher<T>; const AExtendedHasher: TOnExtendedHasher<T>); overload;
- constructor Create(const AEqualityComparison: TOnEqualityComparison<T>;
- const AExtendedHasher: TOnExtendedHasher<T>); overload;
- end;
- TDelegatedExtendedEqualityComparerFunc<T> = class(TExtendedEqualityComparer<T>)
- private
- FEqualityComparison: TEqualityComparisonFunc<T>;
- FHasher: THasherFunc<T>;
- FExtendedHasher: TExtendedHasherFunc<T>;
- public
- function Equals(const ALeft, ARight: T): Boolean; override;
- function GetHashCode(const AValue: T): UInt32; override;
- procedure GetHashList(const AValue: T; AHashList: PUInt32); override;
- constructor Create(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AHasher: THasherFunc<T>; const AExtendedHasher: TExtendedHasherFunc<T>); overload;
- constructor Create(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AExtendedHasher: TExtendedHasherFunc<T>); overload;
- end;
- TBinaryComparer<T> = class(TInterfacedObject, IComparer<T>)
- public
- function Compare(const ALeft, ARight: T): Integer;
- end;
- TBinaryEqualityComparer<T> = class(TInterfacedObject, IEqualityComparer<T>)
- private
- FHashFactory: THashFactoryClass;
- public
- constructor Create(AHashFactoryClass: THashFactoryClass);
- function Equals(const ALeft, ARight: T): Boolean;
- function GetHashCode(const AValue: T): UInt32;
- end;
- TBinaryExtendedEqualityComparer<T> = class(TBinaryEqualityComparer<T>, IExtendedEqualityComparer<T>)
- private
- FExtendedHashFactory: TExtendedHashFactoryClass;
- public
- constructor Create(AHashFactoryClass: TExtendedHashFactoryClass);
- procedure GetHashList(const AValue: T; AHashList: PUInt32);
- end;
- { TDelphiHashFactory }
- TDelphiHashFactory = class(THashFactory)
- public
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- end;
- { TGenericsHashFactory }
- TGenericsHashFactory = class(THashFactory)
- public
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- end;
- { TxxHash32HashFactory }
- TxxHash32HashFactory = class(THashFactory)
- public
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- end;
- { TxxHash32PascalHashFactory }
- TxxHash32PascalHashFactory = class(THashFactory)
- public
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- end;
- { TAdler32HashFactory }
- TAdler32HashFactory = class(THashFactory)
- public
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- end;
- { TSdbmHashFactory }
- TSdbmHashFactory = class(THashFactory)
- public
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- end;
- { TSdbmHashFactory }
- TSimpleChecksumFactory = class(THashFactory)
- public
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- end;
- { TDelphiDoubleHashFactory }
- TDelphiDoubleHashFactory = class(TExtendedHashFactory)
- public
- const MAX_HASHLIST_COUNT = 2;
- const HASH_FUNCTIONS_COUNT = 1;
- const HASHLIST_COUNT_PER_FUNCTION: array[1..HASH_FUNCTIONS_COUNT] of Integer = (2);
- const HASH_FUNCTIONS_MASK_SIZE = 1;
- const HASH_FUNCTIONS_MASK = 1; // 00000001b
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- class procedure GetHashList(AKey: Pointer; ASize: SizeInt; AHashList: PUInt32; AOptions: TGetHashListOptions = []); override;
- end;
- TDelphiQuadrupleHashFactory = class(TExtendedHashFactory)
- public
- const MAX_HASHLIST_COUNT = 4;
- const HASH_FUNCTIONS_COUNT = 2;
- const HASHLIST_COUNT_PER_FUNCTION: array[1..HASH_FUNCTIONS_COUNT] of Integer = (2, 2);
- const HASH_FUNCTIONS_MASK_SIZE = 2;
- const HASH_FUNCTIONS_MASK = 3; // 00000011b
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- class procedure GetHashList(AKey: Pointer; ASize: SizeInt; AHashList: PUInt32; AOptions: TGetHashListOptions = []); override;
- end;
- TDelphiSixfoldHashFactory = class(TExtendedHashFactory)
- public
- const MAX_HASHLIST_COUNT = 6;
- const HASH_FUNCTIONS_COUNT = 3;
- const HASHLIST_COUNT_PER_FUNCTION: array[1..HASH_FUNCTIONS_COUNT] of Integer = (2, 2, 2);
- const HASH_FUNCTIONS_MASK_SIZE = 3;
- const HASH_FUNCTIONS_MASK = 7; // 00000111b
- class function GetHashService: THashServiceClass; override;
- class function GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32 = 0): UInt32; override;
- class procedure GetHashList(AKey: Pointer; ASize: SizeInt; AHashList: PUInt32; AOptions: TGetHashListOptions = []); override;
- end;
- TDefaultHashFactory = TGenericsHashFactory;
- TDefaultGenericInterface = (giComparer, giEqualityComparer, giExtendedEqualityComparer);
- TCustomComparer<T> = class(TSingletonImplementation, IComparer<T>, IEqualityComparer<T>, IExtendedEqualityComparer<T>)
- protected
- function Compare(const Left, Right: T): Integer; virtual; abstract;
- function Equals(const Left, Right: T): Boolean; reintroduce; overload; virtual; abstract;
- function GetHashCode(const Value: T): UInt32; reintroduce; overload; virtual; abstract;
- procedure GetHashList(const Value: T; AHashList: PUInt32); virtual; abstract;
- end;
- TOrdinalComparer<T, THashFactory> = class(TCustomComparer<T>)
- protected class var
- FComparer: IComparer<T>;
- FEqualityComparer: IEqualityComparer<T>;
- FExtendedEqualityComparer: IExtendedEqualityComparer<T>;
- class constructor Create;
- public
- class function Ordinal: TCustomComparer<T>; virtual; abstract;
- end;
- // TGStringComparer will be renamed to TStringComparer -> bug #26030
- // anyway class var can't be used safely -> bug #24848
- TGStringComparer<T, THashFactory> = class(TOrdinalComparer<T, THashFactory>)
- private class var
- FOrdinal: TCustomComparer<T>;
- class destructor Destroy;
- public
- class function Ordinal: TCustomComparer<T>; override;
- end;
- TGStringComparer<T> = class(TGStringComparer<T, TDelphiQuadrupleHashFactory>);
- TStringComparer = class(TGStringComparer<string>);
- TAnsiStringComparer = class(TGStringComparer<AnsiString>);
- TUnicodeStringComparer = class(TGStringComparer<UnicodeString>);
- { TGOrdinalStringComparer }
- // TGOrdinalStringComparer will be renamed to TOrdinalStringComparer -> bug #26030
- // anyway class var can't be used safely -> bug #24848
- TGOrdinalStringComparer<T, THashFactory> = class(TGStringComparer<T, THashFactory>)
- public
- function Compare(const ALeft, ARight: T): Integer; override;
- function Equals(const ALeft, ARight: T): Boolean; overload; override;
- function GetHashCode(const AValue: T): UInt32; overload; override;
- procedure GetHashList(const AValue: T; AHashList: PUInt32); override;
- end;
- TGOrdinalStringComparer<T> = class(TGOrdinalStringComparer<T, TDelphiQuadrupleHashFactory>);
- TOrdinalStringComparer = class(TGOrdinalStringComparer<string>);
- TGIStringComparer<T, THashFactory> = class(TOrdinalComparer<T, THashFactory>)
- private class var
- FOrdinal: TCustomComparer<T>;
- class destructor Destroy;
- public
- class function Ordinal: TCustomComparer<T>; override;
- end;
- TGIStringComparer<T> = class(TGIStringComparer<T, TDelphiQuadrupleHashFactory>);
- TIStringComparer = class(TGIStringComparer<string>);
- TIAnsiStringComparer = class(TGIStringComparer<AnsiString>);
- TIUnicodeStringComparer = class(TGIStringComparer<UnicodeString>);
- TGOrdinalIStringComparer<T, THashFactory> = class(TGIStringComparer<T, THashFactory>)
- public
- function Compare(const ALeft, ARight: T): Integer; override;
- function Equals(const ALeft, ARight: T): Boolean; overload; override;
- function GetHashCode(const AValue: T): UInt32; overload; override;
- procedure GetHashList(const AValue: T; AHashList: PUInt32); override;
- end;
- TGOrdinalIStringComparer<T> = class(TGOrdinalIStringComparer<T, TDelphiQuadrupleHashFactory>);
- TOrdinalIStringComparer = class(TGOrdinalIStringComparer<string>);
- // Delphi version of Bob Jenkins Hash
- function BobJenkinsHash(const AData; ALength, AInitData: Integer): Integer; // same result as HashLittle_Delphi, just different interface
- function BinaryCompare(const ALeft, ARight: Pointer; ASize: PtrUInt): Integer; inline;
- function _LookupVtableInfo(AGInterface: TDefaultGenericInterface; ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer; inline;
- function _LookupVtableInfoEx(AGInterface: TDefaultGenericInterface; ATypeInfo: PTypeInfo; ASize: SizeInt;
- AFactory: THashFactoryClass): Pointer;
- implementation
- { TComparer<T> }
- class function TComparer<T>.Default: IComparer<T>;
- begin
- if GetTypeKind(T) in TComparerService.UseBinaryMethods then begin
- Result := TBinaryComparer<T>.Create
- end else
- Result := _LookupVtableInfo(giComparer, TypeInfo(T), SizeOf(T));
- end;
- class function TComparer<T>.Construct(const AComparison: TOnComparison<T>): IComparer<T>;
- begin
- Result := TDelegatedComparerEvents<T>.Create(AComparison);
- end;
- class function TComparer<T>.Construct(const AComparison: TComparisonFunc<T>): IComparer<T>;
- begin
- Result := TDelegatedComparerFunc<T>.Create(AComparison);
- end;
- function TDelegatedComparerEvents<T>.Compare(const ALeft, ARight: T): Integer;
- begin
- Result := FComparison(ALeft, ARight);
- end;
- constructor TDelegatedComparerEvents<T>.Create(AComparison: TOnComparison<T>);
- begin
- FComparison := AComparison;
- end;
- function TDelegatedComparerFunc<T>.Compare(const ALeft, ARight: T): Integer;
- begin
- Result := FComparison(ALeft, ARight);
- end;
- constructor TDelegatedComparerFunc<T>.Create(AComparison: TComparisonFunc<T>);
- begin
- FComparison := AComparison;
- end;
- { TInterface }
- function TInterface.QueryInterface(constref IID: TGUID; out Obj): HResult;
- begin
- Result := E_NOINTERFACE;
- end;
- { TRawInterface }
- function TRawInterface._AddRef: LongInt;
- begin
- Result := -1;
- end;
- function TRawInterface._Release: LongInt;
- begin
- Result := -1;
- end;
- { TComTypeSizeInterface }
- function TComTypeSizeInterface._AddRef: LongInt;
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- begin
- Result := InterLockedIncrement(_self.RefCount);
- end;
- function TComTypeSizeInterface._Release: LongInt;
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- begin
- Result := InterLockedDecrement(_self.RefCount);
- if _self.RefCount = 0 then
- Dispose(_self);
- end;
- { TSingletonImplementation }
- function TSingletonImplementation.QueryInterface(constref IID: TGUID; out Obj): HResult;
- begin
- if GetInterface(IID, Obj) then
- Result := S_OK
- else
- Result := E_NOINTERFACE;
- end;
- { TCompare }
- (***********************************************************************************************************************
- Comparers
- (**********************************************************************************************************************)
- {-----------------------------------------------------------------------------------------------------------------------
- Comparers Int8 - Int32 and UInt8 - UInt32
- {----------------------------------------------------------------------------------------------------------------------}
- class function TCompare.Integer(const ALeft, ARight: Integer): Integer;
- begin
- Result := Math.CompareValue(ALeft, ARight);
- end;
- class function TCompare.Int8(const ALeft, ARight: Int8): Integer;
- begin
- Result := ALeft - ARight;
- end;
- class function TCompare.Int16(const ALeft, ARight: Int16): Integer;
- begin
- Result := ALeft - ARight;
- end;
- class function TCompare.Int32(const ALeft, ARight: Int32): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.Int64(const ALeft, ARight: Int64): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.UInt8(const ALeft, ARight: UInt8): Integer;
- begin
- Result := System.Integer(ALeft) - System.Integer(ARight);
- end;
- class function TCompare.UInt16(const ALeft, ARight: UInt16): Integer;
- begin
- Result := System.Integer(ALeft) - System.Integer(ARight);
- end;
- class function TCompare.UInt32(const ALeft, ARight: UInt32): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.UInt64(const ALeft, ARight: UInt64): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Comparers for Float types
- {----------------------------------------------------------------------------------------------------------------------}
- class function TCompare.Single(const ALeft, ARight: Single): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.Double(const ALeft, ARight: Double): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.Extended(const ALeft, ARight: Extended): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Comparers for other number types
- {----------------------------------------------------------------------------------------------------------------------}
- class function TCompare.Currency(const ALeft, ARight: Currency): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.Comp(const ALeft, ARight: Comp): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Comparers for binary data (records etc) and dynamics arrays
- {----------------------------------------------------------------------------------------------------------------------}
- class function TCompare._Binary(const ALeft, ARight): Integer;
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- begin
- Result := CompareMemRange(@ALeft, @ARight, _self.Size)
- end;
- class function TCompare._DynArray(const ALeft, ARight: Pointer): Integer;
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- LLength, LLeftLength, LRightLength: Integer;
- begin
- LLeftLength := DynArraySize(ALeft);
- LRightLength := DynArraySize(ARight);
- if LLeftLength > LRightLength then
- LLength := LRightLength
- else
- LLength := LLeftLength;
- Result := CompareMemRange(ALeft, ARight, LLength * _self.Size);
- if Result = 0 then
- Result := LLeftLength - LRightLength;
- end;
- class function TCompare.Binary(const ALeft, ARight; const ASize: SizeInt): Integer;
- begin
- Result := CompareMemRange(@ALeft, @ARight, ASize);
- end;
- class function TCompare.DynArray(const ALeft, ARight: Pointer; const AElementSize: SizeInt): Integer;
- var
- LLength, LLeftLength, LRightLength: Integer;
- begin
- LLeftLength := DynArraySize(ALeft);
- LRightLength := DynArraySize(ARight);
- if LLeftLength > LRightLength then
- LLength := LRightLength
- else
- LLength := LLeftLength;
- Result := CompareMemRange(ALeft, ARight, LLength * AElementSize);
- if Result = 0 then
- Result := LLeftLength - LRightLength;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Comparers for string types
- {----------------------------------------------------------------------------------------------------------------------}
- class function TCompare.ShortString1(const ALeft, ARight: ShortString1): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.ShortString2(const ALeft, ARight: ShortString2): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.ShortString3(const ALeft, ARight: ShortString3): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.ShortString(const ALeft, ARight: ShortString): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- class function TCompare.&String(const ALeft, ARight: String): Integer;
- begin
- Result := CompareStr(ALeft, ARight);
- end;
- class function TCompare.AnsiString(const ALeft, ARight: AnsiString): Integer;
- begin
- Result := AnsiCompareStr(ALeft, ARight);
- end;
- class function TCompare.WideString(const ALeft, ARight: WideString): Integer;
- begin
- Result := WideCompareStr(ALeft, ARight);
- end;
- class function TCompare.UnicodeString(const ALeft, ARight: UnicodeString): Integer;
- begin
- Result := UnicodeCompareStr(ALeft, ARight);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Comparers for Delegates
- {----------------------------------------------------------------------------------------------------------------------}
- class function TCompare.Method(const ALeft, ARight: TMethod): Integer;
- begin
- Result := CompareMemRange(@ALeft, @ARight, SizeOf(System.TMethod));
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Comparers for Variant
- {----------------------------------------------------------------------------------------------------------------------}
- class function TCompare.Variant(const ALeft, ARight: PVariant): Integer;
- var
- LLeftString, LRightString: string;
- begin
- try
- case VarCompareValue(ALeft^, ARight^) of
- vrGreaterThan:
- Exit(1);
- vrLessThan:
- Exit(-1);
- vrEqual:
- Exit(0);
- vrNotEqual:
- if VarIsEmpty(ALeft^) or VarIsNull(ALeft^) then
- Exit(1)
- else
- Exit(-1);
- end;
- except
- try
- LLeftString := ALeft^;
- LRightString := ARight^;
- Result := CompareStr(LLeftString, LRightString);
- except
- Result := CompareMemRange(ALeft, ARight, SizeOf(System.Variant));
- end;
- end;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Comparers for Pointer
- {----------------------------------------------------------------------------------------------------------------------}
- class function TCompare.Pointer(const ALeft, ARight: PtrUInt): Integer;
- begin
- if ALeft > ARight then
- Exit(1)
- else if ALeft < ARight then
- Exit(-1)
- else
- Exit(0);
- end;
- { TEquals }
- (***********************************************************************************************************************
- Equality Comparers
- (**********************************************************************************************************************)
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers Int8 - Int32 and UInt8 - UInt32
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals.Integer(const ALeft, ARight: Integer): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.Int8(const ALeft, ARight: Int8): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.Int16(const ALeft, ARight: Int16): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.Int32(const ALeft, ARight: Int32): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.Int64(const ALeft, ARight: Int64): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.UInt8(const ALeft, ARight: UInt8): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.UInt16(const ALeft, ARight: UInt16): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.UInt32(const ALeft, ARight: UInt32): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.UInt64(const ALeft, ARight: UInt64): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers for Float types
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals.Single(const ALeft, ARight: Single): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.Double(const ALeft, ARight: Double): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.Extended(const ALeft, ARight: Extended): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers for other number types
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals.Currency(const ALeft, ARight: Currency): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.Comp(const ALeft, ARight: Comp): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers for binary data (records etc) and dynamics arrays
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals._Binary(const ALeft, ARight): Boolean;
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- begin
- Result := CompareMem(@ALeft, @ARight, _self.Size)
- end;
- class function TEquals._DynArray(const ALeft, ARight: Pointer): Boolean;
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- LLength: Integer;
- begin
- LLength := DynArraySize(ALeft);
- if LLength <> DynArraySize(ARight) then
- Exit(False);
- Result := CompareMem(ALeft, ARight, LLength * _self.Size);
- end;
- class function TEquals.Binary(const ALeft, ARight; const ASize: SizeInt): Boolean;
- begin
- Result := CompareMem(@ALeft, @ARight, ASize);
- end;
- class function TEquals.DynArray(const ALeft, ARight: Pointer; const AElementSize: SizeInt): Boolean;
- var
- LLength: Integer;
- begin
- LLength := DynArraySize(ALeft);
- if LLength <> DynArraySize(ARight) then
- Exit(False);
- Result := CompareMem(ALeft, ARight, LLength * AElementSize);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers for classes
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals.&class(const ALeft, ARight: TObject): Boolean;
- begin
- if ALeft <> nil then
- Exit(ALeft.Equals(ARight))
- else
- Exit(ARight = nil);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers for string types
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals.ShortString1(const ALeft, ARight: ShortString1): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.ShortString2(const ALeft, ARight: ShortString2): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.ShortString3(const ALeft, ARight: ShortString3): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.&String(const ALeft, ARight: String): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.ShortString(const ALeft, ARight: ShortString): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.AnsiString(const ALeft, ARight: AnsiString): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.WideString(const ALeft, ARight: WideString): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- class function TEquals.UnicodeString(const ALeft, ARight: UnicodeString): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers for Delegates
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals.Method(const ALeft, ARight: TMethod): Boolean;
- begin
- Result := (ALeft.Code = ARight.Code) and (ALeft.Data = ARight.Data);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers for Variant
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals.Variant(const ALeft, ARight: PVariant): Boolean;
- begin
- Result := VarCompareValue(ALeft^, ARight^) = vrEqual;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- Equality Comparers for Pointer
- {----------------------------------------------------------------------------------------------------------------------}
- class function TEquals.Pointer(const ALeft, ARight: PtrUInt): Boolean;
- begin
- Result := ALeft = ARight;
- end;
- (***********************************************************************************************************************
- Hashes
- (**********************************************************************************************************************)
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode Int8 - Int32 and UInt8 - UInt32
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.Int8(const AValue: Int8): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.Int8), 0);
- end;
- class function THashFactory.Int16(const AValue: Int16): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.Int16), 0);
- end;
- class function THashFactory.Int32(const AValue: Int32): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.Int32), 0);
- end;
- class function THashFactory.Int64(const AValue: Int64): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.Int64), 0);
- end;
- class function THashFactory.UInt8(const AValue: UInt8): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.UInt8), 0);
- end;
- class function THashFactory.UInt16(const AValue: UInt16): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.UInt16), 0);
- end;
- class function THashFactory.UInt32(const AValue: UInt32): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.UInt32), 0);
- end;
- class function THashFactory.UInt64(const AValue: UInt64): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.UInt64), 0);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for Float types
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.Single(const AValue: Single): UInt32;
- var
- LMantissa: Float;
- LExponent: Integer;
- begin
- Frexp(AValue, LMantissa, LExponent);
- if LMantissa = 0 then
- LMantissa := Abs(LMantissa);
- Result := HASH_FACTORY.GetHashCode(@LMantissa, SizeOf(Math.Float), 0);
- Result := HASH_FACTORY.GetHashCode(@LExponent, SizeOf(System.Integer), Result);
- end;
- class function THashFactory.Double(const AValue: Double): UInt32;
- var
- LMantissa: Float;
- LExponent: Integer;
- begin
- Frexp(AValue, LMantissa, LExponent);
- if LMantissa = 0 then
- LMantissa := Abs(LMantissa);
- Result := HASH_FACTORY.GetHashCode(@LMantissa, SizeOf(Math.Float), 0);
- Result := HASH_FACTORY.GetHashCode(@LExponent, SizeOf(System.Integer), Result);
- end;
- class function THashFactory.Extended(const AValue: Extended): UInt32;
- var
- LMantissa: Float;
- LExponent: Integer;
- begin
- Frexp(AValue, LMantissa, LExponent);
- if LMantissa = 0 then
- LMantissa := Abs(LMantissa);
- Result := HASH_FACTORY.GetHashCode(@LMantissa, SizeOf(Math.Float), 0);
- Result := HASH_FACTORY.GetHashCode(@LExponent, SizeOf(System.Integer), Result);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for other number types
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.Currency(const AValue: Currency): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.Int64), 0);
- end;
- class function THashFactory.Comp(const AValue: Comp): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.Int64), 0);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for binary data (records etc) and dynamics arrays
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.Binary(const AValue): UInt32;
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, _self.Size, 0);
- end;
- class function THashFactory.DynArray(const AValue: Pointer): UInt32;
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- begin
- Result := HASH_FACTORY.GetHashCode(AValue, DynArraySize(AValue) * _self.Size, 0);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for classes
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.&Class(const AValue: TObject): UInt32;
- begin
- if AValue = nil then
- Exit($2A);
- Result := AValue.GetHashCode;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for string types
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.ShortString1(const AValue: ShortString1): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue[1], Length(AValue), 0);
- end;
- class function THashFactory.ShortString2(const AValue: ShortString2): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue[1], Length(AValue), 0);
- end;
- class function THashFactory.ShortString3(const AValue: ShortString3): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue[1], Length(AValue), 0);
- end;
- class function THashFactory.ShortString(const AValue: ShortString): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue[1], Length(AValue), 0);
- end;
- class function THashFactory.AnsiString(const AValue: AnsiString): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue[1], Length(AValue) * SizeOf(System.AnsiChar), 0);
- end;
- class function THashFactory.WideString(const AValue: WideString): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue[1], Length(AValue) * SizeOf(System.WideChar), 0);
- end;
- class function THashFactory.UnicodeString(const AValue: UnicodeString): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue[1], Length(AValue) * SizeOf(System.UnicodeChar), 0);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for Delegates
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.Method(const AValue: TMethod): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.TMethod), 0);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for Variant
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.Variant(const AValue: PVariant): UInt32;
- begin
- try
- Result := HASH_FACTORY.UnicodeString(AValue^);
- except
- Result := HASH_FACTORY.GetHashCode(AValue, SizeOf(System.Variant), 0);
- end;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for Pointer
- {----------------------------------------------------------------------------------------------------------------------}
- class function THashFactory.Pointer(const AValue: Pointer): UInt32;
- begin
- Result := HASH_FACTORY.GetHashCode(@AValue, SizeOf(System.Pointer), 0);
- end;
- { TExtendedHashFactory }
- (***********************************************************************************************************************
- Hashes 2
- (**********************************************************************************************************************)
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode Int8 - Int32 and UInt8 - UInt32
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.Int8(const AValue: Int8; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.Int8), AHashList, []);
- end;
- class procedure TExtendedHashFactory.Int16(const AValue: Int16; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.Int16), AHashList, []);
- end;
- class procedure TExtendedHashFactory.Int32(const AValue: Int32; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.Int32), AHashList, []);
- end;
- class procedure TExtendedHashFactory.Int64(const AValue: Int64; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.Int64), AHashList, []);
- end;
- class procedure TExtendedHashFactory.UInt8(const AValue: UInt8; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.UInt8), AHashList, []);
- end;
- class procedure TExtendedHashFactory.UInt16(const AValue: UInt16; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.UInt16), AHashList, []);
- end;
- class procedure TExtendedHashFactory.UInt32(const AValue: UInt32; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.UInt32), AHashList, []);
- end;
- class procedure TExtendedHashFactory.UInt64(const AValue: UInt64; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.UInt64), AHashList, []);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for Float types
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.Single(const AValue: Single; AHashList: PUInt32);
- var
- LMantissa: Float;
- LExponent: Integer;
- begin
- Frexp(AValue, LMantissa, LExponent);
- if LMantissa = 0 then
- LMantissa := Abs(LMantissa);
- EXTENDED_HASH_FACTORY.GetHashList(@LMantissa, SizeOf(Math.Float), AHashList, []);
- EXTENDED_HASH_FACTORY.GetHashList(@LExponent, SizeOf(System.Integer), AHashList, [ghloHashListAsInitData]);
- end;
- class procedure TExtendedHashFactory.Double(const AValue: Double; AHashList: PUInt32);
- var
- LMantissa: Float;
- LExponent: Integer;
- begin
- Frexp(AValue, LMantissa, LExponent);
- if LMantissa = 0 then
- LMantissa := Abs(LMantissa);
- EXTENDED_HASH_FACTORY.GetHashList(@LMantissa, SizeOf(Math.Float), AHashList, []);
- EXTENDED_HASH_FACTORY.GetHashList(@LExponent, SizeOf(System.Integer), AHashList, [ghloHashListAsInitData]);
- end;
- class procedure TExtendedHashFactory.Extended(const AValue: Extended; AHashList: PUInt32);
- var
- LMantissa: Float;
- LExponent: Integer;
- begin
- Frexp(AValue, LMantissa, LExponent);
- if LMantissa = 0 then
- LMantissa := Abs(LMantissa);
- EXTENDED_HASH_FACTORY.GetHashList(@LMantissa, SizeOf(Math.Float), AHashList, []);
- EXTENDED_HASH_FACTORY.GetHashList(@LExponent, SizeOf(System.Integer), AHashList, [ghloHashListAsInitData]);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for other number types
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.Currency(const AValue: Currency; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.Int64), AHashList, []);
- end;
- class procedure TExtendedHashFactory.Comp(const AValue: Comp; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.Int64), AHashList, []);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for binary data (records etc) and dynamics arrays
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.Binary(const AValue; AHashList: PUInt32);
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, _self.Size, AHashList, []);
- end;
- class procedure TExtendedHashFactory.DynArray(const AValue: Pointer; AHashList: PUInt32);
- var
- _self: TComparerService.PSpoofInterfacedTypeSizeObject absolute Self;
- begin
- EXTENDED_HASH_FACTORY.GetHashList(AValue, DynArraySize(AValue) * _self.Size, AHashList, []);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for classes
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.&Class(const AValue: TObject; AHashList: PUInt32);
- var
- LValue: PtrInt;
- begin
- if AValue = nil then
- begin
- LValue := $2A;
- EXTENDED_HASH_FACTORY.GetHashList(@LValue, SizeOf(LValue), AHashList, []);
- Exit;
- end;
- LValue := AValue.GetHashCode;
- EXTENDED_HASH_FACTORY.GetHashList(@LValue, SizeOf(LValue), AHashList, []);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for string types
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.ShortString1(const AValue: ShortString1; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue[1], Length(AValue), AHashList, []);
- end;
- class procedure TExtendedHashFactory.ShortString2(const AValue: ShortString2; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue[1], Length(AValue), AHashList, []);
- end;
- class procedure TExtendedHashFactory.ShortString3(const AValue: ShortString3; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue[1], Length(AValue), AHashList, []);
- end;
- class procedure TExtendedHashFactory.ShortString(const AValue: ShortString; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue[1], Length(AValue), AHashList, []);
- end;
- class procedure TExtendedHashFactory.AnsiString(const AValue: AnsiString; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue[1], Length(AValue) * SizeOf(System.AnsiChar), AHashList, []);
- end;
- class procedure TExtendedHashFactory.WideString(const AValue: WideString; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue[1], Length(AValue) * SizeOf(System.WideChar), AHashList, []);
- end;
- class procedure TExtendedHashFactory.UnicodeString(const AValue: UnicodeString; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue[1], Length(AValue) * SizeOf(System.UnicodeChar), AHashList, []);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for Delegates
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.Method(const AValue: TMethod; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.TMethod), AHashList, []);
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for Variant
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.Variant(const AValue: PVariant; AHashList: PUInt32);
- begin
- try
- EXTENDED_HASH_FACTORY.UnicodeString(AValue^, AHashList);
- except
- EXTENDED_HASH_FACTORY.GetHashList(AValue, SizeOf(System.Variant), AHashList, []);
- end;
- end;
- {-----------------------------------------------------------------------------------------------------------------------
- GetHashCode for Pointer
- {----------------------------------------------------------------------------------------------------------------------}
- class procedure TExtendedHashFactory.Pointer(const AValue: Pointer; AHashList: PUInt32);
- begin
- EXTENDED_HASH_FACTORY.GetHashList(@AValue, SizeOf(System.Pointer), AHashList, []);
- end;
- { TComparerService }
- class function TComparerService.CreateInterface(AVMT: Pointer; ASize: SizeInt): PSpoofInterfacedTypeSizeObject;
- begin
- Result := New(PSpoofInterfacedTypeSizeObject);
- Result.VMT := AVMT;
- Result.RefCount := 0;
- Result.Size := ASize;
- end;
- class function TComparerService.SelectIntegerComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- case ATypeData.OrdType of
- otSByte:
- Exit(@Comparer_Int8_Instance);
- otUByte:
- Exit(@Comparer_UInt8_Instance);
- otSWord:
- Exit(@Comparer_Int16_Instance);
- otUWord:
- Exit(@Comparer_UInt16_Instance);
- otSLong:
- Exit(@Comparer_Int32_Instance);
- otULong:
- Exit(@Comparer_UInt32_Instance);
- else
- System.Error(reRangeError);
- Exit(nil);
- end;
- end;
- class function TComparerService.SelectInt64Comparer(ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- if ATypeData.MaxInt64Value > ATypeData.MinInt64Value then
- Exit(@Comparer_Int64_Instance)
- else
- Exit(@Comparer_UInt64_Instance);
- end;
- class function TComparerService.SelectFloatComparer(ATypeData: PTypeData;
- ASize: SizeInt): Pointer;
- begin
- case ATypeData.FloatType of
- ftSingle:
- Exit(@Comparer_Single_Instance);
- ftDouble:
- Exit(@Comparer_Double_Instance);
- ftExtended:
- Exit(@Comparer_Extended_Instance);
- ftComp:
- Exit(@Comparer_Comp_Instance);
- ftCurr:
- Exit(@Comparer_Currency_Instance);
- else
- System.Error(reRangeError);
- Exit(nil);
- end;
- end;
- class function TComparerService.SelectShortStringComparer(ATypeData: PTypeData;
- ASize: SizeInt): Pointer;
- begin
- case ASize of
- 2: Exit(@Comparer_ShortString1_Instance);
- 3: Exit(@Comparer_ShortString2_Instance);
- 4: Exit(@Comparer_ShortString3_Instance);
- else
- Exit(@Comparer_ShortString_Instance);
- end;
- end;
- class function TComparerService.SelectBinaryComparer(ATypeData: PTypeData;
- ASize: SizeInt): Pointer;
- begin
- Result := CreateInterface(@Comparer_Binary_VMT, ASize);
- end;
- class function TComparerService.SelectDynArrayComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- Result := CreateInterface(@Comparer_DynArray_VMT, ATypeData.elSize);
- end;
- class function TComparerService.LookupComparer(ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer;
- var
- LInstance: PInstance;
- begin
- if ATypeInfo = nil then
- Exit(SelectBinaryComparer(Nil, ASize))
- else
- begin
- LInstance := @ComparerInstances[ATypeInfo.Kind];
- if LInstance.Selector then
- Result := TSelectFunc(LInstance.SelectorInstance)(GetTypeData(ATypeInfo), ASize)
- else
- Result := LInstance.Instance;
- end;
- end;
- { TComparerService.TInstance }
- class function TComparerService.TInstance.Create(ASelector: Boolean;
- AInstance: Pointer): TComparerService.TInstance;
- begin
- Result.Selector := ASelector;
- Result.Instance := AInstance;
- end;
- class function TComparerService.TInstance.CreateSelector(ASelectorInstance: CodePointer): TComparerService.TInstance;
- begin
- Result.Selector := True;
- Result.SelectorInstance := ASelectorInstance;
- end;
- { TExtendedHashService }
- class function TExtendedHashService.LookupEqualityComparer(ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer;
- begin
- Result := LookupExtendedEqualityComparer(ATypeInfo, ASize);
- end;
- { THashService }
- class function THashService<T>.SelectIntegerEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- case ATypeData.OrdType of
- otSByte:
- Exit(@FEqualityComparer_Int8_Instance);
- otUByte:
- Exit(@FEqualityComparer_UInt8_Instance);
- otSWord:
- Exit(@FEqualityComparer_Int16_Instance);
- otUWord:
- Exit(@FEqualityComparer_UInt16_Instance);
- otSLong:
- Exit(@FEqualityComparer_Int32_Instance);
- otULong:
- Exit(@FEqualityComparer_UInt32_Instance);
- else
- System.Error(reRangeError);
- Exit(nil);
- end;
- end;
- class function THashService<T>.SelectFloatEqualityComparer(ATypeData: PTypeData;
- ASize: SizeInt): Pointer;
- begin
- case ATypeData.FloatType of
- ftSingle:
- Exit(@FEqualityComparer_Single_Instance);
- ftDouble:
- Exit(@FEqualityComparer_Double_Instance);
- ftExtended:
- Exit(@FEqualityComparer_Extended_Instance);
- ftComp:
- Exit(@FEqualityComparer_Comp_Instance);
- ftCurr:
- Exit(@FEqualityComparer_Currency_Instance);
- else
- System.Error(reRangeError);
- Exit(nil);
- end;
- end;
- class function THashService<T>.SelectShortStringEqualityComparer(
- ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- case ASize of
- 2: Exit(@FEqualityComparer_ShortString1_Instance);
- 3: Exit(@FEqualityComparer_ShortString2_Instance);
- 4: Exit(@FEqualityComparer_ShortString3_Instance);
- else
- Exit(@FEqualityComparer_ShortString_Instance);
- end
- end;
- class function THashService<T>.SelectBinaryEqualityComparer(ATypeData: PTypeData;
- ASize: SizeInt): Pointer;
- begin
- Result := CreateInterface(@FEqualityComparer_Binary_VMT, ASize);
- end;
- class function THashService<T>.SelectDynArrayEqualityComparer(
- ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- Result := CreateInterface(@FEqualityComparer_DynArray_VMT, ATypeData.elSize);
- end;
- class function THashService<T>.LookupEqualityComparer(ATypeInfo: PTypeInfo;
- ASize: SizeInt): Pointer;
- var
- LInstance: PInstance;
- LSelectMethod: TSelectMethod;
- begin
- if ATypeInfo = nil then
- Exit(SelectBinaryEqualityComparer(Nil, ASize))
- else
- begin
- LInstance := @FEqualityComparerInstances[ATypeInfo.Kind];
- Result := LInstance.Instance;
- if LInstance.Selector then
- begin
- TMethod(LSelectMethod).Code := LInstance.SelectorInstance;
- TMethod(LSelectMethod).Data := Self;
- Result := LSelectMethod(GetTypeData(ATypeInfo), ASize);
- end;
- end;
- end;
- class constructor THashService<T>.Create;
- begin
- FEqualityComparer_Int8_VMT := EqualityComparer_Int8_VMT ;
- FEqualityComparer_Int16_VMT := EqualityComparer_Int16_VMT ;
- FEqualityComparer_Int32_VMT := EqualityComparer_Int32_VMT ;
- FEqualityComparer_Int64_VMT := EqualityComparer_Int64_VMT ;
- FEqualityComparer_UInt8_VMT := EqualityComparer_UInt8_VMT ;
- FEqualityComparer_UInt16_VMT := EqualityComparer_UInt16_VMT ;
- FEqualityComparer_UInt32_VMT := EqualityComparer_UInt32_VMT ;
- FEqualityComparer_UInt64_VMT := EqualityComparer_UInt64_VMT ;
- FEqualityComparer_Single_VMT := EqualityComparer_Single_VMT ;
- FEqualityComparer_Double_VMT := EqualityComparer_Double_VMT ;
- FEqualityComparer_Extended_VMT := EqualityComparer_Extended_VMT ;
- FEqualityComparer_Currency_VMT := EqualityComparer_Currency_VMT ;
- FEqualityComparer_Comp_VMT := EqualityComparer_Comp_VMT ;
- FEqualityComparer_Binary_VMT := EqualityComparer_Binary_VMT ;
- FEqualityComparer_DynArray_VMT := EqualityComparer_DynArray_VMT ;
- FEqualityComparer_Class_VMT := EqualityComparer_Class_VMT ;
- FEqualityComparer_ShortString1_VMT := EqualityComparer_ShortString1_VMT ;
- FEqualityComparer_ShortString2_VMT := EqualityComparer_ShortString2_VMT ;
- FEqualityComparer_ShortString3_VMT := EqualityComparer_ShortString3_VMT ;
- FEqualityComparer_ShortString_VMT := EqualityComparer_ShortString_VMT ;
- FEqualityComparer_AnsiString_VMT := EqualityComparer_AnsiString_VMT ;
- FEqualityComparer_WideString_VMT := EqualityComparer_WideString_VMT ;
- FEqualityComparer_UnicodeString_VMT := EqualityComparer_UnicodeString_VMT;
- FEqualityComparer_Method_VMT := EqualityComparer_Method_VMT ;
- FEqualityComparer_Variant_VMT := EqualityComparer_Variant_VMT ;
- FEqualityComparer_Pointer_VMT := EqualityComparer_Pointer_VMT ;
- /////
- FEqualityComparer_Int8_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Int16_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Int32_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Int64_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_UInt8_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_UInt16_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_UInt32_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_UInt64_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Single_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Double_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Extended_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Currency_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Comp_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Binary_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_DynArray_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Class_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_ShortString1_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_ShortString2_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_ShortString3_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_ShortString_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_AnsiString_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_WideString_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_UnicodeString_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Method_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Variant_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- FEqualityComparer_Pointer_VMT.__ClassRef := THashFactoryClass(T.ClassType);
- ///////
- FEqualityComparer_Int8_Instance := @FEqualityComparer_Int8_VMT ;
- FEqualityComparer_Int16_Instance := @FEqualityComparer_Int16_VMT ;
- FEqualityComparer_Int32_Instance := @FEqualityComparer_Int32_VMT ;
- FEqualityComparer_Int64_Instance := @FEqualityComparer_Int64_VMT ;
- FEqualityComparer_UInt8_Instance := @FEqualityComparer_UInt8_VMT ;
- FEqualityComparer_UInt16_Instance := @FEqualityComparer_UInt16_VMT ;
- FEqualityComparer_UInt32_Instance := @FEqualityComparer_UInt32_VMT ;
- FEqualityComparer_UInt64_Instance := @FEqualityComparer_UInt64_VMT ;
- FEqualityComparer_Single_Instance := @FEqualityComparer_Single_VMT ;
- FEqualityComparer_Double_Instance := @FEqualityComparer_Double_VMT ;
- FEqualityComparer_Extended_Instance := @FEqualityComparer_Extended_VMT ;
- FEqualityComparer_Currency_Instance := @FEqualityComparer_Currency_VMT ;
- FEqualityComparer_Comp_Instance := @FEqualityComparer_Comp_VMT ;
- //FEqualityComparer_Binary_Instance := @FEqualityComparer_Binary_VMT ; // dynamic instance
- //FEqualityComparer_DynArray_Instance := @FEqualityComparer_DynArray_VMT ; // dynamic instance
- FEqualityComparer_ShortString1_Instance := @FEqualityComparer_ShortString1_VMT ;
- FEqualityComparer_ShortString2_Instance := @FEqualityComparer_ShortString2_VMT ;
- FEqualityComparer_ShortString3_Instance := @FEqualityComparer_ShortString3_VMT ;
- FEqualityComparer_ShortString_Instance := @FEqualityComparer_ShortString_VMT ;
- FEqualityComparer_AnsiString_Instance := @FEqualityComparer_AnsiString_VMT ;
- FEqualityComparer_WideString_Instance := @FEqualityComparer_WideString_VMT ;
- FEqualityComparer_UnicodeString_Instance := @FEqualityComparer_UnicodeString_VMT;
- FEqualityComparer_Method_Instance := @FEqualityComparer_Method_VMT ;
- FEqualityComparer_Variant_Instance := @FEqualityComparer_Variant_VMT ;
- FEqualityComparer_Pointer_Instance := @FEqualityComparer_Pointer_VMT ;
- //////
- FEqualityComparerInstances[tkUnknown] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectBinaryEqualityComparer)).Code);
- FEqualityComparerInstances[tkInteger] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectIntegerEqualityComparer)).Code);
- FEqualityComparerInstances[tkChar] := TInstance.Create(False, @FEqualityComparer_UInt8_Instance);
- FEqualityComparerInstances[tkEnumeration] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectIntegerEqualityComparer)).Code);
- FEqualityComparerInstances[tkFloat] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectFloatEqualityComparer)).Code);
- FEqualityComparerInstances[tkSet] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectBinaryEqualityComparer)).Code);
- FEqualityComparerInstances[tkMethod] := TInstance.Create(False, @FEqualityComparer_Method_Instance);
- FEqualityComparerInstances[tkSString] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectShortStringEqualityComparer)).Code);
- FEqualityComparerInstances[tkLString] := TInstance.Create(False, @FEqualityComparer_AnsiString_Instance);
- FEqualityComparerInstances[tkAString] := TInstance.Create(False, @FEqualityComparer_AnsiString_Instance);
- FEqualityComparerInstances[tkWString] := TInstance.Create(False, @FEqualityComparer_WideString_Instance);
- FEqualityComparerInstances[tkVariant] := TInstance.Create(False, @FEqualityComparer_Variant_Instance);
- FEqualityComparerInstances[tkArray] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectBinaryEqualityComparer)).Code);
- FEqualityComparerInstances[tkRecord] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectBinaryEqualityComparer)).Code);
- FEqualityComparerInstances[tkInterface] := TInstance.Create(False, @FEqualityComparer_Pointer_Instance);
- FEqualityComparerInstances[tkClass] := TInstance.Create(False, @FEqualityComparer_Pointer_Instance);
- FEqualityComparerInstances[tkObject] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectBinaryEqualityComparer)).Code);
- FEqualityComparerInstances[tkWChar] := TInstance.Create(False, @FEqualityComparer_UInt16_Instance);
- FEqualityComparerInstances[tkBool] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectIntegerEqualityComparer)).Code);
- FEqualityComparerInstances[tkInt64] := TInstance.Create(False, @FEqualityComparer_Int64_Instance);
- FEqualityComparerInstances[tkQWord] := TInstance.Create(False, @FEqualityComparer_UInt64_Instance);
- FEqualityComparerInstances[tkDynArray] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectDynArrayEqualityComparer)).Code);
- FEqualityComparerInstances[tkInterfaceRaw] := TInstance.Create(False, @FEqualityComparer_Pointer_Instance);
- FEqualityComparerInstances[tkProcVar] := TInstance.Create(False, @FEqualityComparer_Pointer_Instance);
- FEqualityComparerInstances[tkUString] := TInstance.Create(False, @FEqualityComparer_UnicodeString_Instance);
- FEqualityComparerInstances[tkUChar] := TInstance.Create(False, @FEqualityComparer_UInt16_Instance);
- FEqualityComparerInstances[tkHelper] := TInstance.Create(False, @FEqualityComparer_Pointer_Instance);
- FEqualityComparerInstances[tkFile] := TInstance.CreateSelector(TMethod(TSelectMethod(THashService<T>.SelectBinaryEqualityComparer)).Code);
- FEqualityComparerInstances[tkClassRef] := TInstance.Create(False, @FEqualityComparer_Pointer_Instance);
- FEqualityComparerInstances[tkPointer] := TInstance.Create(False, @FEqualityComparer_Pointer_Instance)
- end;
- { TExtendedHashService }
- class function TExtendedHashService<T>.SelectIntegerEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- case ATypeData.OrdType of
- otSByte:
- Exit(@FExtendedEqualityComparer_Int8_Instance);
- otUByte:
- Exit(@FExtendedEqualityComparer_UInt8_Instance);
- otSWord:
- Exit(@FExtendedEqualityComparer_Int16_Instance);
- otUWord:
- Exit(@FExtendedEqualityComparer_UInt16_Instance);
- otSLong:
- Exit(@FExtendedEqualityComparer_Int32_Instance);
- otULong:
- Exit(@FExtendedEqualityComparer_UInt32_Instance);
- else
- System.Error(reRangeError);
- Exit(nil);
- end;
- end;
- class function TExtendedHashService<T>.SelectFloatEqualityComparer(ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- case ATypeData.FloatType of
- ftSingle:
- Exit(@FExtendedEqualityComparer_Single_Instance);
- ftDouble:
- Exit(@FExtendedEqualityComparer_Double_Instance);
- ftExtended:
- Exit(@FExtendedEqualityComparer_Extended_Instance);
- ftComp:
- Exit(@FExtendedEqualityComparer_Comp_Instance);
- ftCurr:
- Exit(@FExtendedEqualityComparer_Currency_Instance);
- else
- System.Error(reRangeError);
- Exit(nil);
- end;
- end;
- class function TExtendedHashService<T>.SelectShortStringEqualityComparer(ATypeData: PTypeData;
- ASize: SizeInt): Pointer;
- begin
- case ASize of
- 2: Exit(@FExtendedEqualityComparer_ShortString1_Instance);
- 3: Exit(@FExtendedEqualityComparer_ShortString2_Instance);
- 4: Exit(@FExtendedEqualityComparer_ShortString3_Instance);
- else
- Exit(@FExtendedEqualityComparer_ShortString_Instance);
- end
- end;
- class function TExtendedHashService<T>.SelectBinaryEqualityComparer(ATypeData: PTypeData;
- ASize: SizeInt): Pointer;
- begin
- Result := CreateInterface(@FExtendedEqualityComparer_Binary_VMT, ASize);
- end;
- class function TExtendedHashService<T>.SelectDynArrayEqualityComparer(
- ATypeData: PTypeData; ASize: SizeInt): Pointer;
- begin
- Result := CreateInterface(@FExtendedEqualityComparer_DynArray_VMT, ATypeData.elSize);
- end;
- class function TExtendedHashService<T>.LookupExtendedEqualityComparer(
- ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer;
- var
- LInstance: PInstance;
- LSelectMethod: TSelectMethod;
- begin
- if ATypeInfo = nil then
- Exit(SelectBinaryEqualityComparer(Nil, ASize))
- else
- begin
- LInstance := @FExtendedEqualityComparerInstances[ATypeInfo.Kind];
- Result := LInstance.Instance;
- if LInstance.Selector then
- begin
- TMethod(LSelectMethod).Code := LInstance.SelectorInstance;
- TMethod(LSelectMethod).Data := Self;
- Result := LSelectMethod(GetTypeData(ATypeInfo), ASize);
- end;
- end;
- end;
- class constructor TExtendedHashService<T>.Create;
- begin
- FExtendedEqualityComparer_Int8_VMT := ExtendedEqualityComparer_Int8_VMT ;
- FExtendedEqualityComparer_Int16_VMT := ExtendedEqualityComparer_Int16_VMT ;
- FExtendedEqualityComparer_Int32_VMT := ExtendedEqualityComparer_Int32_VMT ;
- FExtendedEqualityComparer_Int64_VMT := ExtendedEqualityComparer_Int64_VMT ;
- FExtendedEqualityComparer_UInt8_VMT := ExtendedEqualityComparer_UInt8_VMT ;
- FExtendedEqualityComparer_UInt16_VMT := ExtendedEqualityComparer_UInt16_VMT ;
- FExtendedEqualityComparer_UInt32_VMT := ExtendedEqualityComparer_UInt32_VMT ;
- FExtendedEqualityComparer_UInt64_VMT := ExtendedEqualityComparer_UInt64_VMT ;
- FExtendedEqualityComparer_Single_VMT := ExtendedEqualityComparer_Single_VMT ;
- FExtendedEqualityComparer_Double_VMT := ExtendedEqualityComparer_Double_VMT ;
- FExtendedEqualityComparer_Extended_VMT := ExtendedEqualityComparer_Extended_VMT ;
- FExtendedEqualityComparer_Currency_VMT := ExtendedEqualityComparer_Currency_VMT ;
- FExtendedEqualityComparer_Comp_VMT := ExtendedEqualityComparer_Comp_VMT ;
- FExtendedEqualityComparer_Binary_VMT := ExtendedEqualityComparer_Binary_VMT ;
- FExtendedEqualityComparer_DynArray_VMT := ExtendedEqualityComparer_DynArray_VMT ;
- FExtendedEqualityComparer_Class_VMT := ExtendedEqualityComparer_Class_VMT ;
- FExtendedEqualityComparer_ShortString1_VMT := ExtendedEqualityComparer_ShortString1_VMT ;
- FExtendedEqualityComparer_ShortString2_VMT := ExtendedEqualityComparer_ShortString2_VMT ;
- FExtendedEqualityComparer_ShortString3_VMT := ExtendedEqualityComparer_ShortString3_VMT ;
- FExtendedEqualityComparer_ShortString_VMT := ExtendedEqualityComparer_ShortString_VMT ;
- FExtendedEqualityComparer_AnsiString_VMT := ExtendedEqualityComparer_AnsiString_VMT ;
- FExtendedEqualityComparer_WideString_VMT := ExtendedEqualityComparer_WideString_VMT ;
- FExtendedEqualityComparer_UnicodeString_VMT := ExtendedEqualityComparer_UnicodeString_VMT;
- FExtendedEqualityComparer_Method_VMT := ExtendedEqualityComparer_Method_VMT ;
- FExtendedEqualityComparer_Variant_VMT := ExtendedEqualityComparer_Variant_VMT ;
- FExtendedEqualityComparer_Pointer_VMT := ExtendedEqualityComparer_Pointer_VMT ;
- /////
- FExtendedEqualityComparer_Int8_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Int16_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Int32_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Int64_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_UInt8_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_UInt16_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_UInt32_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_UInt64_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Single_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Double_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Extended_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Currency_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Comp_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Binary_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_DynArray_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Class_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_ShortString1_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_ShortString2_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_ShortString3_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_ShortString_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_AnsiString_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_WideString_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_UnicodeString_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Method_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Variant_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- FExtendedEqualityComparer_Pointer_VMT.__ClassRef := TExtendedHashFactoryClass(T.ClassType);
- ///////
- FExtendedEqualityComparer_Int8_Instance := @FExtendedEqualityComparer_Int8_VMT ;
- FExtendedEqualityComparer_Int16_Instance := @FExtendedEqualityComparer_Int16_VMT ;
- FExtendedEqualityComparer_Int32_Instance := @FExtendedEqualityComparer_Int32_VMT ;
- FExtendedEqualityComparer_Int64_Instance := @FExtendedEqualityComparer_Int64_VMT ;
- FExtendedEqualityComparer_UInt8_Instance := @FExtendedEqualityComparer_UInt8_VMT ;
- FExtendedEqualityComparer_UInt16_Instance := @FExtendedEqualityComparer_UInt16_VMT ;
- FExtendedEqualityComparer_UInt32_Instance := @FExtendedEqualityComparer_UInt32_VMT ;
- FExtendedEqualityComparer_UInt64_Instance := @FExtendedEqualityComparer_UInt64_VMT ;
- FExtendedEqualityComparer_Single_Instance := @FExtendedEqualityComparer_Single_VMT ;
- FExtendedEqualityComparer_Double_Instance := @FExtendedEqualityComparer_Double_VMT ;
- FExtendedEqualityComparer_Extended_Instance := @FExtendedEqualityComparer_Extended_VMT ;
- FExtendedEqualityComparer_Currency_Instance := @FExtendedEqualityComparer_Currency_VMT ;
- FExtendedEqualityComparer_Comp_Instance := @FExtendedEqualityComparer_Comp_VMT ;
- //FExtendedEqualityComparer_Binary_Instance := @FExtendedEqualityComparer_Binary_VMT ; // dynamic instance
- //FExtendedEqualityComparer_DynArray_Instance := @FExtendedEqualityComparer_DynArray_VMT ; // dynamic instance
- FExtendedEqualityComparer_ShortString1_Instance := @FExtendedEqualityComparer_ShortString1_VMT ;
- FExtendedEqualityComparer_ShortString2_Instance := @FExtendedEqualityComparer_ShortString2_VMT ;
- FExtendedEqualityComparer_ShortString3_Instance := @FExtendedEqualityComparer_ShortString3_VMT ;
- FExtendedEqualityComparer_ShortString_Instance := @FExtendedEqualityComparer_ShortString_VMT ;
- FExtendedEqualityComparer_AnsiString_Instance := @FExtendedEqualityComparer_AnsiString_VMT ;
- FExtendedEqualityComparer_WideString_Instance := @FExtendedEqualityComparer_WideString_VMT ;
- FExtendedEqualityComparer_UnicodeString_Instance := @FExtendedEqualityComparer_UnicodeString_VMT;
- FExtendedEqualityComparer_Method_Instance := @FExtendedEqualityComparer_Method_VMT ;
- FExtendedEqualityComparer_Variant_Instance := @FExtendedEqualityComparer_Variant_VMT ;
- FExtendedEqualityComparer_Pointer_Instance := @FExtendedEqualityComparer_Pointer_VMT ;
- //////
- FExtendedEqualityComparerInstances[tkUnknown] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectBinaryEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkInteger] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectIntegerEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkChar] := TInstance.Create(False, @FExtendedEqualityComparer_UInt8_Instance);
- FExtendedEqualityComparerInstances[tkEnumeration] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectIntegerEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkFloat] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectFloatEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkSet] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectBinaryEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkMethod] := TInstance.Create(False, @FExtendedEqualityComparer_Method_Instance);
- FExtendedEqualityComparerInstances[tkSString] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectShortStringEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkLString] := TInstance.Create(False, @FExtendedEqualityComparer_AnsiString_Instance);
- FExtendedEqualityComparerInstances[tkAString] := TInstance.Create(False, @FExtendedEqualityComparer_AnsiString_Instance);
- FExtendedEqualityComparerInstances[tkWString] := TInstance.Create(False, @FExtendedEqualityComparer_WideString_Instance);
- FExtendedEqualityComparerInstances[tkVariant] := TInstance.Create(False, @FExtendedEqualityComparer_Variant_Instance);
- FExtendedEqualityComparerInstances[tkArray] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectBinaryEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkRecord] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectBinaryEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkInterface] := TInstance.Create(False, @FExtendedEqualityComparer_Pointer_Instance);
- FExtendedEqualityComparerInstances[tkClass] := TInstance.Create(False, @FExtendedEqualityComparer_Pointer_Instance);
- FExtendedEqualityComparerInstances[tkObject] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectBinaryEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkWChar] := TInstance.Create(False, @FExtendedEqualityComparer_UInt16_Instance);
- FExtendedEqualityComparerInstances[tkBool] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectIntegerEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkInt64] := TInstance.Create(False, @FExtendedEqualityComparer_Int64_Instance);
- FExtendedEqualityComparerInstances[tkQWord] := TInstance.Create(False, @FExtendedEqualityComparer_UInt64_Instance);
- FExtendedEqualityComparerInstances[tkDynArray] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectDynArrayEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkInterfaceRaw] := TInstance.Create(False, @FExtendedEqualityComparer_Pointer_Instance);
- FExtendedEqualityComparerInstances[tkProcVar] := TInstance.Create(False, @FExtendedEqualityComparer_Pointer_Instance);
- FExtendedEqualityComparerInstances[tkUString] := TInstance.Create(False, @FExtendedEqualityComparer_UnicodeString_Instance);
- FExtendedEqualityComparerInstances[tkUChar] := TInstance.Create(False, @FExtendedEqualityComparer_UInt16_Instance);
- FExtendedEqualityComparerInstances[tkHelper] := TInstance.Create(False, @FExtendedEqualityComparer_Pointer_Instance);
- FExtendedEqualityComparerInstances[tkFile] := TInstance.CreateSelector(TMethod(TSelectMethod(TExtendedHashService<T>.SelectBinaryEqualityComparer)).Code);
- FExtendedEqualityComparerInstances[tkClassRef] := TInstance.Create(False, @FExtendedEqualityComparer_Pointer_Instance);
- FExtendedEqualityComparerInstances[tkPointer] := TInstance.Create(False, @FExtendedEqualityComparer_Pointer_Instance);
- end;
- { TEqualityComparer<T> }
- class function TEqualityComparer<T>.Default: IEqualityComparer<T>;
- begin
- if GetTypeKind(T) in TComparerService.UseBinaryMethods then
- Result := TBinaryEqualityComparer<T>.Create(Nil)
- else
- Result := _LookupVtableInfo(giEqualityComparer, TypeInfo(T), SizeOf(T));
- end;
- class function TEqualityComparer<T>.Default(AHashFactoryClass: THashFactoryClass): IEqualityComparer<T>;
- begin
- if GetTypeKind(T) in TComparerService.UseBinaryMethods then
- Result := TBinaryEqualityComparer<T>.Create(AHashFactoryClass)
- else if AHashFactoryClass.InheritsFrom(TExtendedHashFactory) then
- Result := _LookupVtableInfoEx(giExtendedEqualityComparer, TypeInfo(T), SizeOf(T), AHashFactoryClass)
- else if AHashFactoryClass.InheritsFrom(THashFactory) then
- Result := _LookupVtableInfoEx(giEqualityComparer, TypeInfo(T), SizeOf(T), AHashFactoryClass);
- end;
- class function TEqualityComparer<T>.Construct(const AEqualityComparison: TOnEqualityComparison<T>;
- const AHasher: TOnHasher<T>): IEqualityComparer<T>;
- begin
- Result := TDelegatedEqualityComparerEvents<T>.Create(AEqualityComparison, AHasher);
- end;
- class function TEqualityComparer<T>.Construct(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AHasher: THasherFunc<T>): IEqualityComparer<T>;
- begin
- Result := TDelegatedEqualityComparerFunc<T>.Create(AEqualityComparison, AHasher);
- end;
- { TDelegatedEqualityComparerEvents<T> }
- function TDelegatedEqualityComparerEvents<T>.Equals(const ALeft, ARight: T): Boolean;
- begin
- Result := FEqualityComparison(ALeft, ARight);
- end;
- function TDelegatedEqualityComparerEvents<T>.GetHashCode(const AValue: T): UInt32;
- begin
- Result := FHasher(AValue);
- end;
- constructor TDelegatedEqualityComparerEvents<T>.Create(const AEqualityComparison: TOnEqualityComparison<T>;
- const AHasher: TOnHasher<T>);
- begin
- FEqualityComparison := AEqualityComparison;
- FHasher := AHasher;
- end;
- { TDelegatedEqualityComparerFunc<T> }
- function TDelegatedEqualityComparerFunc<T>.Equals(const ALeft, ARight: T): Boolean;
- begin
- Result := FEqualityComparison(ALeft, ARight);
- end;
- function TDelegatedEqualityComparerFunc<T>.GetHashCode(const AValue: T): UInt32;
- begin
- Result := FHasher(AValue);
- end;
- constructor TDelegatedEqualityComparerFunc<T>.Create(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AHasher: THasherFunc<T>);
- begin
- FEqualityComparison := AEqualityComparison;
- FHasher := AHasher;
- end;
- { TDelegatedExtendedEqualityComparerEvents<T> }
- function TDelegatedExtendedEqualityComparerEvents<T>.GetHashCodeMethod(const AValue: T): UInt32;
- var
- LHashList: array[0..1] of Int32;
- LHashListParams: array[0..3] of Int16 absolute LHashList;
- begin
- LHashListParams[0] := -1;
- FExtendedHasher(AValue, @LHashList[0]);
- Result := LHashList[1];
- end;
- function TDelegatedExtendedEqualityComparerEvents<T>.Equals(const ALeft, ARight: T): Boolean;
- begin
- Result := FEqualityComparison(ALeft, ARight);
- end;
- function TDelegatedExtendedEqualityComparerEvents<T>.GetHashCode(const AValue: T): UInt32;
- begin
- Result := FHasher(AValue);
- end;
- procedure TDelegatedExtendedEqualityComparerEvents<T>.GetHashList(const AValue: T; AHashList: PUInt32);
- begin
- FExtendedHasher(AValue, AHashList);
- end;
- constructor TDelegatedExtendedEqualityComparerEvents<T>.Create(const AEqualityComparison: TOnEqualityComparison<T>;
- const AHasher: TOnHasher<T>; const AExtendedHasher: TOnExtendedHasher<T>);
- begin
- FEqualityComparison := AEqualityComparison;
- FHasher := AHasher;
- FExtendedHasher := AExtendedHasher;
- end;
- constructor TDelegatedExtendedEqualityComparerEvents<T>.Create(const AEqualityComparison: TOnEqualityComparison<T>;
- const AExtendedHasher: TOnExtendedHasher<T>);
- begin
- Create(AEqualityComparison, GetHashCodeMethod, AExtendedHasher);
- end;
- { TDelegatedExtendedEqualityComparerFunc<T> }
- function TDelegatedExtendedEqualityComparerFunc<T>.Equals(const ALeft, ARight: T): Boolean;
- begin
- Result := FEqualityComparison(ALeft, ARight);
- end;
- function TDelegatedExtendedEqualityComparerFunc<T>.GetHashCode(const AValue: T): UInt32;
- var
- LHashList: array[0..1] of Int32;
- LHashListParams: array[0..3] of Int16 absolute LHashList;
- begin
- if not Assigned(FHasher) then
- begin
- LHashListParams[0] := -1;
- FExtendedHasher(AValue, @LHashList[0]);
- Result := LHashList[1];
- end
- else
- Result := FHasher(AValue);
- end;
- procedure TDelegatedExtendedEqualityComparerFunc<T>.GetHashList(const AValue: T; AHashList: PUInt32);
- begin
- FExtendedHasher(AValue, AHashList);
- end;
- constructor TDelegatedExtendedEqualityComparerFunc<T>.Create(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AHasher: THasherFunc<T>; const AExtendedHasher: TExtendedHasherFunc<T>);
- begin
- FEqualityComparison := AEqualityComparison;
- FHasher := AHasher;
- FExtendedHasher := AExtendedHasher;
- end;
- constructor TDelegatedExtendedEqualityComparerFunc<T>.Create(const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AExtendedHasher: TExtendedHasherFunc<T>);
- begin
- Create(AEqualityComparison, nil, AExtendedHasher);
- end;
- { TExtendedEqualityComparer<T> }
- class function TExtendedEqualityComparer<T>.Default: IExtendedEqualityComparer<T>;
- begin
- if GetTypeKind(T) in TComparerService.UseBinaryMethods then
- Result := TBinaryExtendedEqualityComparer<T>.Create(Nil)
- else
- Result := _LookupVtableInfo(giExtendedEqualityComparer, TypeInfo(T), SizeOf(T));
- end;
- class function TExtendedEqualityComparer<T>.Default(
- AExtenedHashFactoryClass: TExtendedHashFactoryClass
- ): IExtendedEqualityComparer<T>;
- begin
- if GetTypeKind(T) in TComparerService.UseBinaryMethods then
- Result := TBinaryExtendedEqualityComparer<T>.Create(Nil)
- else
- Result := _LookupVtableInfoEx(giExtendedEqualityComparer, TypeInfo(T), SizeOf(T), AExtenedHashFactoryClass);
- end;
- class function TExtendedEqualityComparer<T>.Construct(
- const AEqualityComparison: TOnEqualityComparison<T>; const AHasher: TOnHasher<T>;
- const AExtendedHasher: TOnExtendedHasher<T>): IExtendedEqualityComparer<T>;
- begin
- Result := TDelegatedExtendedEqualityComparerEvents<T>.Create(AEqualityComparison, AHasher, AExtendedHasher);
- end;
- class function TExtendedEqualityComparer<T>.Construct(
- const AEqualityComparison: TEqualityComparisonFunc<T>; const AHasher: THasherFunc<T>;
- const AExtendedHasher: TExtendedHasherFunc<T>): IExtendedEqualityComparer<T>;
- begin
- Result := TDelegatedExtendedEqualityComparerFunc<T>.Create(AEqualityComparison, AHasher, AExtendedHasher);
- end;
- class function TExtendedEqualityComparer<T>.Construct(
- const AEqualityComparison: TOnEqualityComparison<T>;
- const AExtendedHasher: TOnExtendedHasher<T>): IExtendedEqualityComparer<T>;
- begin
- Result := TDelegatedExtendedEqualityComparerEvents<T>.Create(AEqualityComparison, AExtendedHasher);
- end;
- class function TExtendedEqualityComparer<T>.Construct(
- const AEqualityComparison: TEqualityComparisonFunc<T>;
- const AExtendedHasher: TExtendedHasherFunc<T>): IExtendedEqualityComparer<T>;
- begin
- Result := TDelegatedExtendedEqualityComparerFunc<T>.Create(AEqualityComparison, AExtendedHasher);
- end;
- { TBinaryComparer<T> }
- function TBinaryComparer<T>.Compare(const ALeft, ARight: T): Integer;
- begin
- Result := BinaryCompare(@ALeft, @ARight, SizeOf(T));
- end;
- { TBinaryEqualityComparer<T> }
- constructor TBinaryEqualityComparer<T>.Create(AHashFactoryClass: THashFactoryClass);
- begin
- if not Assigned(AHashFactoryClass) then
- FHashFactory := TDefaultHashFactory
- else
- FHashFactory := AHashFactoryClass;
- end;
- function TBinaryEqualityComparer<T>.Equals(const ALeft, ARight: T): Boolean;
- begin
- Result := CompareMem(@ALeft, @ARight, SizeOf(T));
- end;
- function TBinaryEqualityComparer<T>.GetHashCode(const AValue: T): UInt32;
- begin
- Result := FHashFactory.GetHashCode(@AValue, SizeOf(T), 0);
- end;
- { TBinaryExtendedEqualityComparer<T> }
- constructor TBinaryExtendedEqualityComparer<T>.Create(AHashFactoryClass: TExtendedHashFactoryClass);
- begin
- if not Assigned(AHashFactoryClass) then
- FExtendedHashFactory := TDelphiDoubleHashFactory
- else
- FExtendedHashFactory := AHashFactoryClass;
- inherited Create(FExtendedHashFactory);
- end;
- procedure TBinaryExtendedEqualityComparer<T>.GetHashList(const AValue: T; AHashList: PUInt32);
- begin
- FExtendedHashFactory.GetHashList(@AValue, SizeOf(T), AHashList, []);
- end;
- { TDelphiHashFactory }
- class function TDelphiHashFactory.GetHashService: THashServiceClass;
- begin
- Result := THashService<TDelphiHashFactory>;
- end;
- class function TDelphiHashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32): UInt32;
- begin
- Result := DelphiHashLittle(AKey, ASize, AInitVal);
- end;
- { TGenericsHashFactory }
- class function TGenericsHashFactory.GetHashService: THashServiceClass;
- begin
- Result := THashService<TGenericsHashFactory>;
- end;
- class function TGenericsHashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32): UInt32;
- begin
- Result := mORMotHasher(AInitVal, AKey, ASize);
- end;
- { TxxHash32HashFactory }
- class function TxxHash32HashFactory.GetHashService: THashServiceClass;
- begin
- Result := THashService<TxxHash32HashFactory>;
- end;
- class function TxxHash32HashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt;
- AInitVal: UInt32): UInt32;
- begin
- Result := xxHash32(AInitVal, AKey, ASize);
- end;
- { TxxHash32PascalHashFactory }
- class function TxxHash32PascalHashFactory.GetHashService: THashServiceClass;
- begin
- Result := THashService<TxxHash32PascalHashFactory>;
- end;
- class function TxxHash32PascalHashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt;
- AInitVal: UInt32): UInt32;
- begin
- Result := xxHash32Pascal(AInitVal, AKey, ASize);
- end;
- { TAdler32HashFactory }
- class function TAdler32HashFactory.GetHashService: THashServiceClass;
- begin
- Result := THashService<TAdler32HashFactory>;
- end;
- class function TAdler32HashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt;
- AInitVal: UInt32): UInt32;
- begin
- Result := Adler32(AKey, ASize);
- end;
- { TSdbmHashFactory }
- class function TSdbmHashFactory.GetHashService: THashServiceClass;
- begin
- Result := THashService<TSdbmHashFactory>;
- end;
- class function TSdbmHashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt;
- AInitVal: UInt32): UInt32;
- begin
- Result := sdbm(AKey, ASize);
- end;
- { TSimpleChecksumFactory }
- class function TSimpleChecksumFactory.GetHashService: THashServiceClass;
- begin
- Result := THashService<TSimpleChecksumFactory>;
- end;
- class function TSimpleChecksumFactory.GetHashCode(AKey: Pointer; ASize: SizeInt;
- AInitVal: UInt32): UInt32;
- begin
- Result := SimpleChecksumHash(AKey, ASize);
- end;
- { TDelphiDoubleHashFactory }
- class function TDelphiDoubleHashFactory.GetHashService: THashServiceClass;
- begin
- Result := TExtendedHashService<TDelphiDoubleHashFactory>;
- end;
- class function TDelphiDoubleHashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32): UInt32;
- begin
- Result := DelphiHashLittle(AKey, ASize, AInitVal);
- end;
- class procedure TDelphiDoubleHashFactory.GetHashList(AKey: Pointer; ASize: SizeInt; AHashList: PUInt32;
- AOptions: TGetHashListOptions);
- var
- LHash: UInt32;
- AHashListParams: PUInt16 absolute AHashList;
- begin
- {$WARNINGS OFF}
- case AHashListParams[0] of
- -2:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, LHash, AHashList[1]);
- Exit;
- end;
- -1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- 0: Exit;
- 1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- 2:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[1] := 0;
- AHashList[2] := 0;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[1], AHashList[2]);
- Exit;
- end;
- else
- raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
- end;
- {.$WARNINGS ON} // do not enable warnings ever in this unit, or you will get many warnings about uninitialized TEqualityComparerVMT fields
- end;
- { TDelphiQuadrupleHashFactory }
- class function TDelphiQuadrupleHashFactory.GetHashService: THashServiceClass;
- begin
- Result := TExtendedHashService<TDelphiQuadrupleHashFactory>;
- end;
- class function TDelphiQuadrupleHashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32): UInt32;
- begin
- Result := DelphiHashLittle(AKey, ASize, AInitVal);
- end;
- class procedure TDelphiQuadrupleHashFactory.GetHashList(AKey: Pointer; ASize: SizeInt; AHashList: PUInt32;
- AOptions: TGetHashListOptions);
- var
- LHash: UInt32;
- AHashListParams: PInt16 absolute AHashList;
- begin
- case AHashListParams[0] of
- -4:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 1988;
- LHash := 2004;
- DelphiHashLittle2(AKey, ASize, LHash, AHashList[1]);
- Exit;
- end;
- -3:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 2004;
- LHash := 1988;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- -2:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, LHash, AHashList[1]);
- Exit;
- end;
- -1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- 0: Exit;
- 1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- 2:
- begin
- case AHashListParams[1] of
- 0, 1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[1] := 0;
- AHashList[2] := 0;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[1], AHashList[2]);
- Exit;
- end;
- 2:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[1] := 2004;
- AHashList[2] := 1988;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[1], AHashList[2]);
- Exit;
- end;
- else
- raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
- end;
- end;
- 4:
- case AHashListParams[1] of
- 1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[1] := 0;
- AHashList[2] := 0;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[1], AHashList[2]);
- Exit;
- end;
- 2:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[3] := 2004;
- AHashList[4] := 1988;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[3], AHashList[4]);
- Exit;
- end;
- else
- raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
- end;
- else
- raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
- end;
- end;
- { TDelphiSixfoldHashFactory }
- class function TDelphiSixfoldHashFactory.GetHashService: THashServiceClass;
- begin
- Result := TExtendedHashService<TDelphiSixfoldHashFactory>;
- end;
- class function TDelphiSixfoldHashFactory.GetHashCode(AKey: Pointer; ASize: SizeInt; AInitVal: UInt32): UInt32;
- begin
- Result := DelphiHashLittle(AKey, ASize, AInitVal);
- end;
- class procedure TDelphiSixfoldHashFactory.GetHashList(AKey: Pointer; ASize: SizeInt; AHashList: PUInt32;
- AOptions: TGetHashListOptions);
- var
- LHash: UInt32;
- AHashListParams: PInt16 absolute AHashList;
- begin
- case AHashListParams[0] of
- -6:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 2;
- LHash := 1;
- DelphiHashLittle2(AKey, ASize, LHash, AHashList[1]);
- Exit;
- end;
- -5:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 1;
- LHash := 2;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- -4:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 1988;
- LHash := 2004;
- DelphiHashLittle2(AKey, ASize, LHash, AHashList[1]);
- Exit;
- end;
- -3:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 2004;
- LHash := 1988;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- -2:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, LHash, AHashList[1]);
- Exit;
- end;
- -1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- 0: Exit;
- 1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- AHashList[1] := 0;
- LHash := 0;
- DelphiHashLittle2(AKey, ASize, AHashList[1], LHash);
- Exit;
- end;
- 2:
- begin
- case AHashListParams[1] of
- 0, 1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[1] := 0;
- AHashList[2] := 0;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[1], AHashList[2]);
- Exit;
- end;
- 2:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[1] := 2004;
- AHashList[2] := 1988;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[1], AHashList[2]);
- Exit;
- end;
- else
- raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
- end;
- end;
- 6:
- case AHashListParams[1] of
- 1:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[1] := 0;
- AHashList[2] := 0;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[1], AHashList[2]);
- Exit;
- end;
- 2:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[3] := 2004;
- AHashList[4] := 1988;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[3], AHashList[4]);
- Exit;
- end;
- 3:
- begin
- if not (ghloHashListAsInitData in AOptions) then
- begin
- AHashList[5] := 1;
- AHashList[6] := 2;
- end;
- DelphiHashLittle2(AKey, ASize, AHashList[5], AHashList[6]);
- Exit;
- end;
- else
- raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
- end;
- else
- raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
- end;
- end;
- { TOrdinalComparer<T, THashFactory> }
- class constructor TOrdinalComparer<T, THashFactory>.Create;
- begin
- if THashFactory.InheritsFrom(TExtendedHashService) then
- begin
- FExtendedEqualityComparer := TExtendedEqualityComparer<T>.Default(TExtendedHashFactoryClass(THashFactory));
- FEqualityComparer := IEqualityComparer<T>(FExtendedEqualityComparer);
- end
- else
- FEqualityComparer := TEqualityComparer<T>.Default(THashFactory);
- FComparer := TComparer<T>.Default;
- end;
- { TGStringComparer<T, THashFactory> }
- class destructor TGStringComparer<T, THashFactory>.Destroy;
- begin
- if Assigned(FOrdinal) then
- FOrdinal.Free;
- end;
- class function TGStringComparer<T, THashFactory>.Ordinal: TCustomComparer<T>;
- begin
- if not Assigned(FOrdinal) then
- FOrdinal := TGOrdinalStringComparer<T, THashFactory>.Create;
- Result := FOrdinal;
- end;
- { TGOrdinalStringComparer<T, THashFactory> }
- function TGOrdinalStringComparer<T, THashFactory>.Compare(const ALeft, ARight: T): Integer;
- begin
- Result := FComparer.Compare(ALeft, ARight);
- end;
- function TGOrdinalStringComparer<T, THashFactory>.Equals(const ALeft, ARight: T): Boolean;
- begin
- Result := FEqualityComparer.Equals(ALeft, ARight);
- end;
- function TGOrdinalStringComparer<T, THashFactory>.GetHashCode(const AValue: T): UInt32;
- begin
- Result := FEqualityComparer.GetHashCode(AValue);
- end;
- procedure TGOrdinalStringComparer<T, THashFactory>.GetHashList(const AValue: T; AHashList: PUInt32);
- begin
- FExtendedEqualityComparer.GetHashList(AValue, AHashList);
- end;
- { TGIStringComparer<T, THashFactory> }
- class destructor TGIStringComparer<T, THashFactory>.Destroy;
- begin
- if Assigned(FOrdinal) then
- FOrdinal.Free;
- end;
- class function TGIStringComparer<T, THashFactory>.Ordinal: TCustomComparer<T>;
- begin
- if not Assigned(FOrdinal) then
- FOrdinal := TGOrdinalIStringComparer<T, THashFactory>.Create;
- Result := FOrdinal;
- end;
- { TGOrdinalIStringComparer<T, THashFactory> }
- function TGOrdinalIStringComparer<T, THashFactory>.Compare(const ALeft, ARight: T): Integer;
- begin
- Result := FComparer.Compare(ALeft.ToLower, ARight.ToLower);
- end;
- function TGOrdinalIStringComparer<T, THashFactory>.Equals(const ALeft, ARight: T): Boolean;
- begin
- Result := FEqualityComparer.Equals(ALeft.ToLower, ARight.ToLower);
- end;
- function TGOrdinalIStringComparer<T, THashFactory>.GetHashCode(const AValue: T): UInt32;
- begin
- Result := FEqualityComparer.GetHashCode(AValue.ToLower);
- end;
- procedure TGOrdinalIStringComparer<T, THashFactory>.GetHashList(const AValue: T; AHashList: PUInt32);
- begin
- FExtendedEqualityComparer.GetHashList(AValue.ToLower, AHashList);
- end;
- function BobJenkinsHash(const AData; ALength, AInitData: Integer): Integer;
- begin
- Result := DelphiHashLittle(@AData, ALength, AInitData);
- end;
- function BinaryCompare(const ALeft, ARight: Pointer; ASize: PtrUInt): Integer;
- begin
- Result := CompareMemRange(ALeft, ARight, ASize);
- end;
- function _LookupVtableInfo(AGInterface: TDefaultGenericInterface; ATypeInfo: PTypeInfo; ASize: SizeInt): Pointer;
- begin
- Result := _LookupVtableInfoEx(AGInterface, ATypeInfo, ASize, nil);
- end;
- function _LookupVtableInfoEx(AGInterface: TDefaultGenericInterface; ATypeInfo: PTypeInfo; ASize: SizeInt;
- AFactory: THashFactoryClass): Pointer;
- begin
- if ATypeInfo^.Kind in TComparerService.UseBinaryMethods then begin
- System.Error(reInvalidCast);
- Exit(Nil);
- end;
- case AGInterface of
- giComparer:
- Exit(
- TComparerService.LookupComparer(ATypeInfo, ASize));
- giEqualityComparer:
- begin
- if AFactory = nil then
- AFactory := TDefaultHashFactory;
- Exit(
- AFactory.GetHashService.LookupEqualityComparer(ATypeInfo, ASize));
- end;
- giExtendedEqualityComparer:
- begin
- if AFactory = nil then
- AFactory := TDelphiDoubleHashFactory;
- Exit(
- TExtendedHashServiceClass(AFactory.GetHashService).LookupExtendedEqualityComparer(ATypeInfo, ASize));
- end;
- else
- System.Error(reRangeError);
- Exit(nil);
- end;
- end;
- end.
|