{**************************************************************************************************} { WARNING: JEDI preprocessor generated unit. Do not edit. } {**************************************************************************************************} {**************************************************************************************************} { } { Project JEDI Code Library (JCL) } { } { The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); } { you may not use this file except in compliance with the License. You may obtain a copy of the } { License at http://www.mozilla.org/MPL/ } { } { Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF } { ANY KIND, either express or implied. See the License for the specific language governing rights } { and limitations under the License. } { } { The Original Code is HashSet.pas. } { } { The Initial Developer of the Original Code is Jean-Philippe BEMPEL aka RDM. Portions created by } { Jean-Philippe BEMPEL are Copyright (C) Jean-Philippe BEMPEL (rdm_30 att yahoo dott com) } { All rights reserved. } { } { Contributors: } { Florent Ouchet (outchy) } { } {**************************************************************************************************} { } { The Delphi Container Library } { } {**************************************************************************************************} { } { Last modified: $Date:: 2009-09-12 14:21:23 +0200 (sam., 12 sept. 2009) $ } { Revision: $Rev:: 2997 $ } { Author: $Author:: outchy $ } { } {**************************************************************************************************} unit JclHashSets; {$I jcl.inc} interface uses SysUtils, {$IFDEF UNITVERSIONING} JclUnitVersioning, {$ENDIF UNITVERSIONING} Classes, {$IFDEF SUPPORTS_GENERICS} JclAlgorithms, {$ENDIF SUPPORTS_GENERICS} JclBase, JclAbstractContainers, JclContainerIntf, JclHashMaps, JclSynch; type {$IFDEF SUPPORTS_GENERICS} TRefUnique = class; TRefUnique = class(TInterfacedObject, IEquatable, IJclEqualityComparer) public { IEquatable } function Equals(Other: TRefUnique): Boolean; reintroduce; { IJclEqualityComparer } function GetEqualityCompare: TEqualityCompare; procedure SetEqualityCompare(Value: TEqualityCompare); function ItemsEqual(const A, B: TRefUnique): Boolean; property EqualityCompare: TEqualityCompare read GetEqualityCompare write SetEqualityCompare; end; {$ELSE ~SUPPORTS_GENERICS} TRefUnique = TInterfacedObject; {$ENDIF ~SUPPORTS_GENERICS} TJclIntfHashSet = class(TJclIntfAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclIntfEqualityComparer, IJclIntfCollection, IJclIntfSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; private FMap: IJclIntfMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclIntfMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclIntfCollection } function Add(const AInterface: IInterface): Boolean; function AddAll(const ACollection: IJclIntfCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclIntfCollection): Boolean; function Contains(const AInterface: IInterface): Boolean; function ContainsAll(const ACollection: IJclIntfCollection): Boolean; function Extract(const AInterface: IInterface): Boolean; function ExtractAll(const ACollection: IJclIntfCollection): Boolean; function First: IJclIntfIterator; function IsEmpty: Boolean; function Last: IJclIntfIterator; function Remove(const AInterface: IInterface): Boolean; function RemoveAll(const ACollection: IJclIntfCollection): Boolean; function RetainAll(const ACollection: IJclIntfCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclIntfIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclIntfSet } procedure Intersect(const ACollection: IJclIntfCollection); procedure Subtract(const ACollection: IJclIntfCollection); procedure Union(const ACollection: IJclIntfCollection); end; TJclAnsiStrHashSet = class(TJclAnsiStrAbstractCollection, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclStrContainer, IJclAnsiStrContainer, IJclAnsiStrEqualityComparer, IJclAnsiStrCollection, IJclAnsiStrSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; { IJclStrContainer } function GetCaseSensitive: Boolean; override; procedure SetCaseSensitive(Value: Boolean); override; { IJclAnsiStrContainer } function GetEncoding: TJclAnsiStrEncoding; override; procedure SetEncoding(Value: TJclAnsiStrEncoding); override; private FMap: IJclAnsiStrMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclAnsiStrMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclAnsiStrCollection } function Add(const AString: AnsiString): Boolean; override; function AddAll(const ACollection: IJclAnsiStrCollection): Boolean; override; procedure Clear; override; function CollectionEquals(const ACollection: IJclAnsiStrCollection): Boolean; override; function Contains(const AString: AnsiString): Boolean; override; function ContainsAll(const ACollection: IJclAnsiStrCollection): Boolean; override; function Extract(const AString: AnsiString): Boolean; override; function ExtractAll(const ACollection: IJclAnsiStrCollection): Boolean; override; function First: IJclAnsiStrIterator; override; function IsEmpty: Boolean; override; function Last: IJclAnsiStrIterator; override; function Remove(const AString: AnsiString): Boolean; override; function RemoveAll(const ACollection: IJclAnsiStrCollection): Boolean; override; function RetainAll(const ACollection: IJclAnsiStrCollection): Boolean; override; function Size: Integer; override; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclAnsiStrIterator; override; {$ENDIF SUPPORTS_FOR_IN} { IJclAnsiStrSet } procedure Intersect(const ACollection: IJclAnsiStrCollection); procedure Subtract(const ACollection: IJclAnsiStrCollection); procedure Union(const ACollection: IJclAnsiStrCollection); end; TJclWideStrHashSet = class(TJclWideStrAbstractCollection, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclStrContainer, IJclWideStrContainer, IJclWideStrEqualityComparer, IJclWideStrCollection, IJclWideStrSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; { IJclStrContainer } function GetCaseSensitive: Boolean; override; procedure SetCaseSensitive(Value: Boolean); override; { IJclWideStrContainer } function GetEncoding: TJclWideStrEncoding; override; procedure SetEncoding(Value: TJclWideStrEncoding); override; private FMap: IJclWideStrMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclWideStrMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclWideStrCollection } function Add(const AString: WideString): Boolean; override; function AddAll(const ACollection: IJclWideStrCollection): Boolean; override; procedure Clear; override; function CollectionEquals(const ACollection: IJclWideStrCollection): Boolean; override; function Contains(const AString: WideString): Boolean; override; function ContainsAll(const ACollection: IJclWideStrCollection): Boolean; override; function Extract(const AString: WideString): Boolean; override; function ExtractAll(const ACollection: IJclWideStrCollection): Boolean; override; function First: IJclWideStrIterator; override; function IsEmpty: Boolean; override; function Last: IJclWideStrIterator; override; function Remove(const AString: WideString): Boolean; override; function RemoveAll(const ACollection: IJclWideStrCollection): Boolean; override; function RetainAll(const ACollection: IJclWideStrCollection): Boolean; override; function Size: Integer; override; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclWideStrIterator; override; {$ENDIF SUPPORTS_FOR_IN} { IJclWideStrSet } procedure Intersect(const ACollection: IJclWideStrCollection); procedure Subtract(const ACollection: IJclWideStrCollection); procedure Union(const ACollection: IJclWideStrCollection); end; {$IFDEF SUPPORTS_UNICODE_STRING} TJclUnicodeStrHashSet = class(TJclUnicodeStrAbstractCollection, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclStrContainer, IJclUnicodeStrContainer, IJclUnicodeStrEqualityComparer, IJclUnicodeStrCollection, IJclUnicodeStrSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; { IJclStrContainer } function GetCaseSensitive: Boolean; override; procedure SetCaseSensitive(Value: Boolean); override; private FMap: IJclUnicodeStrMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclUnicodeStrMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclUnicodeStrCollection } function Add(const AString: UnicodeString): Boolean; override; function AddAll(const ACollection: IJclUnicodeStrCollection): Boolean; override; procedure Clear; override; function CollectionEquals(const ACollection: IJclUnicodeStrCollection): Boolean; override; function Contains(const AString: UnicodeString): Boolean; override; function ContainsAll(const ACollection: IJclUnicodeStrCollection): Boolean; override; function Extract(const AString: UnicodeString): Boolean; override; function ExtractAll(const ACollection: IJclUnicodeStrCollection): Boolean; override; function First: IJclUnicodeStrIterator; override; function IsEmpty: Boolean; override; function Last: IJclUnicodeStrIterator; override; function Remove(const AString: UnicodeString): Boolean; override; function RemoveAll(const ACollection: IJclUnicodeStrCollection): Boolean; override; function RetainAll(const ACollection: IJclUnicodeStrCollection): Boolean; override; function Size: Integer; override; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclUnicodeStrIterator; override; {$ENDIF SUPPORTS_FOR_IN} { IJclUnicodeStrSet } procedure Intersect(const ACollection: IJclUnicodeStrCollection); procedure Subtract(const ACollection: IJclUnicodeStrCollection); procedure Union(const ACollection: IJclUnicodeStrCollection); end; {$ENDIF SUPPORTS_UNICODE_STRING} {$IFDEF CONTAINER_ANSISTR} TJclStrHashSet = TJclAnsiStrHashSet; {$ENDIF CONTAINER_ANSISTR} {$IFDEF CONTAINER_WIDESTR} TJclStrHashSet = TJclWideStrHashSet; {$ENDIF CONTAINER_WIDESTR} {$IFDEF CONTAINER_UNICODESTR} TJclStrHashSet = TJclUnicodeStrHashSet; {$ENDIF CONTAINER_UNICODESTR} TJclSingleHashSet = class(TJclSingleAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclSingleContainer, IJclSingleEqualityComparer, IJclSingleCollection, IJclSingleSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; { IJclSingleContainer } function GetPrecision: Single; override; procedure SetPrecision(const Value: Single); override; private FMap: IJclSingleMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclSingleMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclSingleCollection } function Add(const AValue: Single): Boolean; function AddAll(const ACollection: IJclSingleCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclSingleCollection): Boolean; function Contains(const AValue: Single): Boolean; function ContainsAll(const ACollection: IJclSingleCollection): Boolean; function Extract(const AValue: Single): Boolean; function ExtractAll(const ACollection: IJclSingleCollection): Boolean; function First: IJclSingleIterator; function IsEmpty: Boolean; function Last: IJclSingleIterator; function Remove(const AValue: Single): Boolean; function RemoveAll(const ACollection: IJclSingleCollection): Boolean; function RetainAll(const ACollection: IJclSingleCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclSingleIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclSingleSet } procedure Intersect(const ACollection: IJclSingleCollection); procedure Subtract(const ACollection: IJclSingleCollection); procedure Union(const ACollection: IJclSingleCollection); end; TJclDoubleHashSet = class(TJclDoubleAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclDoubleContainer, IJclDoubleEqualityComparer, IJclDoubleCollection, IJclDoubleSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; { IJclDoubleContainer } function GetPrecision: Double; override; procedure SetPrecision(const Value: Double); override; private FMap: IJclDoubleMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclDoubleMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclDoubleCollection } function Add(const AValue: Double): Boolean; function AddAll(const ACollection: IJclDoubleCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclDoubleCollection): Boolean; function Contains(const AValue: Double): Boolean; function ContainsAll(const ACollection: IJclDoubleCollection): Boolean; function Extract(const AValue: Double): Boolean; function ExtractAll(const ACollection: IJclDoubleCollection): Boolean; function First: IJclDoubleIterator; function IsEmpty: Boolean; function Last: IJclDoubleIterator; function Remove(const AValue: Double): Boolean; function RemoveAll(const ACollection: IJclDoubleCollection): Boolean; function RetainAll(const ACollection: IJclDoubleCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclDoubleIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclDoubleSet } procedure Intersect(const ACollection: IJclDoubleCollection); procedure Subtract(const ACollection: IJclDoubleCollection); procedure Union(const ACollection: IJclDoubleCollection); end; TJclExtendedHashSet = class(TJclExtendedAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclExtendedContainer, IJclExtendedEqualityComparer, IJclExtendedCollection, IJclExtendedSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; { IJclExtendedContainer } function GetPrecision: Extended; override; procedure SetPrecision(const Value: Extended); override; private FMap: IJclExtendedMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclExtendedMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclExtendedCollection } function Add(const AValue: Extended): Boolean; function AddAll(const ACollection: IJclExtendedCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclExtendedCollection): Boolean; function Contains(const AValue: Extended): Boolean; function ContainsAll(const ACollection: IJclExtendedCollection): Boolean; function Extract(const AValue: Extended): Boolean; function ExtractAll(const ACollection: IJclExtendedCollection): Boolean; function First: IJclExtendedIterator; function IsEmpty: Boolean; function Last: IJclExtendedIterator; function Remove(const AValue: Extended): Boolean; function RemoveAll(const ACollection: IJclExtendedCollection): Boolean; function RetainAll(const ACollection: IJclExtendedCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclExtendedIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclExtendedSet } procedure Intersect(const ACollection: IJclExtendedCollection); procedure Subtract(const ACollection: IJclExtendedCollection); procedure Union(const ACollection: IJclExtendedCollection); end; {$IFDEF MATH_EXTENDED_PRECISION} TJclFloatHashSet = TJclExtendedHashSet; {$ENDIF MATH_EXTENDED_PRECISION} {$IFDEF MATH_DOUBLE_PRECISION} TJclFloatHashSet = TJclDoubleHashSet; {$ENDIF MATH_DOUBLE_PRECISION} {$IFDEF MATH_SINGLE_PRECISION} TJclFloatHashSet = TJclSingleHashSet; {$ENDIF MATH_SINGLE_PRECISION} TJclIntegerHashSet = class(TJclIntegerAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclIntegerEqualityComparer, IJclIntegerCollection, IJclIntegerSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; private FMap: IJclIntegerMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclIntegerMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclIntegerCollection } function Add(AValue: Integer): Boolean; function AddAll(const ACollection: IJclIntegerCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclIntegerCollection): Boolean; function Contains(AValue: Integer): Boolean; function ContainsAll(const ACollection: IJclIntegerCollection): Boolean; function Extract(AValue: Integer): Boolean; function ExtractAll(const ACollection: IJclIntegerCollection): Boolean; function First: IJclIntegerIterator; function IsEmpty: Boolean; function Last: IJclIntegerIterator; function Remove(AValue: Integer): Boolean; function RemoveAll(const ACollection: IJclIntegerCollection): Boolean; function RetainAll(const ACollection: IJclIntegerCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclIntegerIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclIntegerSet } procedure Intersect(const ACollection: IJclIntegerCollection); procedure Subtract(const ACollection: IJclIntegerCollection); procedure Union(const ACollection: IJclIntegerCollection); end; TJclCardinalHashSet = class(TJclCardinalAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclCardinalEqualityComparer, IJclCardinalCollection, IJclCardinalSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; private FMap: IJclCardinalMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclCardinalMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclCardinalCollection } function Add(AValue: Cardinal): Boolean; function AddAll(const ACollection: IJclCardinalCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclCardinalCollection): Boolean; function Contains(AValue: Cardinal): Boolean; function ContainsAll(const ACollection: IJclCardinalCollection): Boolean; function Extract(AValue: Cardinal): Boolean; function ExtractAll(const ACollection: IJclCardinalCollection): Boolean; function First: IJclCardinalIterator; function IsEmpty: Boolean; function Last: IJclCardinalIterator; function Remove(AValue: Cardinal): Boolean; function RemoveAll(const ACollection: IJclCardinalCollection): Boolean; function RetainAll(const ACollection: IJclCardinalCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclCardinalIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclCardinalSet } procedure Intersect(const ACollection: IJclCardinalCollection); procedure Subtract(const ACollection: IJclCardinalCollection); procedure Union(const ACollection: IJclCardinalCollection); end; TJclInt64HashSet = class(TJclInt64AbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclInt64EqualityComparer, IJclInt64Collection, IJclInt64Set) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; private FMap: IJclInt64Map; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclInt64Map); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclInt64Collection } function Add(const AValue: Int64): Boolean; function AddAll(const ACollection: IJclInt64Collection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclInt64Collection): Boolean; function Contains(const AValue: Int64): Boolean; function ContainsAll(const ACollection: IJclInt64Collection): Boolean; function Extract(const AValue: Int64): Boolean; function ExtractAll(const ACollection: IJclInt64Collection): Boolean; function First: IJclInt64Iterator; function IsEmpty: Boolean; function Last: IJclInt64Iterator; function Remove(const AValue: Int64): Boolean; function RemoveAll(const ACollection: IJclInt64Collection): Boolean; function RetainAll(const ACollection: IJclInt64Collection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclInt64Iterator; {$ENDIF SUPPORTS_FOR_IN} { IJclInt64Set } procedure Intersect(const ACollection: IJclInt64Collection); procedure Subtract(const ACollection: IJclInt64Collection); procedure Union(const ACollection: IJclInt64Collection); end; TJclPtrHashSet = class(TJclPtrAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclPtrEqualityComparer, IJclPtrCollection, IJclPtrSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer); overload; private FMap: IJclPtrMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclPtrMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclPtrCollection } function Add(AValue: Pointer): Boolean; function AddAll(const ACollection: IJclPtrCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclPtrCollection): Boolean; function Contains(AValue: Pointer): Boolean; function ContainsAll(const ACollection: IJclPtrCollection): Boolean; function Extract(AValue: Pointer): Boolean; function ExtractAll(const ACollection: IJclPtrCollection): Boolean; function First: IJclPtrIterator; function IsEmpty: Boolean; function Last: IJclPtrIterator; function Remove(AValue: Pointer): Boolean; function RemoveAll(const ACollection: IJclPtrCollection): Boolean; function RetainAll(const ACollection: IJclPtrCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclPtrIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclPtrSet } procedure Intersect(const ACollection: IJclPtrCollection); procedure Subtract(const ACollection: IJclPtrCollection); procedure Union(const ACollection: IJclPtrCollection); end; TJclHashSet = class(TJclAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclObjectOwner, IJclEqualityComparer, IJclCollection, IJclSet) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(ACapacity: Integer; AOwnsObjects: Boolean); overload; { IJclObjectOwner } function FreeObject(var AObject: TObject): TObject; override; function GetOwnsObjects: Boolean; override; private FMap: IJclMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclCollection } function Add(AObject: TObject): Boolean; function AddAll(const ACollection: IJclCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclCollection): Boolean; function Contains(AObject: TObject): Boolean; function ContainsAll(const ACollection: IJclCollection): Boolean; function Extract(AObject: TObject): Boolean; function ExtractAll(const ACollection: IJclCollection): Boolean; function First: IJclIterator; function IsEmpty: Boolean; function Last: IJclIterator; function Remove(AObject: TObject): Boolean; function RemoveAll(const ACollection: IJclCollection): Boolean; function RetainAll(const ACollection: IJclCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclSet } procedure Intersect(const ACollection: IJclCollection); procedure Subtract(const ACollection: IJclCollection); procedure Union(const ACollection: IJclCollection); end; {$IFDEF SUPPORTS_GENERICS} TJclHashSet = class(TJclAbstractContainer, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclItemOwner, IJclEqualityComparer, IJclCollection, IJclSet) public { IJclItemOwner } function FreeItem(var AItem: T): T; override; function GetOwnsItems: Boolean; override; private FMap: IJclMap; protected procedure AssignDataTo(Dest: TJclAbstractContainerBase); override; public constructor Create(const AMap: IJclMap); overload; destructor Destroy; override; { IJclPackable } function GetAutoPackParameter: Integer; override; function GetAutoPackStrategy: TJclAutoPackStrategy; override; function GetCapacity: Integer; override; procedure Pack; override; procedure SetAutoPackParameter(Value: Integer); override; procedure SetAutoPackStrategy(Value: TJclAutoPackStrategy); override; procedure SetCapacity(Value: Integer); override; { IJclContainer } function GetAllowDefaultElements: Boolean; override; function GetDuplicates: TDuplicates; override; function GetReadOnly: Boolean; override; function GetRemoveSingleElement: Boolean; override; function GetReturnDefaultElements: Boolean; override; function GetThreadSafe: Boolean; override; procedure SetAllowDefaultElements(Value: Boolean); override; procedure SetDuplicates(Value: TDuplicates); override; procedure SetReadOnly(Value: Boolean); override; procedure SetRemoveSingleElement(Value: Boolean); override; procedure SetReturnDefaultElements(Value: Boolean); override; procedure SetThreadSafe(Value: Boolean); override; { IJclCollection } function Add(const AItem: T): Boolean; function AddAll(const ACollection: IJclCollection): Boolean; procedure Clear; function CollectionEquals(const ACollection: IJclCollection): Boolean; function Contains(const AItem: T): Boolean; function ContainsAll(const ACollection: IJclCollection): Boolean; function Extract(const AItem: T): Boolean; function ExtractAll(const ACollection: IJclCollection): Boolean; function First: IJclIterator; function IsEmpty: Boolean; function Last: IJclIterator; function Remove(const AItem: T): Boolean; function RemoveAll(const ACollection: IJclCollection): Boolean; function RetainAll(const ACollection: IJclCollection): Boolean; function Size: Integer; {$IFDEF SUPPORTS_FOR_IN} function GetEnumerator: IJclIterator; {$ENDIF SUPPORTS_FOR_IN} { IJclSet } procedure Intersect(const ACollection: IJclCollection); procedure Subtract(const ACollection: IJclCollection); procedure Union(const ACollection: IJclCollection); end; // E = External helper to compare items for equality TJclHashSetE = class(TJclHashSet, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclCollection, IJclSet, IJclItemOwner, IJclEqualityComparer) private FEqualityComparer: IJclEqualityComparer; FHashConverter: IJclHashconverter; protected procedure AssignPropertiesTo(Dest: TJclAbstractContainerBase); override; function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(const AEqualityComparer: IJclEqualityComparer; const AHashConverter: IJclHashConverter; const AMap: IJclMap); overload; constructor Create(const AEqualityComparer: IJclEqualityComparer; const AHashConverter: IJclHashConverter; const AComparer: IJclComparer; ACapacity: Integer; AOwnsItems: Boolean); overload; { IJclEqualityComparer } function ItemsEqual(const A, B: T): Boolean; override; property EqualityComparer: IJclEqualityComparer read FEqualityComparer write FEqualityComparer; property HashConverter: IJclHashConverter read FHashConverter write FHashConverter; end; // F = Function to compare items for equality TJclHashSetF = class(TJclHashSet, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclCollection, IJclSet, IJclItemOwner, IJclEqualityComparer) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(const AEqualityCompare: TEqualityCompare; const AMap: IJclMap); overload; constructor Create(const AEqualityCompare: TEqualityCompare; const AHash: THashConvert; const ACompare: TCompare; ACapacity: Integer; AOwnsItems: Boolean); overload; end; // I = Items can compare themselves to an other TJclHashSetI, IComparable, IHashable> = class(TJclHashSet, {$IFDEF THREADSAFE} IJclLockable, {$ENDIF THREADSAFE} IJclIntfCloneable, IJclCloneable, IJclPackable, IJclContainer, IJclCollection, IJclSet, IJclItemOwner, IJclEqualityComparer) protected function CreateEmptyContainer: TJclAbstractContainerBase; override; public constructor Create(const AMap: IJclMap); overload; constructor Create(ACapacity: Integer; AOwnsItems: Boolean); overload; { IJclEqualityComparer } function ItemsEqual(const A, B: T): Boolean; override; end; {$ENDIF SUPPORTS_GENERICS} {$IFDEF UNITVERSIONING} const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL: https://jcl.svn.sourceforge.net/svnroot/jcl/tags/JCL-2.1-Build3536/jcl/source/common/JclHashSets.pas $'; Revision: '$Revision: 2997 $'; Date: '$Date: 2009-09-12 14:21:23 +0200 (sam., 12 sept. 2009) $'; LogPath: 'JCL\source\common'; Extra: ''; Data: nil ); {$ENDIF UNITVERSIONING} function RefUnique: TRefUnique; function EqualityCompareEqObjects(const Obj1, Obj2: TRefUnique): Boolean; implementation var GlobalRefUnique: TRefUnique = nil; function RefUnique: TRefUnique; begin // We keep the reference till program end. A unique memory address is not // possible under a garbage collector. if GlobalRefUnique = nil then GlobalRefUnique := TRefUnique.Create; Result := GlobalRefUnique; end; function EqualityCompareEqObjects(const Obj1, Obj2: TRefUnique): Boolean; begin Result := Obj1 = Obj2; end; {$IFDEF SUPPORTS_GENERICS} //=== { TRefUnique } ========================================================== function TRefUnique.GetEqualityCompare: TEqualityCompare; begin raise EJclOperationNotSupportedError.Create; end; procedure TRefUnique.SetEqualityCompare(Value: TEqualityCompare); begin raise EJclOperationNotSupportedError.Create; end; function TRefUnique.ItemsEqual(const A, B: TRefUnique): Boolean; begin Result := A = B; end; function TRefUnique.Equals(Other: TRefUnique): Boolean; begin Result := Self = Other; end; {$ENDIF SUPPORTS_GENERICS} //=== { TJclIntfHashSet } ===================================================== constructor TJclIntfHashSet.Create(const AMap: IJclIntfMap); begin inherited Create(); FMap := AMap; end; destructor TJclIntfHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclIntfHashSet.Add(const AInterface: IInterface): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AInterface); if Result then FMap.PutValue(AInterface, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntfHashSet.AddAll(const ACollection: IJclIntfCollection): Boolean; var It: IJclIntfIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclIntfHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclIntfHashSet then TJclIntfHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclIntfMap; end; procedure TJclIntfHashSet.Clear; begin FMap.Clear; end; function TJclIntfHashSet.CollectionEquals(const ACollection: IJclIntfCollection): Boolean; var It, ItMap: IJclIntfIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntfHashSet.Contains(const AInterface: IInterface): Boolean; begin Result := FMap.ContainsKey(AInterface); end; function TJclIntfHashSet.ContainsAll(const ACollection: IJclIntfCollection): Boolean; var It: IJclIntfIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntfHashSet.Extract(const AInterface: IInterface): Boolean; begin Result := FMap.Extract(AInterface) = RefUnique; end; function TJclIntfHashSet.ExtractAll(const ACollection: IJclIntfCollection): Boolean; var It: IJclIntfIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntfHashSet.First: IJclIntfIterator; begin Result := FMap.KeySet.First; end; function TJclIntfHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclIntfHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclIntfHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclIntfHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclIntfHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclIntfHashSet.GetEnumerator: IJclIntfIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclIntfHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclIntfHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclIntfHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclIntfHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclIntfHashSet.Intersect(const ACollection: IJclIntfCollection); begin RetainAll(ACollection); end; function TJclIntfHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclIntfHashSet.Last: IJclIntfIterator; begin Result := FMap.KeySet.Last; end; procedure TJclIntfHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclIntfHashSet.Remove(const AInterface: IInterface): Boolean; begin Result := FMap.Remove(AInterface) = RefUnique; end; function TJclIntfHashSet.RemoveAll(const ACollection: IJclIntfCollection): Boolean; var It: IJclIntfIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntfHashSet.RetainAll(const ACollection: IJclIntfCollection): Boolean; var ItMap: IJclIntfIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclIntfHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclIntfHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclIntfHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclIntfHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclIntfHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclIntfHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclIntfHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclIntfHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclIntfHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclIntfHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclIntfHashSet.Subtract(const ACollection: IJclIntfCollection); begin RemoveAll(ACollection); end; procedure TJclIntfHashSet.Union(const ACollection: IJclIntfCollection); begin AddAll(ACollection); end; constructor TJclIntfHashSet.Create(ACapacity: Integer); begin Create(TJclIntfHashMap.Create(ACapacity, False)); end; function TJclIntfHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclIntfHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; //=== { TJclAnsiStrHashSet } ===================================================== constructor TJclAnsiStrHashSet.Create(const AMap: IJclAnsiStrMap); begin inherited Create(); FMap := AMap; end; destructor TJclAnsiStrHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclAnsiStrHashSet.Add(const AString: AnsiString): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AString); if Result then FMap.PutValue(AString, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclAnsiStrHashSet.AddAll(const ACollection: IJclAnsiStrCollection): Boolean; var It: IJclAnsiStrIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclAnsiStrHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclAnsiStrHashSet then TJclAnsiStrHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclAnsiStrMap; end; procedure TJclAnsiStrHashSet.Clear; begin FMap.Clear; end; function TJclAnsiStrHashSet.CollectionEquals(const ACollection: IJclAnsiStrCollection): Boolean; var It, ItMap: IJclAnsiStrIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclAnsiStrHashSet.Contains(const AString: AnsiString): Boolean; begin Result := FMap.ContainsKey(AString); end; function TJclAnsiStrHashSet.ContainsAll(const ACollection: IJclAnsiStrCollection): Boolean; var It: IJclAnsiStrIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclAnsiStrHashSet.Extract(const AString: AnsiString): Boolean; begin Result := FMap.Extract(AString) = RefUnique; end; function TJclAnsiStrHashSet.ExtractAll(const ACollection: IJclAnsiStrCollection): Boolean; var It: IJclAnsiStrIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclAnsiStrHashSet.First: IJclAnsiStrIterator; begin Result := FMap.KeySet.First; end; function TJclAnsiStrHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclAnsiStrHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclAnsiStrHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclAnsiStrHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclAnsiStrHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclAnsiStrHashSet.GetEnumerator: IJclAnsiStrIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclAnsiStrHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclAnsiStrHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclAnsiStrHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclAnsiStrHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclAnsiStrHashSet.Intersect(const ACollection: IJclAnsiStrCollection); begin RetainAll(ACollection); end; function TJclAnsiStrHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclAnsiStrHashSet.Last: IJclAnsiStrIterator; begin Result := FMap.KeySet.Last; end; procedure TJclAnsiStrHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclAnsiStrHashSet.Remove(const AString: AnsiString): Boolean; begin Result := FMap.Remove(AString) = RefUnique; end; function TJclAnsiStrHashSet.RemoveAll(const ACollection: IJclAnsiStrCollection): Boolean; var It: IJclAnsiStrIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclAnsiStrHashSet.RetainAll(const ACollection: IJclAnsiStrCollection): Boolean; var ItMap: IJclAnsiStrIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclAnsiStrHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclAnsiStrHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclAnsiStrHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclAnsiStrHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclAnsiStrHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclAnsiStrHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclAnsiStrHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclAnsiStrHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclAnsiStrHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclAnsiStrHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclAnsiStrHashSet.Subtract(const ACollection: IJclAnsiStrCollection); begin RemoveAll(ACollection); end; procedure TJclAnsiStrHashSet.Union(const ACollection: IJclAnsiStrCollection); begin AddAll(ACollection); end; constructor TJclAnsiStrHashSet.Create(ACapacity: Integer); begin Create(TJclAnsiStrHashMap.Create(ACapacity, False)); end; function TJclAnsiStrHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclAnsiStrHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; function TJclAnsiStrHashSet.GetCaseSensitive: Boolean; begin Result := FMap.GetCaseSensitive; end; function TJclAnsiStrHashSet.GetEncoding: TJclAnsiStrEncoding; begin Result := FMap.GetEncoding; end; procedure TJclAnsiStrHashSet.SetCaseSensitive(Value: Boolean); begin FMap.SetCaseSensitive(Value); end; procedure TJclAnsiStrHashSet.SetEncoding(Value: TJclAnsiStrEncoding); begin FMap.SetEncoding(Value); end; //=== { TJclWideStrHashSet } ===================================================== constructor TJclWideStrHashSet.Create(const AMap: IJclWideStrMap); begin inherited Create(); FMap := AMap; end; destructor TJclWideStrHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclWideStrHashSet.Add(const AString: WideString): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AString); if Result then FMap.PutValue(AString, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclWideStrHashSet.AddAll(const ACollection: IJclWideStrCollection): Boolean; var It: IJclWideStrIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclWideStrHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclWideStrHashSet then TJclWideStrHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclWideStrMap; end; procedure TJclWideStrHashSet.Clear; begin FMap.Clear; end; function TJclWideStrHashSet.CollectionEquals(const ACollection: IJclWideStrCollection): Boolean; var It, ItMap: IJclWideStrIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclWideStrHashSet.Contains(const AString: WideString): Boolean; begin Result := FMap.ContainsKey(AString); end; function TJclWideStrHashSet.ContainsAll(const ACollection: IJclWideStrCollection): Boolean; var It: IJclWideStrIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclWideStrHashSet.Extract(const AString: WideString): Boolean; begin Result := FMap.Extract(AString) = RefUnique; end; function TJclWideStrHashSet.ExtractAll(const ACollection: IJclWideStrCollection): Boolean; var It: IJclWideStrIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclWideStrHashSet.First: IJclWideStrIterator; begin Result := FMap.KeySet.First; end; function TJclWideStrHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclWideStrHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclWideStrHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclWideStrHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclWideStrHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclWideStrHashSet.GetEnumerator: IJclWideStrIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclWideStrHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclWideStrHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclWideStrHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclWideStrHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclWideStrHashSet.Intersect(const ACollection: IJclWideStrCollection); begin RetainAll(ACollection); end; function TJclWideStrHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclWideStrHashSet.Last: IJclWideStrIterator; begin Result := FMap.KeySet.Last; end; procedure TJclWideStrHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclWideStrHashSet.Remove(const AString: WideString): Boolean; begin Result := FMap.Remove(AString) = RefUnique; end; function TJclWideStrHashSet.RemoveAll(const ACollection: IJclWideStrCollection): Boolean; var It: IJclWideStrIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclWideStrHashSet.RetainAll(const ACollection: IJclWideStrCollection): Boolean; var ItMap: IJclWideStrIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclWideStrHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclWideStrHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclWideStrHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclWideStrHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclWideStrHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclWideStrHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclWideStrHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclWideStrHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclWideStrHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclWideStrHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclWideStrHashSet.Subtract(const ACollection: IJclWideStrCollection); begin RemoveAll(ACollection); end; procedure TJclWideStrHashSet.Union(const ACollection: IJclWideStrCollection); begin AddAll(ACollection); end; constructor TJclWideStrHashSet.Create(ACapacity: Integer); begin Create(TJclWideStrHashMap.Create(ACapacity, False)); end; function TJclWideStrHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclWideStrHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; function TJclWideStrHashSet.GetCaseSensitive: Boolean; begin Result := FMap.GetCaseSensitive; end; function TJclWideStrHashSet.GetEncoding: TJclWideStrEncoding; begin Result := FMap.GetEncoding; end; procedure TJclWideStrHashSet.SetCaseSensitive(Value: Boolean); begin FMap.SetCaseSensitive(Value); end; procedure TJclWideStrHashSet.SetEncoding(Value: TJclWideStrEncoding); begin FMap.SetEncoding(Value); end; {$IFDEF SUPPORTS_UNICODE_STRING} //=== { TJclUnicodeStrHashSet } ===================================================== constructor TJclUnicodeStrHashSet.Create(const AMap: IJclUnicodeStrMap); begin inherited Create(); FMap := AMap; end; destructor TJclUnicodeStrHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclUnicodeStrHashSet.Add(const AString: UnicodeString): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AString); if Result then FMap.PutValue(AString, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclUnicodeStrHashSet.AddAll(const ACollection: IJclUnicodeStrCollection): Boolean; var It: IJclUnicodeStrIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclUnicodeStrHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclUnicodeStrHashSet then TJclUnicodeStrHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclUnicodeStrMap; end; procedure TJclUnicodeStrHashSet.Clear; begin FMap.Clear; end; function TJclUnicodeStrHashSet.CollectionEquals(const ACollection: IJclUnicodeStrCollection): Boolean; var It, ItMap: IJclUnicodeStrIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclUnicodeStrHashSet.Contains(const AString: UnicodeString): Boolean; begin Result := FMap.ContainsKey(AString); end; function TJclUnicodeStrHashSet.ContainsAll(const ACollection: IJclUnicodeStrCollection): Boolean; var It: IJclUnicodeStrIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclUnicodeStrHashSet.Extract(const AString: UnicodeString): Boolean; begin Result := FMap.Extract(AString) = RefUnique; end; function TJclUnicodeStrHashSet.ExtractAll(const ACollection: IJclUnicodeStrCollection): Boolean; var It: IJclUnicodeStrIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclUnicodeStrHashSet.First: IJclUnicodeStrIterator; begin Result := FMap.KeySet.First; end; function TJclUnicodeStrHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclUnicodeStrHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclUnicodeStrHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclUnicodeStrHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclUnicodeStrHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclUnicodeStrHashSet.GetEnumerator: IJclUnicodeStrIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclUnicodeStrHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclUnicodeStrHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclUnicodeStrHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclUnicodeStrHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclUnicodeStrHashSet.Intersect(const ACollection: IJclUnicodeStrCollection); begin RetainAll(ACollection); end; function TJclUnicodeStrHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclUnicodeStrHashSet.Last: IJclUnicodeStrIterator; begin Result := FMap.KeySet.Last; end; procedure TJclUnicodeStrHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclUnicodeStrHashSet.Remove(const AString: UnicodeString): Boolean; begin Result := FMap.Remove(AString) = RefUnique; end; function TJclUnicodeStrHashSet.RemoveAll(const ACollection: IJclUnicodeStrCollection): Boolean; var It: IJclUnicodeStrIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclUnicodeStrHashSet.RetainAll(const ACollection: IJclUnicodeStrCollection): Boolean; var ItMap: IJclUnicodeStrIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclUnicodeStrHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclUnicodeStrHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclUnicodeStrHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclUnicodeStrHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclUnicodeStrHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclUnicodeStrHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclUnicodeStrHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclUnicodeStrHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclUnicodeStrHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclUnicodeStrHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclUnicodeStrHashSet.Subtract(const ACollection: IJclUnicodeStrCollection); begin RemoveAll(ACollection); end; procedure TJclUnicodeStrHashSet.Union(const ACollection: IJclUnicodeStrCollection); begin AddAll(ACollection); end; constructor TJclUnicodeStrHashSet.Create(ACapacity: Integer); begin Create(TJclUnicodeStrHashMap.Create(ACapacity, False)); end; function TJclUnicodeStrHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclUnicodeStrHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; function TJclUnicodeStrHashSet.GetCaseSensitive: Boolean; begin Result := FMap.GetCaseSensitive; end; procedure TJclUnicodeStrHashSet.SetCaseSensitive(Value: Boolean); begin FMap.SetCaseSensitive(Value); end; {$ENDIF SUPPORTS_UNICODE_STRING} //=== { TJclSingleHashSet } ===================================================== constructor TJclSingleHashSet.Create(const AMap: IJclSingleMap); begin inherited Create(); FMap := AMap; end; destructor TJclSingleHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclSingleHashSet.Add(const AValue: Single): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AValue); if Result then FMap.PutValue(AValue, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclSingleHashSet.AddAll(const ACollection: IJclSingleCollection): Boolean; var It: IJclSingleIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclSingleHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclSingleHashSet then TJclSingleHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclSingleMap; end; procedure TJclSingleHashSet.Clear; begin FMap.Clear; end; function TJclSingleHashSet.CollectionEquals(const ACollection: IJclSingleCollection): Boolean; var It, ItMap: IJclSingleIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclSingleHashSet.Contains(const AValue: Single): Boolean; begin Result := FMap.ContainsKey(AValue); end; function TJclSingleHashSet.ContainsAll(const ACollection: IJclSingleCollection): Boolean; var It: IJclSingleIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclSingleHashSet.Extract(const AValue: Single): Boolean; begin Result := FMap.Extract(AValue) = RefUnique; end; function TJclSingleHashSet.ExtractAll(const ACollection: IJclSingleCollection): Boolean; var It: IJclSingleIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclSingleHashSet.First: IJclSingleIterator; begin Result := FMap.KeySet.First; end; function TJclSingleHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclSingleHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclSingleHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclSingleHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclSingleHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclSingleHashSet.GetEnumerator: IJclSingleIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclSingleHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclSingleHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclSingleHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclSingleHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclSingleHashSet.Intersect(const ACollection: IJclSingleCollection); begin RetainAll(ACollection); end; function TJclSingleHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclSingleHashSet.Last: IJclSingleIterator; begin Result := FMap.KeySet.Last; end; procedure TJclSingleHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclSingleHashSet.Remove(const AValue: Single): Boolean; begin Result := FMap.Remove(AValue) = RefUnique; end; function TJclSingleHashSet.RemoveAll(const ACollection: IJclSingleCollection): Boolean; var It: IJclSingleIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclSingleHashSet.RetainAll(const ACollection: IJclSingleCollection): Boolean; var ItMap: IJclSingleIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclSingleHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclSingleHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclSingleHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclSingleHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclSingleHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclSingleHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclSingleHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclSingleHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclSingleHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclSingleHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclSingleHashSet.Subtract(const ACollection: IJclSingleCollection); begin RemoveAll(ACollection); end; procedure TJclSingleHashSet.Union(const ACollection: IJclSingleCollection); begin AddAll(ACollection); end; constructor TJclSingleHashSet.Create(ACapacity: Integer); begin Create(TJclSingleHashMap.Create(ACapacity, False)); end; function TJclSingleHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclSingleHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; function TJclSingleHashSet.GetPrecision: Single; begin Result := FMap.GetPrecision; end; procedure TJclSingleHashSet.SetPrecision(const Value: Single); begin FMap.SetPrecision(Value); end; //=== { TJclDoubleHashSet } ===================================================== constructor TJclDoubleHashSet.Create(const AMap: IJclDoubleMap); begin inherited Create(); FMap := AMap; end; destructor TJclDoubleHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclDoubleHashSet.Add(const AValue: Double): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AValue); if Result then FMap.PutValue(AValue, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclDoubleHashSet.AddAll(const ACollection: IJclDoubleCollection): Boolean; var It: IJclDoubleIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclDoubleHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclDoubleHashSet then TJclDoubleHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclDoubleMap; end; procedure TJclDoubleHashSet.Clear; begin FMap.Clear; end; function TJclDoubleHashSet.CollectionEquals(const ACollection: IJclDoubleCollection): Boolean; var It, ItMap: IJclDoubleIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclDoubleHashSet.Contains(const AValue: Double): Boolean; begin Result := FMap.ContainsKey(AValue); end; function TJclDoubleHashSet.ContainsAll(const ACollection: IJclDoubleCollection): Boolean; var It: IJclDoubleIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclDoubleHashSet.Extract(const AValue: Double): Boolean; begin Result := FMap.Extract(AValue) = RefUnique; end; function TJclDoubleHashSet.ExtractAll(const ACollection: IJclDoubleCollection): Boolean; var It: IJclDoubleIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclDoubleHashSet.First: IJclDoubleIterator; begin Result := FMap.KeySet.First; end; function TJclDoubleHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclDoubleHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclDoubleHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclDoubleHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclDoubleHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclDoubleHashSet.GetEnumerator: IJclDoubleIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclDoubleHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclDoubleHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclDoubleHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclDoubleHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclDoubleHashSet.Intersect(const ACollection: IJclDoubleCollection); begin RetainAll(ACollection); end; function TJclDoubleHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclDoubleHashSet.Last: IJclDoubleIterator; begin Result := FMap.KeySet.Last; end; procedure TJclDoubleHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclDoubleHashSet.Remove(const AValue: Double): Boolean; begin Result := FMap.Remove(AValue) = RefUnique; end; function TJclDoubleHashSet.RemoveAll(const ACollection: IJclDoubleCollection): Boolean; var It: IJclDoubleIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclDoubleHashSet.RetainAll(const ACollection: IJclDoubleCollection): Boolean; var ItMap: IJclDoubleIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclDoubleHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclDoubleHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclDoubleHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclDoubleHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclDoubleHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclDoubleHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclDoubleHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclDoubleHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclDoubleHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclDoubleHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclDoubleHashSet.Subtract(const ACollection: IJclDoubleCollection); begin RemoveAll(ACollection); end; procedure TJclDoubleHashSet.Union(const ACollection: IJclDoubleCollection); begin AddAll(ACollection); end; constructor TJclDoubleHashSet.Create(ACapacity: Integer); begin Create(TJclDoubleHashMap.Create(ACapacity, False)); end; function TJclDoubleHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclDoubleHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; function TJclDoubleHashSet.GetPrecision: Double; begin Result := FMap.GetPrecision; end; procedure TJclDoubleHashSet.SetPrecision(const Value: Double); begin FMap.SetPrecision(Value); end; //=== { TJclExtendedHashSet } ===================================================== constructor TJclExtendedHashSet.Create(const AMap: IJclExtendedMap); begin inherited Create(); FMap := AMap; end; destructor TJclExtendedHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclExtendedHashSet.Add(const AValue: Extended): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AValue); if Result then FMap.PutValue(AValue, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclExtendedHashSet.AddAll(const ACollection: IJclExtendedCollection): Boolean; var It: IJclExtendedIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclExtendedHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclExtendedHashSet then TJclExtendedHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclExtendedMap; end; procedure TJclExtendedHashSet.Clear; begin FMap.Clear; end; function TJclExtendedHashSet.CollectionEquals(const ACollection: IJclExtendedCollection): Boolean; var It, ItMap: IJclExtendedIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclExtendedHashSet.Contains(const AValue: Extended): Boolean; begin Result := FMap.ContainsKey(AValue); end; function TJclExtendedHashSet.ContainsAll(const ACollection: IJclExtendedCollection): Boolean; var It: IJclExtendedIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclExtendedHashSet.Extract(const AValue: Extended): Boolean; begin Result := FMap.Extract(AValue) = RefUnique; end; function TJclExtendedHashSet.ExtractAll(const ACollection: IJclExtendedCollection): Boolean; var It: IJclExtendedIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclExtendedHashSet.First: IJclExtendedIterator; begin Result := FMap.KeySet.First; end; function TJclExtendedHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclExtendedHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclExtendedHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclExtendedHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclExtendedHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclExtendedHashSet.GetEnumerator: IJclExtendedIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclExtendedHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclExtendedHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclExtendedHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclExtendedHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclExtendedHashSet.Intersect(const ACollection: IJclExtendedCollection); begin RetainAll(ACollection); end; function TJclExtendedHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclExtendedHashSet.Last: IJclExtendedIterator; begin Result := FMap.KeySet.Last; end; procedure TJclExtendedHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclExtendedHashSet.Remove(const AValue: Extended): Boolean; begin Result := FMap.Remove(AValue) = RefUnique; end; function TJclExtendedHashSet.RemoveAll(const ACollection: IJclExtendedCollection): Boolean; var It: IJclExtendedIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclExtendedHashSet.RetainAll(const ACollection: IJclExtendedCollection): Boolean; var ItMap: IJclExtendedIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclExtendedHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclExtendedHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclExtendedHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclExtendedHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclExtendedHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclExtendedHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclExtendedHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclExtendedHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclExtendedHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclExtendedHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclExtendedHashSet.Subtract(const ACollection: IJclExtendedCollection); begin RemoveAll(ACollection); end; procedure TJclExtendedHashSet.Union(const ACollection: IJclExtendedCollection); begin AddAll(ACollection); end; constructor TJclExtendedHashSet.Create(ACapacity: Integer); begin Create(TJclExtendedHashMap.Create(ACapacity, False)); end; function TJclExtendedHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclExtendedHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; function TJclExtendedHashSet.GetPrecision: Extended; begin Result := FMap.GetPrecision; end; procedure TJclExtendedHashSet.SetPrecision(const Value: Extended); begin FMap.SetPrecision(Value); end; //=== { TJclIntegerHashSet } ===================================================== constructor TJclIntegerHashSet.Create(const AMap: IJclIntegerMap); begin inherited Create(); FMap := AMap; end; destructor TJclIntegerHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclIntegerHashSet.Add(AValue: Integer): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AValue); if Result then FMap.PutValue(AValue, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntegerHashSet.AddAll(const ACollection: IJclIntegerCollection): Boolean; var It: IJclIntegerIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclIntegerHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclIntegerHashSet then TJclIntegerHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclIntegerMap; end; procedure TJclIntegerHashSet.Clear; begin FMap.Clear; end; function TJclIntegerHashSet.CollectionEquals(const ACollection: IJclIntegerCollection): Boolean; var It, ItMap: IJclIntegerIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntegerHashSet.Contains(AValue: Integer): Boolean; begin Result := FMap.ContainsKey(AValue); end; function TJclIntegerHashSet.ContainsAll(const ACollection: IJclIntegerCollection): Boolean; var It: IJclIntegerIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntegerHashSet.Extract(AValue: Integer): Boolean; begin Result := FMap.Extract(AValue) = RefUnique; end; function TJclIntegerHashSet.ExtractAll(const ACollection: IJclIntegerCollection): Boolean; var It: IJclIntegerIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntegerHashSet.First: IJclIntegerIterator; begin Result := FMap.KeySet.First; end; function TJclIntegerHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclIntegerHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclIntegerHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclIntegerHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclIntegerHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclIntegerHashSet.GetEnumerator: IJclIntegerIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclIntegerHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclIntegerHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclIntegerHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclIntegerHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclIntegerHashSet.Intersect(const ACollection: IJclIntegerCollection); begin RetainAll(ACollection); end; function TJclIntegerHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclIntegerHashSet.Last: IJclIntegerIterator; begin Result := FMap.KeySet.Last; end; procedure TJclIntegerHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclIntegerHashSet.Remove(AValue: Integer): Boolean; begin Result := FMap.Remove(AValue) = RefUnique; end; function TJclIntegerHashSet.RemoveAll(const ACollection: IJclIntegerCollection): Boolean; var It: IJclIntegerIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclIntegerHashSet.RetainAll(const ACollection: IJclIntegerCollection): Boolean; var ItMap: IJclIntegerIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclIntegerHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclIntegerHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclIntegerHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclIntegerHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclIntegerHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclIntegerHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclIntegerHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclIntegerHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclIntegerHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclIntegerHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclIntegerHashSet.Subtract(const ACollection: IJclIntegerCollection); begin RemoveAll(ACollection); end; procedure TJclIntegerHashSet.Union(const ACollection: IJclIntegerCollection); begin AddAll(ACollection); end; constructor TJclIntegerHashSet.Create(ACapacity: Integer); begin Create(TJclIntegerHashMap.Create(ACapacity, False)); end; function TJclIntegerHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclIntegerHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; //=== { TJclCardinalHashSet } ===================================================== constructor TJclCardinalHashSet.Create(const AMap: IJclCardinalMap); begin inherited Create(); FMap := AMap; end; destructor TJclCardinalHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclCardinalHashSet.Add(AValue: Cardinal): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AValue); if Result then FMap.PutValue(AValue, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclCardinalHashSet.AddAll(const ACollection: IJclCardinalCollection): Boolean; var It: IJclCardinalIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclCardinalHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclCardinalHashSet then TJclCardinalHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclCardinalMap; end; procedure TJclCardinalHashSet.Clear; begin FMap.Clear; end; function TJclCardinalHashSet.CollectionEquals(const ACollection: IJclCardinalCollection): Boolean; var It, ItMap: IJclCardinalIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclCardinalHashSet.Contains(AValue: Cardinal): Boolean; begin Result := FMap.ContainsKey(AValue); end; function TJclCardinalHashSet.ContainsAll(const ACollection: IJclCardinalCollection): Boolean; var It: IJclCardinalIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclCardinalHashSet.Extract(AValue: Cardinal): Boolean; begin Result := FMap.Extract(AValue) = RefUnique; end; function TJclCardinalHashSet.ExtractAll(const ACollection: IJclCardinalCollection): Boolean; var It: IJclCardinalIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclCardinalHashSet.First: IJclCardinalIterator; begin Result := FMap.KeySet.First; end; function TJclCardinalHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclCardinalHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclCardinalHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclCardinalHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclCardinalHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclCardinalHashSet.GetEnumerator: IJclCardinalIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclCardinalHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclCardinalHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclCardinalHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclCardinalHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclCardinalHashSet.Intersect(const ACollection: IJclCardinalCollection); begin RetainAll(ACollection); end; function TJclCardinalHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclCardinalHashSet.Last: IJclCardinalIterator; begin Result := FMap.KeySet.Last; end; procedure TJclCardinalHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclCardinalHashSet.Remove(AValue: Cardinal): Boolean; begin Result := FMap.Remove(AValue) = RefUnique; end; function TJclCardinalHashSet.RemoveAll(const ACollection: IJclCardinalCollection): Boolean; var It: IJclCardinalIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclCardinalHashSet.RetainAll(const ACollection: IJclCardinalCollection): Boolean; var ItMap: IJclCardinalIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclCardinalHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclCardinalHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclCardinalHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclCardinalHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclCardinalHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclCardinalHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclCardinalHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclCardinalHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclCardinalHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclCardinalHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclCardinalHashSet.Subtract(const ACollection: IJclCardinalCollection); begin RemoveAll(ACollection); end; procedure TJclCardinalHashSet.Union(const ACollection: IJclCardinalCollection); begin AddAll(ACollection); end; constructor TJclCardinalHashSet.Create(ACapacity: Integer); begin Create(TJclCardinalHashMap.Create(ACapacity, False)); end; function TJclCardinalHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclCardinalHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; //=== { TJclInt64HashSet } ===================================================== constructor TJclInt64HashSet.Create(const AMap: IJclInt64Map); begin inherited Create(); FMap := AMap; end; destructor TJclInt64HashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclInt64HashSet.Add(const AValue: Int64): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AValue); if Result then FMap.PutValue(AValue, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclInt64HashSet.AddAll(const ACollection: IJclInt64Collection): Boolean; var It: IJclInt64Iterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclInt64HashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclInt64HashSet then TJclInt64HashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclInt64Map; end; procedure TJclInt64HashSet.Clear; begin FMap.Clear; end; function TJclInt64HashSet.CollectionEquals(const ACollection: IJclInt64Collection): Boolean; var It, ItMap: IJclInt64Iterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclInt64HashSet.Contains(const AValue: Int64): Boolean; begin Result := FMap.ContainsKey(AValue); end; function TJclInt64HashSet.ContainsAll(const ACollection: IJclInt64Collection): Boolean; var It: IJclInt64Iterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclInt64HashSet.Extract(const AValue: Int64): Boolean; begin Result := FMap.Extract(AValue) = RefUnique; end; function TJclInt64HashSet.ExtractAll(const ACollection: IJclInt64Collection): Boolean; var It: IJclInt64Iterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclInt64HashSet.First: IJclInt64Iterator; begin Result := FMap.KeySet.First; end; function TJclInt64HashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclInt64HashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclInt64HashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclInt64HashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclInt64HashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclInt64HashSet.GetEnumerator: IJclInt64Iterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclInt64HashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclInt64HashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclInt64HashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclInt64HashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclInt64HashSet.Intersect(const ACollection: IJclInt64Collection); begin RetainAll(ACollection); end; function TJclInt64HashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclInt64HashSet.Last: IJclInt64Iterator; begin Result := FMap.KeySet.Last; end; procedure TJclInt64HashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclInt64HashSet.Remove(const AValue: Int64): Boolean; begin Result := FMap.Remove(AValue) = RefUnique; end; function TJclInt64HashSet.RemoveAll(const ACollection: IJclInt64Collection): Boolean; var It: IJclInt64Iterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclInt64HashSet.RetainAll(const ACollection: IJclInt64Collection): Boolean; var ItMap: IJclInt64Iterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclInt64HashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclInt64HashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclInt64HashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclInt64HashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclInt64HashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclInt64HashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclInt64HashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclInt64HashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclInt64HashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclInt64HashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclInt64HashSet.Subtract(const ACollection: IJclInt64Collection); begin RemoveAll(ACollection); end; procedure TJclInt64HashSet.Union(const ACollection: IJclInt64Collection); begin AddAll(ACollection); end; constructor TJclInt64HashSet.Create(ACapacity: Integer); begin Create(TJclInt64HashMap.Create(ACapacity, False)); end; function TJclInt64HashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclInt64HashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; //=== { TJclPtrHashSet } ===================================================== constructor TJclPtrHashSet.Create(const AMap: IJclPtrMap); begin inherited Create(); FMap := AMap; end; destructor TJclPtrHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclPtrHashSet.Add(AValue: Pointer): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AValue); if Result then FMap.PutValue(AValue, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclPtrHashSet.AddAll(const ACollection: IJclPtrCollection): Boolean; var It: IJclPtrIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclPtrHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclPtrHashSet then TJclPtrHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclPtrMap; end; procedure TJclPtrHashSet.Clear; begin FMap.Clear; end; function TJclPtrHashSet.CollectionEquals(const ACollection: IJclPtrCollection): Boolean; var It, ItMap: IJclPtrIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclPtrHashSet.Contains(AValue: Pointer): Boolean; begin Result := FMap.ContainsKey(AValue); end; function TJclPtrHashSet.ContainsAll(const ACollection: IJclPtrCollection): Boolean; var It: IJclPtrIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclPtrHashSet.Extract(AValue: Pointer): Boolean; begin Result := FMap.Extract(AValue) = RefUnique; end; function TJclPtrHashSet.ExtractAll(const ACollection: IJclPtrCollection): Boolean; var It: IJclPtrIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclPtrHashSet.First: IJclPtrIterator; begin Result := FMap.KeySet.First; end; function TJclPtrHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclPtrHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclPtrHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclPtrHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclPtrHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclPtrHashSet.GetEnumerator: IJclPtrIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclPtrHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclPtrHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclPtrHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclPtrHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclPtrHashSet.Intersect(const ACollection: IJclPtrCollection); begin RetainAll(ACollection); end; function TJclPtrHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclPtrHashSet.Last: IJclPtrIterator; begin Result := FMap.KeySet.Last; end; procedure TJclPtrHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclPtrHashSet.Remove(AValue: Pointer): Boolean; begin Result := FMap.Remove(AValue) = RefUnique; end; function TJclPtrHashSet.RemoveAll(const ACollection: IJclPtrCollection): Boolean; var It: IJclPtrIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclPtrHashSet.RetainAll(const ACollection: IJclPtrCollection): Boolean; var ItMap: IJclPtrIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclPtrHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclPtrHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclPtrHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclPtrHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclPtrHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclPtrHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclPtrHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclPtrHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclPtrHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclPtrHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclPtrHashSet.Subtract(const ACollection: IJclPtrCollection); begin RemoveAll(ACollection); end; procedure TJclPtrHashSet.Union(const ACollection: IJclPtrCollection); begin AddAll(ACollection); end; constructor TJclPtrHashSet.Create(ACapacity: Integer); begin Create(TJclPtrHashMap.Create(ACapacity, False)); end; function TJclPtrHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclPtrHashSet.Create(GetCapacity); AssignPropertiesTo(Result); end; //=== { TJclHashSet } ===================================================== constructor TJclHashSet.Create(const AMap: IJclMap); begin inherited Create(False); FMap := AMap; end; destructor TJclHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclHashSet.Add(AObject: TObject): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AObject); if Result then FMap.PutValue(AObject, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.AddAll(const ACollection: IJclCollection): Boolean; var It: IJclIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclHashSet then TJclHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclMap; end; procedure TJclHashSet.Clear; begin FMap.Clear; end; function TJclHashSet.CollectionEquals(const ACollection: IJclCollection): Boolean; var It, ItMap: IJclIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.Contains(AObject: TObject): Boolean; begin Result := FMap.ContainsKey(AObject); end; function TJclHashSet.ContainsAll(const ACollection: IJclCollection): Boolean; var It: IJclIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.Extract(AObject: TObject): Boolean; begin Result := FMap.Extract(AObject) = RefUnique; end; function TJclHashSet.ExtractAll(const ACollection: IJclCollection): Boolean; var It: IJclIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.First: IJclIterator; begin Result := FMap.KeySet.First; end; function TJclHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclHashSet.GetEnumerator: IJclIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclHashSet.Intersect(const ACollection: IJclCollection); begin RetainAll(ACollection); end; function TJclHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclHashSet.Last: IJclIterator; begin Result := FMap.KeySet.Last; end; procedure TJclHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclHashSet.Remove(AObject: TObject): Boolean; begin Result := FMap.Remove(AObject) = RefUnique; end; function TJclHashSet.RemoveAll(const ACollection: IJclCollection): Boolean; var It: IJclIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.RetainAll(const ACollection: IJclCollection): Boolean; var ItMap: IJclIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclHashSet.Subtract(const ACollection: IJclCollection); begin RemoveAll(ACollection); end; procedure TJclHashSet.Union(const ACollection: IJclCollection); begin AddAll(ACollection); end; constructor TJclHashSet.Create(ACapacity: Integer; AOwnsObjects: Boolean); begin Create(TJclHashMap.Create(ACapacity, AOwnsObjects, False)); end; function TJclHashSet.CreateEmptyContainer: TJclAbstractContainerBase; begin Result := TJclHashSet.Create(GetCapacity, False); AssignPropertiesTo(Result); end; function TJclHashSet.FreeObject(var AObject: TObject): TObject; begin Result := (FMap as IJclKeyOwner).FreeKey(AObject); end; function TJclHashSet.GetOwnsObjects: Boolean; begin Result := (FMap as IJclKeyOwner).GetOwnsKeys; end; {$IFDEF SUPPORTS_GENERICS} //=== { TJclHashSet } ===================================================== constructor TJclHashSet.Create(const AMap: IJclMap); begin inherited Create(False); FMap := AMap; end; destructor TJclHashSet.Destroy; begin FMap := nil; inherited Destroy; end; function TJclHashSet.Add(const AItem: T): Boolean; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := not FMap.ContainsKey(AItem); if Result then FMap.PutValue(AItem, RefUnique); {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.AddAll(const ACollection: IJclCollection): Boolean; var It: IJclIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while It.HasNext do Result := Add(It.Next) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclHashSet.AssignDataTo(Dest: TJclAbstractContainerBase); begin inherited AssignDataTo(Dest); if Dest is TJclHashSet then TJclHashSet(Dest).FMap := (FMap as IJclIntfCloneable).IntfClone as IJclMap; end; procedure TJclHashSet.Clear; begin FMap.Clear; end; function TJclHashSet.CollectionEquals(const ACollection: IJclCollection): Boolean; var It, ItMap: IJclIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; if FMap.Size <> ACollection.Size then Exit; Result := True; It := ACollection.First; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ItemsEqual(ItMap.Next, It.Next) then begin Result := False; Exit; end; {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.Contains(const AItem: T): Boolean; begin Result := FMap.ContainsKey(AItem); end; function TJclHashSet.ContainsAll(const ACollection: IJclCollection): Boolean; var It: IJclIterator; begin {$IFDEF THREADSAFE} FMap.ReadLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; It := ACollection.First; while Result and It.HasNext do Result := FMap.ContainsKey(It.Next); {$IFDEF THREADSAFE} finally FMap.ReadUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.Extract(const AItem: T): Boolean; begin Result := FMap.Extract(AItem) = RefUnique; end; function TJclHashSet.ExtractAll(const ACollection: IJclCollection): Boolean; var It: IJclIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Extract(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.First: IJclIterator; begin Result := FMap.KeySet.First; end; function TJclHashSet.GetAutoPackParameter: Integer; begin Result := (FMap as IJclPackable).GetAutoPackParameter; end; function TJclHashSet.GetAutoPackStrategy: TJclAutoPackStrategy; begin Result := (FMap as IJclPackable).GetAutoPackStrategy; end; function TJclHashSet.GetCapacity: Integer; begin Result := (FMap as IJclPackable).GetCapacity; end; function TJclHashSet.GetAllowDefaultElements: Boolean; begin Result := FMap.AllowDefaultElements; end; function TJclHashSet.GetDuplicates: TDuplicates; begin Result := FMap.Duplicates; end; {$IFDEF SUPPORTS_FOR_IN} function TJclHashSet.GetEnumerator: IJclIterator; begin Result := FMap.KeySet.First; end; {$ENDIF SUPPORTS_FOR_IN} function TJclHashSet.GetReadOnly: Boolean; begin Result := FMap.ReadOnly; end; function TJclHashSet.GetRemoveSingleElement: Boolean; begin Result := FMap.RemoveSingleElement; end; function TJclHashSet.GetReturnDefaultElements: Boolean; begin Result := FMap.ReturnDefaultElements; end; function TJclHashSet.GetThreadSafe: Boolean; begin Result := FMap.ThreadSafe; end; procedure TJclHashSet.Intersect(const ACollection: IJclCollection); begin RetainAll(ACollection); end; function TJclHashSet.IsEmpty: Boolean; begin Result := FMap.IsEmpty; end; function TJclHashSet.Last: IJclIterator; begin Result := FMap.KeySet.Last; end; procedure TJclHashSet.Pack; begin (FMap as IJclPackable).Pack; end; function TJclHashSet.Remove(const AItem: T): Boolean; begin Result := FMap.Remove(AItem) = RefUnique; end; function TJclHashSet.RemoveAll(const ACollection: IJclCollection): Boolean; var It: IJclIterator; ARefUnique: TRefUnique; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ARefUnique := RefUnique; It := ACollection.First; while It.HasNext do Result := (FMap.Remove(It.Next) = ARefUnique) and Result; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; function TJclHashSet.RetainAll(const ACollection: IJclCollection): Boolean; var ItMap: IJclIterator; begin if FMap.ReadOnly then raise EJclReadOnlyError.Create; {$IFDEF THREADSAFE} FMap.WriteLock; try {$ENDIF THREADSAFE} Result := False; if ACollection = nil then Exit; Result := True; ItMap := FMap.KeySet.First; while ItMap.HasNext do if not ACollection.Contains(ItMap.Next) then ItMap.Remove; {$IFDEF THREADSAFE} finally FMap.WriteUnlock; end; {$ENDIF THREADSAFE} end; procedure TJclHashSet.SetAutoPackParameter(Value: Integer); begin (FMap as IJclPackable).SetAutoPackParameter(Value); end; procedure TJclHashSet.SetAutoPackStrategy(Value: TJclAutoPackStrategy); begin (FMap as IJclPackable).SetAutoPackStrategy(Value); end; procedure TJclHashSet.SetCapacity(Value: Integer); begin (FMap as IJclPackable).SetCapacity(Value); end; procedure TJclHashSet.SetAllowDefaultElements(Value: Boolean); begin FMap.AllowDefaultElements := Value; end; procedure TJclHashSet.SetDuplicates(Value: TDuplicates); begin FMap.Duplicates := Value; end; procedure TJclHashSet.SetReadOnly(Value: Boolean); begin FMap.ReadOnly := Value; end; procedure TJclHashSet.SetRemoveSingleElement(Value: Boolean); begin FMap.RemoveSingleElement := Value; end; procedure TJclHashSet.SetReturnDefaultElements(Value: Boolean); begin FMap.ReturnDefaultElements := Value; end; procedure TJclHashSet.SetThreadSafe(Value: Boolean); begin FMap.ThreadSafe := Value; end; function TJclHashSet.Size: Integer; begin Result := FMap.Size; end; procedure TJclHashSet.Subtract(const ACollection: IJclCollection); begin RemoveAll(ACollection); end; procedure TJclHashSet.Union(const ACollection: IJclCollection); begin AddAll(ACollection); end; function TJclHashSet.FreeItem(var AItem: T): T; begin Result := (FMap as IJclPairOwner).FreeKey(AItem); end; function TJclHashSet.GetOwnsItems: Boolean; begin Result := (FMap as IJclPairOwner).GetOwnsKeys; end; //=== { TJclHashSetE } ==================================================== constructor TJclHashSetE.Create(const AEqualityComparer: IJclEqualityComparer; const AHashConverter: IJclHashConverter; const AMap: IJclMap); begin inherited Create(AMap); FEqualityComparer := AEqualityComparer; FHashConverter := AHashConverter; end; constructor TJclHashSetE.Create(const AEqualityComparer: IJclEqualityComparer; const AHashConverter: IJclHashConverter; const AComparer: IJclComparer; ACapacity: Integer; AOwnsItems: Boolean); begin Create(AEqualityComparer, AHashConverter, TJclHashMapE.Create(AEqualityComparer, AHashConverter, RefUnique, AComparer, ACapacity, False, AOwnsItems)); end; procedure TJclHashSetE.AssignPropertiesTo(Dest: TJclAbstractContainerBase); begin inherited AssignPropertiesTo(Dest); if Dest is TJclHashSetE then TJclHashSetE(Dest).FEqualityComparer := FEqualityComparer; end; function TJclHashSetE.CreateEmptyContainer: TJclAbstractContainerBase; var AMap: IJclMap; begin AMap := (FMap as IJclIntfCloneable).IntfClone as IJclMap; AMap.Clear; Result := TJclHashSetE.Create(FEqualityComparer, FHashConverter, AMap); AssignPropertiesTo(Result); end; function TJclHashSetE.ItemsEqual(const A, B: T): Boolean; begin if EqualityComparer <> nil then Result := EqualityComparer.ItemsEqual(A, B) else Result := inherited ItemsEqual(A, B); end; //=== { TJclHashSetF } ==================================================== constructor TJclHashSetF.Create(const AEqualityCompare: TEqualityCompare; const AMap: IJclMap); begin inherited Create(AMap); SetEqualityCompare(AEqualityCompare); end; constructor TJclHashSetF.Create(const AEqualityCompare: TEqualityCompare; const AHash: THashConvert; const ACompare: TCompare; ACapacity: Integer; AOwnsItems: Boolean); begin Create(AEqualityCompare, TJclHashMapF.Create(AEqualityCompare, AHash, EqualityCompareEqObjects, ACompare, ACapacity, AOwnsItems, False)); end; function TJclHashSetF.CreateEmptyContainer: TJclAbstractContainerBase; var AMap: IJclMap; begin AMap := (FMap as IJclIntfCloneable).IntfClone as IJclMap; AMap.Clear; Result := TJclHashSetF.Create(FEqualityCompare, AMap); AssignPropertiesTo(Result); end; //=== { TJclHashSetI } ==================================================== constructor TJclHashSetI.Create(const AMap: IJclMap); begin inherited Create(AMap); end; constructor TJclHashSetI.Create(ACapacity: Integer; AOwnsItems: Boolean); begin Create(TJclHashMapI.Create(ACapacity, AOwnsItems, False)); end; function TJclHashSetI.CreateEmptyContainer: TJclAbstractContainerBase; var AMap: IJclMap; begin AMap := (FMap as IJclIntfCloneable).IntfClone as IJclMap; AMap.Clear; Result := TJclHashSetI.Create(AMap); AssignPropertiesTo(Result); end; function TJclHashSetI.ItemsEqual(const A, B: T): Boolean; begin if Assigned(FEqualityCompare) then Result := FEqualityCompare(A, B) else if Assigned(FCompare) then Result := FCompare(A, B) = 0 else Result := A.Equals(B); end; {$ENDIF SUPPORTS_GENERICS} initialization {$IFDEF UNITVERSIONING} RegisterUnitVersion(HInstance, UnitVersioning); {$ENDIF UNITVERSIONING} finalization {$IFDEF UNITVERSIONING} UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} FreeAndNil(GlobalRefUnique); end.