diff --git a/tests/tests.lpi b/tests/tests.lpi index 7a2aae7..4aa06dc 100644 --- a/tests/tests.lpi +++ b/tests/tests.lpi @@ -37,7 +37,7 @@ - + @@ -186,6 +186,10 @@ + + + + @@ -214,9 +218,6 @@ - diff --git a/tests/tests.lpr b/tests/tests.lpr index a190b9f..96de6fc 100644 --- a/tests/tests.lpr +++ b/tests/tests.lpr @@ -9,7 +9,7 @@ uses // test cases uutlAlgorithmTests, uutlEnumeratorTests, uutlHashSetTests, uutlLinqTests, uutlListTest, uutlMapTests, uutlQueueTests, uutlStackTests, uutlObservableListTests, - uutlObservableHashSetTests, uutlObservableMapTests + uutlObservableHashSetTests, uutlObservableMapTests, // test misc uTestHelper, @@ -17,7 +17,7 @@ uses // units unter test uutlAlgorithm, uutlArrayContainer, uutlCommon, uutlComparer, uutlEnumerator, uutlFilter, uutlGenerics, uutlInterfaces, uutlLinq, uutlListBase, uutlLogger, - uutlStreamHelper, uutlSyncObjs, uutlTypes, uutlXmlHelper, uutlObservable; + uutlStreamHelper, uutlSyncObjs, uutlTypes, uutlXmlHelper, uutlObservable, uutlSetHelperTests; {$R *.res} diff --git a/tests/tests.lps b/tests/tests.lps index 5640e46..4ad6489 100644 --- a/tests/tests.lps +++ b/tests/tests.lps @@ -4,47 +4,43 @@ - + - - - - + + + - - - + + + - + - - + - - - - - + + + + - + - - + @@ -53,63 +49,61 @@ - + - + - - + - + - - + - + - + - + - - + - + - + - + + @@ -117,26 +111,24 @@ - + - - - - - + + + + - + - - + @@ -144,16 +136,15 @@ - + - + - - + @@ -162,23 +153,21 @@ - + - + - - + - - - + + @@ -186,7 +175,7 @@ - + @@ -194,7 +183,7 @@ - + @@ -202,7 +191,7 @@ - + @@ -210,7 +199,7 @@ - + @@ -219,7 +208,7 @@ - + @@ -228,7 +217,7 @@ - + @@ -237,7 +226,7 @@ - + @@ -246,7 +235,7 @@ - + @@ -255,7 +244,7 @@ - + @@ -264,15 +253,14 @@ - + - + - - + @@ -280,16 +268,15 @@ - + - + - - + @@ -298,7 +285,7 @@ - + @@ -307,15 +294,14 @@ - + - + - - + @@ -370,11 +356,10 @@ - + - - + @@ -394,18 +379,17 @@ - - - - + + + + - - - + + @@ -452,8 +436,8 @@ - - + + @@ -486,11 +470,10 @@ - + - - + @@ -499,6 +482,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -508,133 +515,139 @@ - + - + - + - + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + - + - + diff --git a/tests/uutlSetHelperTests.pas b/tests/uutlSetHelperTests.pas new file mode 100644 index 0000000..6a29bff --- /dev/null +++ b/tests/uutlSetHelperTests.pas @@ -0,0 +1,76 @@ +unit uutlSetHelperTests; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, TestFramework; + +type +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TutlSetHelperTests = class(TTestCase) + published + procedure ToString; + procedure TryToSet; + procedure Compare; + end; + +implementation + +uses + uutlGenerics; + +type + TTestEnum = ( + teTest0 = 0, + teTest1 = 1, + teTest2 = 2, + teTest3 = 3, + teTest4 = 4, + teTest5 = 5, + teTest8 = 8, + teTest9 = 9 + ); + TTestSet = set of TTestEnum; + TTestSetH = specialize TutlSetHelper; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TutlSetHelperTests//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TutlSetHelperTests.ToString; +var + str: String; +begin + str := TTestSetH.ToString([teTest0, teTest1, teTest2, teTest3, teTest4, teTest8]); + AssertEquals('teTest0, teTest1, teTest2, teTest3, teTest4, teTest8', str); + + str := TTestSetH.ToString([teTest0, teTest1, teTest2, teTest3, teTest4, teTest8], '_'); + AssertEquals('teTest0_teTest1_teTest2_teTest3_teTest4_teTest8', str); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TutlSetHelperTests.TryToSet; +var + s: TTestSet; +begin + AssertTrue(TTestSetH.TryToSet('teTest0, teTest1, teTest2, teTest3, teTest8, teTest9', s)); + AssertTrue([teTest0, teTest1, teTest2, teTest3, teTest8, teTest9] = s); + + AssertTrue(TTestSetH.TryToSet('teTest0_asd_teTest1_asd_teTest2_asd_teTest3_asd_teTest8_asd_teTest9', '_asd_', s)); + AssertTrue([teTest0, teTest1, teTest2, teTest3, teTest8, teTest9] = s); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TutlSetHelperTests.Compare; +begin + AssertEquals( 0, TTestSetH.Compare([teTest0, teTest1, teTest2], [teTest0, teTest1, teTest2])); + AssertEquals(-1, TTestSetH.Compare([ teTest1, teTest2], [teTest0, teTest1, teTest2])); + AssertEquals( 1, TTestSetH.Compare([teTest0, teTest1, teTest2], [teTest0, teTest2])); +end; + +initialization + RegisterTest(TutlSetHelperTests.Suite); + +end. + diff --git a/uutlCommon.pas b/uutlCommon.pas index 18c2d34..0a5b360 100644 --- a/uutlCommon.pas +++ b/uutlCommon.pas @@ -79,9 +79,10 @@ type end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function Supports (const aInstance: TObject; const aClass: TClass; out aObj): Boolean; -function GetTickCount64 (): QWord; -function GetMicroTime (): QWord; +function Supports (const aInstance: TObject; const aClass: TClass; out aObj): Boolean; +function GetTickCount64 (): QWord; +function GetMicroTime (): QWord; +function GetPlatformIdentitfier(): String; function utlRateLimited (const Reference: QWord; const Interval: QWord): boolean; procedure utlFinalizeObject (var obj; const aTypeInfo: PTypeInfo; const aFreeObject: Boolean); @@ -150,7 +151,7 @@ var begin pc := 0; QueryPerformanceCounter(pc); - Result:= (pc * 1000*1000) div PERF_FREQ; + result := (pc * 1000*1000) div PERF_FREQ; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -186,6 +187,68 @@ begin end; {$ENDIF} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function GetPlatformIdentitfier: String; + + {$IFDEF WINDOWS} + function GetWindowsVersionStr(const aDefault: String): string; + var + osv: TOSVERSIONINFO; + ver: cardinal; + begin + result := aDefault; + osv.dwOSVersionInfoSize := SizeOf(osv); + if GetVersionEx(osv) then begin + ver := MAKELONG(osv.dwMinorVersion, osv.dwMajorVersion); + // positive overflow: if system is newer, always detect as newest we knew instead of failing + if ver >= $000A0000 then + result := '10' + else if ver >= $00060003 then + result := '8_1' + else if ver >= $00060002 then + result := '8' + else if ver >= $00060001 then + result := '7' + else if ver >= $00060000 then + result := 'Vista' + else if ver >= $00050002 then + result := '2003' + else if ver >= $00050001 then + result := 'XP' + else if ver >= $00050000 then + result := '2000' + else if ver >= $00040000 then + result := 'NT4'; + // ignore NT3, hmkay?; + end; + end; + {$ENDIF} + +var + os,ver,arch: string; +begin + result := ''; + os := ''; + ver := 'generic'; + arch := ''; + {$IF DEFINED(WINDOWS)} + os := 'mswin'; + ver := GetWindowsVersionStr(ver); + {$ELSEIF DEFINED(LINUX)} + os := 'linux'; + {$Warning System Version String missing!} + {$ENDIF} + + {$IF DEFINED(CPUX86)} + arch := 'x86'; + {$ELSEIF DEFINED(cpux86_64)} + arch := 'x64'; + {$ELSE} + {$ERROR Unknown Architecture!} + {$ENDIF} + result := Format('%s-%s-%s', [os, ver, arch]); +end; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function utlRateLimited(const Reference: QWord; const Interval: QWord): boolean; begin @@ -413,7 +476,7 @@ var s: String; e: TFilterEntry; begin - Result:= ''; + result := ''; if (aIncludeAllSupported>'') and (fFilters.Count > 0) then begin s:= ''; for e in fFilters do begin @@ -442,7 +505,7 @@ function TFilterBuilderImpl.Add(aDescr, aMask: string; const aAppendFilterToDesc var e: TFilterEntry; begin - Result:= Self; + result := Self; e:= TFilterEntry.Create; if aAppendFilterToDesc then e.Descr:= Format('%s (%s)', [aDescr, aMask]) @@ -459,9 +522,9 @@ var begin c:= Pos('|', aFilter); if c > 0 then - Result:= (Self as IutlFilterBuilder).Add(Copy(aFilter, 1, c-1), Copy(aFilter, c+1, Maxint)) + result := (Self as IutlFilterBuilder).Add(Copy(aFilter, 1, c-1), Copy(aFilter, c+1, Maxint)) else - Result:= (Self as IutlFilterBuilder).Add(aFilter, aFilter, false); + result := (Self as IutlFilterBuilder).Add(aFilter, aFilter, false); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/uutlEnumerator.pas b/uutlEnumerator.pas index d9f3a02..2efbf86 100644 --- a/uutlEnumerator.pas +++ b/uutlEnumerator.pas @@ -234,6 +234,7 @@ type {$ENDIF} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IFDEF UTL_ENUMERATORS} generic TutlSkipTakeEnumerator = class( specialize TutlEnumerator) @@ -255,6 +256,7 @@ type constructor Create(aEnumerator: IutlEnumerator; const aSkip: Integer; const aTake: Integer); destructor Destroy; override; end; +{$ENDIF} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// {$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} @@ -360,6 +362,7 @@ type {$ENDIF} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IFDEF UTL_ENUMERATORS} generic TutlConcatEnumerator = class( specialize TutlEnumerator) @@ -381,6 +384,7 @@ type constructor Create(aEnumerators: TEnumerators); destructor Destroy; override; end; +{$ENDIF} implementation @@ -696,6 +700,7 @@ end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlDistinctEnumerator//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} function TutlDistinctEnumerator.InternalMoveNext: Boolean; type TBinarySearch = specialize TutlBinarySearch; @@ -723,7 +728,6 @@ begin end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -{$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} function TutlDistinctEnumerator.GetCurrent: T; begin result := fCurrent; @@ -741,6 +745,7 @@ end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlIntersectWithoutEnumerator//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} function TutlIntersectWithoutEnumerator.InternalMoveNext: Boolean; type TBinarySearch = specialize TutlBinarySearch; @@ -764,7 +769,6 @@ begin end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -{$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} function TutlIntersectWithoutEnumerator.GetCurrent: T; begin result := fCurrent; @@ -788,6 +792,7 @@ end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlSkipTakeEnumerator//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IFDEF UTL_ENUMERATORS} function TutlSkipTakeEnumerator.InternalMoveNext: Boolean; begin while (fCurrentSkip > 0) and fEnumerator.MoveNext do @@ -834,10 +839,12 @@ begin fEnumerator := nil; inherited Destroy; end; +{$ENDIF} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlWhereEnumerator/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} function TutlWhereEnumerator.InternalMoveNext: Boolean; begin repeat @@ -852,7 +859,6 @@ begin end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -{$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} function TutlWhereEnumerator.GetCurrent: T; begin result := fEnumerator.Current; @@ -882,6 +888,7 @@ end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlSelectEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} function TutlSelectEnumerator.InternalMoveNext: Boolean; begin result := fEnumerator.MoveNext; @@ -894,7 +901,6 @@ begin end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -{$IF DEFINED(UTL_ENUMERATORS) AND DEFINED(UTL_ADVANCED_ENUMERATORS)} function TutlSelectEnumerator.GetCurrent: Tout; begin result := fSelector.Select(fEnumerator.Current); @@ -1017,6 +1023,7 @@ end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TutlConcatEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IFDEF UTL_ENUMERATORS} function TutlConcatEnumerator.InternalMoveNext: Boolean; begin if (fCurrent < 0) then begin @@ -1065,6 +1072,7 @@ begin SetLength(fEnumerators, 0); inherited Destroy; end; +{$ENDIF} end. diff --git a/uutlGenerics.pas b/uutlGenerics.pas index c903921..e440915 100644 --- a/uutlGenerics.pas +++ b/uutlGenerics.pas @@ -466,13 +466,14 @@ type end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - EutlEnumConvert = class(EConvertError) + EEnumConvertException = class(EConvertError) public constructor Create(const aValue, aExpectedType: String); end; generic TutlEnumHelper = class public type + TEnumType = T; TValueArray = array of T; TStringArray = array of String; @@ -482,18 +483,39 @@ type fNames: TStringArray; public - class function ToString(aValue: T): String; reintroduce; - class function TryToEnum(aStr: String; out aValue: T): Boolean; - class function ToEnum(aStr: String): T; overload; - class function ToEnum(aStr: String; const aDefault: T): T; overload; + class function ToString (aValue: T): String; reintroduce; + class function TryToEnum (aStr: String; out aValue: T): Boolean; + class function ToEnum (aStr: String): T; overload; + class function ToEnum (aStr: String; const aDefault: T): T; overload; - class function Values: TValueArray; inline; - class function Names: TStringArray; inline; - class function TypeInfo: PTypeInfo; inline; + class function Values: TValueArray; inline; + class function Names: TStringArray; inline; + class function TypeInfo: PTypeInfo; inline; class constructor Initialize; end; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + generic TutlSetHelper = class + public type + TEnumHelper = specialize TutlEnumHelper; + TEnumType = TEnum; + TSetType = TSet; + + private + class function IsSet (constref aSet: TSet; aEnum: TEnum): Boolean; + class procedure SetValue (var aSet: TSet; aEnum: TEnum); + class procedure ClearValue(var aSet: TSet; aEnum: TEnum); + + public + class function ToString (const aValue: TSet; const aSeperator: String = ', '): String; reintroduce; + class function TryToSet (const aStr: String; out aValue: TSet): Boolean; overload; + class function TryToSet (const aStr: String; const aSeperator: String; out aValue: TSet): Boolean; overload; + class function ToSet (const aStr: String; const aDefault: TSet): TSet; overload; + class function ToSet (const aStr: String): TSet; overload; + class function Compare (const aSet1, aSet2: TSet): Integer; + end; + implementation //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1464,7 +1486,7 @@ end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EutlEnumConvert/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -constructor EutlEnumConvert.Create(const aValue, aExpectedType: String); +constructor EEnumConvertException.Create(const aValue, aExpectedType: String); begin inherited Create(Format('%s is not a %s', [aValue, aExpectedType])); end; @@ -1505,7 +1527,7 @@ end; class function TutlEnumHelper.ToEnum(aStr: String): T; begin if not TryToEnum(aStr, result) then - raise EutlEnumConvert.Create(aStr, TypeInfo^.Name); + raise EEnumConvertException.Create(aStr, TypeInfo^.Name); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1585,5 +1607,120 @@ begin SetLength(fNames, High(fNames)); end; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TutlSetHelper///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TutlSetHelper.IsSet(constref aSet: TSet; aEnum: TEnum): Boolean; +begin + result := ((PByte(@aSet)[Integer(aEnum) shr 3] and (1 shl (Integer(aEnum) and 7))) <> 0); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class procedure TutlSetHelper.SetValue(var aSet: TSet; aEnum: TEnum); +begin + PByte(@aSet)[Integer(aEnum) shr 3] := PByte(@aSet)[Integer(aEnum) shr 3] or (1 shl (Integer(aEnum) and 7)); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class procedure TutlSetHelper.ClearValue(var aSet: TSet; aEnum: TEnum); +begin + PByte(@aSet)[Integer(aEnum) shr 3] := PByte(@aSet)[Integer(aEnum) shr 3] and not (1 shl (Integer(aEnum) and 7)); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TutlSetHelper.ToString(const aValue: TSet; const aSeperator: String): String; +var + e: TEnum; + i: Integer; + p: PByte; +begin + result := ''; + p := @aValue; + for e in TEnumHelper.Values do begin + i := Integer(e); + if IsSet(aValue, e) then begin + if result > '' then + result := result + aSeperator; + result := result + TEnumHelper.ToString(e); + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TutlSetHelper.TryToSet(const aStr: String; out aValue: TSet): Boolean; +begin + result := TryToSet(aStr, ',', aValue); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TutlSetHelper.TryToSet(const aStr: String; const aSeperator: String; out aValue: TSet): Boolean; +var + i, j: Integer; + p: PAnsiChar; + s: String; + e: TEnum; +begin + if (aSeperator = '') then + raise EArgumentException.Create('''aSeperator'' can not be empty'); + + result := true; + aValue := []; + i := 1; + j := 1; + + while (i <= Length(aStr)) do begin + if (Copy(aStr, i, Length(aSeperator)) = aSeperator) then begin + s := Trim(copy(aStr, j, i - j)); + if (s <> '') then begin + result := result and TEnumHelper.TryToEnum(s, e); + if not result then + exit; + SetValue(aValue, e); + j := i + Length(aSeperator); + end; + end; + inc(i); + end; + + s := Trim(copy(aStr, j, i - j)); + if (s <> '') then begin + result := result and TEnumHelper.TryToEnum(s, e); + if not result then + exit; + SetValue(aValue, e); + end +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TutlSetHelper.ToSet(const aStr: String; const aDefault: TSet): TSet; +begin + if not TryToSet(aStr, result) then + result := aDefault; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TutlSetHelper.ToSet(const aStr: String): TSet; +begin + if not TryToSet(aStr, result) then + raise EEnumConvertException.CreateFmt('"%s" is an invalid value', [aStr]); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TutlSetHelper.Compare(const aSet1, aSet2: TSet): Integer; +var + e: TEnum; +begin + result := 0; + for e in TEnumHelper.Values do begin + if IsSet(aSet1, e) and not IsSet(aSet2, e) then begin + result := 1; + break; + end else if not IsSet(aSet1, e) and IsSet(aSet2, e) then begin + result := -1; + break; + end; + end; +end; + end.