unit CollWrappers;
(*****************************************************************************
* Copyright 2003 by Matthew Greet
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details. (http://opensource.org/licenses/lgpl-license.php)
*
* See http://www.warmachine.u-net.com/delphi_collections for updates and downloads.
*
* $Version: v1.0.3 $
* $Revision: 1.1.1.1 $
* $Log: D:\QVCS Repositories\Delphi Collections\CollWrappers.qbt $
*
* Various primitive type wrappers, adapters and abstract base classes for
* natural items.
*
* Revision 1.1.1.1 by: Matthew Greet Rev date: 24/10/03 16:48:16
* v1.0 branch.
*
* Revision 1.1 by: Matthew Greet Rev date: 06/04/03 10:51:04
* Primitive type wrapper interfaces added.
* Abstract, template classes added.
* All classes implement reference counting by descending from
* TInterfacedObject.
*
*
* Revision 1.0 by: Matthew Greet Rev date: 01/03/03 10:50:02
* Initial revision.
*
* FPC compatibility fixes by: UltraStar Deluxe Team
*
* $Endlog$
*****************************************************************************)
{$IFDEF FPC}
{$MODE Delphi}{$H+}
{$ENDIF}
interface
uses
SysUtils,
Collections;
type
IAssociationWrapper = interface
['{54DF42E0-64F2-11D7-8120-0002E3165EF8}']
function GetAutoDestroy: Boolean;
procedure SetAutoDestroy(Value: Boolean);
function GetKey: ICollectable;
function GetValue: TObject;
property AutoDestroy: Boolean read GetAutoDestroy write SetAutoDestroy;
property Key: ICollectable read GetKey;
property Value: TObject read GetValue;
end;
IBoolean = interface
['{62D1D160-64F2-11D7-8120-0002E3165EF8}']
function GetValue: Boolean;
property Value: Boolean read GetValue;
end;
ICardinal = interface
['{6AF7B1C0-64F2-11D7-8120-0002E3165EF8}']
function GetValue: Cardinal;
property Value: Cardinal read GetValue;
end;
IChar = interface
['{73AD00E0-64F2-11D7-8120-0002E3165EF8}']
function GetValue: Char;
property Value: Char read GetValue;
end;
IClass = interface
['{7A84B660-64F2-11D7-8120-0002E3165EF8}']
function GetValue: TClass;
property Value: TClass read GetValue;
end;
IDouble = interface
['{815C6BE0-64F2-11D7-8120-0002E3165EF8}']
function GetValue: Double;
property Value: Double read GetValue;
end;
IInteger = interface
['{88ECC300-64F2-11D7-8120-0002E3165EF8}']
function GetValue: Integer;
property Value: Integer read GetValue;
end;
IIntegerAssociationWrapper = interface
['{8F582220-64F2-11D7-8120-0002E3165EF8}']
function GetAutoDestroy: Boolean;
procedure SetAutoDestroy(Value: Boolean);
function GetKey: Integer;
function GetValue: TObject;
property AutoDestroy: Boolean read GetAutoDestroy write SetAutoDestroy;
property Key: Integer read GetKey;
property Value: TObject read GetValue;
end;
IInterfaceWrapper = interface
['{962E5100-64F2-11D7-8120-0002E3165EF8}']
function GetValue: IUnknown;
property Value: IUnknown read GetValue;
end;
IObject = interface
['{9C675580-64F2-11D7-8120-0002E3165EF8}']
function GetAutoDestroy: Boolean;
procedure SetAutoDestroy(Value: Boolean);
function GetValue: TObject;
property Value: TObject read GetValue;
end;
IString = interface
['{A420DF80-64F2-11D7-8120-0002E3165EF8}']
function GetValue: String;
property Value: String read GetValue;
end;
IStringAssociationWrapper = interface
['{AB98CCA0-64F2-11D7-8120-0002E3165EF8}']
function GetAutoDestroy: Boolean;
procedure SetAutoDestroy(Value: Boolean);
function GetKey: String;
function GetValue: TObject;
property AutoDestroy: Boolean read GetAutoDestroy write SetAutoDestroy;
property Key: String read GetKey;
property Value: TObject read GetValue;
end;
TAbstractItem = class(TInterfacedObject, ICollectable)
public
function GetInstance: TObject; virtual;
end;
TAbstractIntegerMappable = class(TAbstractItem, IEquatable, IIntegerMappable)
private
FKey: Integer;
protected
function MakeKey: Integer; virtual; abstract;
public
procedure AfterConstruction; override;
function Equals(const Item: ICollectable): Boolean; virtual;
function GetKey: Integer; virtual;
end;
TAbstractMappable = class(TAbstractItem, IEquatable, IMappable)
private
FKey: ICollectable;
protected
function MakeKey: ICollectable; virtual; abstract;
public
destructor Destroy; override;
procedure AfterConstruction; override;
function Equals(const Item: ICollectable): Boolean; virtual;
function GetKey: ICollectable; virtual;
end;
TAbstractStringMappable = class(TAbstractItem, IEquatable, IStringMappable)
private
FKey: String;
protected
function MakeKey: String; virtual; abstract;
public
procedure AfterConstruction; override;
function Equals(const Item: ICollectable): Boolean; virtual;
function GetKey: String; virtual;
end;
TAssociationWrapper = class(TAbstractItem, IEquatable, IMappable, IAssociationWrapper)
private
FAutoDestroy: Boolean;
FKey: ICollectable;
FValue: TObject;
public
constructor Create(const Key: ICollectable; Value: TObject); overload;
constructor Create(Key: Integer; Value: TObject); overload;
constructor Create(Key: String; Value: TObject); overload;
constructor Create(Key, Value: TObject; AutoDestroyKey: Boolean = true); overload;
destructor Destroy; override;
function GetAutoDestroy: Boolean;
procedure SetAutoDestroy(Value: Boolean);
function GetKey: ICollectable;
function GetValue: TObject;
function Equals(const Item: ICollectable): Boolean;
property AutoDestroy: Boolean read GetAutoDestroy write SetAutoDestroy;
property Key: ICollectable read GetKey;
property Value: TObject read GetValue;
end;
TBooleanWrapper = class(TAbstractItem, IEquatable, IHashable, IComparable, IBoolean)
private
FValue: Boolean;
public
constructor Create(Value: Boolean);
function GetValue: Boolean;
function CompareTo(const Item: ICollectable): Integer;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
property Value: Boolean read GetValue;
end;
TCardinalWrapper = class(TAbstractItem, IEquatable, IHashable, IComparable, ICardinal)
private
FValue: Cardinal;
public
constructor Create(Value: Cardinal);
function GetValue: Cardinal;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
function CompareTo(const Item: ICollectable): Integer;
property Value: Cardinal read GetValue;
end;
TCharWrapper = class(TAbstractItem, IEquatable, IHashable, IComparable, IChar)
private
FValue: Char;
public
constructor Create(Value: Char);
function GetValue: Char;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
function CompareTo(const Item: ICollectable): Integer;
property Value: Char read GetValue;
end;
TClassWrapper = class(TAbstractItem, IEquatable, IHashable, IClass)
private
FValue: TClass;
public
constructor Create(Value: TClass);
function GetValue: TClass;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
property Value: TClass read GetValue;
end;
TDoubleWrapper = class(TAbstractItem, IEquatable, IHashable, IComparable, IDouble)
private
FValue: Double;
public
constructor Create(Value: Double);
function GetValue: Double;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
function CompareTo(const Item: ICollectable): Integer;
property Value: Double read GetValue;
end;
TIntegerWrapper = class(TAbstractItem, IEquatable, IHashable, IComparable, IInteger)
private
FValue: Integer;
public
constructor Create(Value: Integer);
function GetValue: Integer;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
function CompareTo(const Item: ICollectable): Integer;
property Value: Integer read GetValue;
end;
TIntegerAssociationWrapper = class(TAbstractItem, IEquatable, IIntegerMappable, IIntegerAssociationWrapper)
private
FAutoDestroy: Boolean;
FKey: Integer;
FValue: TObject;
public
constructor Create(const Key: Integer; Value: TObject); overload;
destructor Destroy; override;
function Equals(const Item: ICollectable): Boolean;
function GetAutoDestroy: Boolean;
procedure SetAutoDestroy(Value: Boolean);
function GetKey: Integer;
function GetValue: TObject;
property AutoDestroy: Boolean read GetAutoDestroy write SetAutoDestroy;
property Key: Integer read GetKey;
property Value: TObject read GetValue;
end;
TInterfaceWrapper = class(TAbstractItem, IHashable, IEquatable, IInterfaceWrapper)
private
FValue: IUnknown;
public
constructor Create(const Value: IUnknown);
destructor Destroy; override;
function GetValue: IUnknown;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
property Value: IUnknown read GetValue;
end;
TObjectWrapper = class(TAbstractItem, IEquatable, IComparable, IHashable, IObject)
private
FAutoDestroy: Boolean;
FValue: TObject;
public
constructor Create(Value: TObject); overload;
destructor Destroy; override;
function GetAutoDestroy: Boolean;
procedure SetAutoDestroy(Value: Boolean);
function GetValue: TObject;
function CompareTo(const Item: ICollectable): Integer;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
property AutoDestroy: Boolean read FAutoDestroy write FAutoDestroy;
property Value: TObject read GetValue;
end;
TStringWrapper = class(TAbstractItem, IEquatable, IHashable, IComparable, IString)
private
FValue: String;
public
constructor Create(Value: String);
function GetValue: String;
function Equals(const Item: ICollectable): Boolean;
function HashCode: Integer;
function CompareTo(const Item: ICollectable): Integer;
property Value: String read FValue;
end;
TStringAssociationWrapper = class(TAbstractItem, IEquatable, IStringMappable, IStringAssociationWrapper)
private
FAutoDestroy: Boolean;
FKey: String;
FValue: TObject;
public
constructor Create(const Key: String; Value: TObject); overload;
destructor Destroy; override;
function GetAutoDestroy: Boolean;
procedure SetAutoDestroy(Value: Boolean);
function GetKey: String;
function GetValue: TObject;
function Equals(const Item: ICollectable): Boolean;
property AutoDestroy: Boolean read GetAutoDestroy write SetAutoDestroy;
property Key: String read GetKey;
property Value: TObject read GetValue;
end;
implementation
{ TAbstractItem }
function TAbstractItem.GetInstance: TObject;
begin
Result := Self;
end;
{ TAbstractIntegerMappable }
procedure TAbstractIntegerMappable.AfterConstruction;
begin
inherited AfterConstruction;
FKey := MakeKey;
end;
function TAbstractIntegerMappable.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self = Item.GetInstance);
end;
function TAbstractIntegerMappable.GetKey: Integer;
begin
Result := FKey;
end;
{ TAbstractMappable }
destructor TAbstractMappable.Destroy;
begin
FKey := nil;
inherited Destroy;
end;
procedure TAbstractMappable.AfterConstruction;
begin
inherited AfterConstruction;
FKey := MakeKey;
end;
function TAbstractMappable.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self = Item.GetInstance);
end;
function TAbstractMappable.GetKey: ICollectable;
begin
Result := FKey;
end;
{ TAbstractStringMappable }
procedure TAbstractStringMappable.AfterConstruction;
begin
inherited AfterConstruction;
FKey := MakeKey;
end;
function TAbstractStringMappable.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self = Item.GetInstance);
end;
function TAbstractStringMappable.GetKey: String;
begin
Result := FKey;
end;
{ TAssociationWrapper }
constructor TAssociationWrapper.Create(const Key: ICollectable; Value: TObject);
begin
inherited Create;
FAutoDestroy := true;
FKey := Key;
FValue := Value;
end;
constructor TAssociationWrapper.Create(Key: Integer; Value: TObject);
begin
Create(TIntegerWrapper.Create(Key) as ICollectable, Value);
end;
constructor TAssociationWrapper.Create(Key: String; Value: TObject);
begin
Create(TStringWrapper.Create(Key) as ICollectable, Value);
end;
constructor TAssociationWrapper.Create(Key, Value: TObject; AutoDestroyKey: Boolean);
var
KeyWrapper: TObjectWrapper;
begin
KeyWrapper := TObjectWrapper.Create(Key);
KeyWrapper.AutoDestroy := AutoDestroyKey;
Create(KeyWrapper as ICollectable, Value);
end;
destructor TAssociationWrapper.Destroy;
begin
if FAutoDestroy then
FValue.Free;
FKey := nil;
inherited Destroy;
end;
function TAssociationWrapper.GetAutoDestroy: Boolean;
begin
Result := FAutoDestroy;
end;
procedure TAssociationWrapper.SetAutoDestroy(Value: Boolean);
begin
FAutoDestroy := Value;
end;
function TAssociationWrapper.GetKey: ICollectable;
begin
Result := FKey;
end;
function TAssociationWrapper.GetValue: TObject;
begin
Result := FValue;
end;
function TAssociationWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TAssociationWrapper).Value)
end;
{ TCardinalWrapper }
constructor TCardinalWrapper.Create(Value: Cardinal);
begin
inherited Create;
FValue := Value;
end;
function TCardinalWrapper.GetValue: Cardinal;
begin
Result := FValue;
end;
function TCardinalWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TCardinalWrapper).Value)
end;
function TCardinalWrapper.HashCode: Integer;
begin
Result := FValue;
end;
function TCardinalWrapper.CompareTo(const Item: ICollectable): Integer;
var
Value2: Cardinal;
begin
Value2 := (Item.GetInstance as TCardinalWrapper).Value;
if Value < Value2 then
Result := -1
else if Value > Value2 then
Result := 1
else
Result := 0;
end;
{ TBooleanWrapper }
constructor TBooleanWrapper.Create(Value: Boolean);
begin
inherited Create;
FValue := Value;
end;
function TBooleanWrapper.GetValue: Boolean;
begin
Result := FValue;
end;
function TBooleanWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TBooleanWrapper).Value)
end;
function TBooleanWrapper.HashCode: Integer;
begin
Result := Ord(FValue);
end;
function TBooleanWrapper.CompareTo(const Item: ICollectable): Integer;
var
Value2: Boolean;
begin
Value2 := (Item.GetInstance as TBooleanWrapper).Value;
if not Value and Value2 then
Result := -1
else if Value and not Value2 then
Result := 1
else
Result := 0;
end;
{ TCharWrapper }
constructor TCharWrapper.Create(Value: Char);
begin
inherited Create;
FValue := Value;
end;
function TCharWrapper.GetValue: Char;
begin
Result := FValue;
end;
function TCharWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TCharWrapper).Value)
end;
function TCharWrapper.HashCode: Integer;
begin
Result := Integer(FValue);
end;
function TCharWrapper.CompareTo(const Item: ICollectable): Integer;
var
Value2: Char;
begin
Value2 := (Item.GetInstance as TCharWrapper).Value;
if Value < Value2 then
Result := -1
else if Value > Value2 then
Result := 1
else
Result := 0;
end;
{ TClassWrapper }
constructor TClassWrapper.Create(Value: TClass);
begin
inherited Create;
FValue := Value;
end;
function TClassWrapper.GetValue: TClass;
begin
Result := FValue;
end;
function TClassWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TClassWrapper).Value)
end;
function TClassWrapper.HashCode: Integer;
begin
Result := Integer(FValue.ClassInfo);
end;
{ TDoubleWrapper }
constructor TDoubleWrapper.Create(Value: Double);
begin
inherited Create;
FValue := Value;
end;
function TDoubleWrapper.GetValue: Double;
begin
Result := FValue;
end;
function TDoubleWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TDoubleWrapper).Value)
end;
function TDoubleWrapper.HashCode: Integer;
var
DblAsInt: array[0..1] of Integer;
begin
Double(DblAsInt) := Value;
Result := DblAsInt[0] xor DblAsInt[1];
end;
function TDoubleWrapper.CompareTo(const Item: ICollectable): Integer;
var
Value2: Double;
begin
Value2 := (Item.GetInstance as TDoubleWrapper).Value;
if Value < Value2 then
Result := -1
else if Value > Value2 then
Result := 1
else
Result := 0;
end;
{ TIntegerWrapper }
constructor TIntegerWrapper.Create(Value: Integer);
begin
inherited Create;
FValue := Value;
end;
function TIntegerWrapper.GetValue: Integer;
begin
Result := FValue;
end;
function TIntegerWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TIntegerWrapper).Value)
end;
function TIntegerWrapper.HashCode: Integer;
begin
Result := FValue;
end;
function TIntegerWrapper.CompareTo(const Item: ICollectable): Integer;
var
Value2: Integer;
begin
Value2 := (Item.GetInstance as TIntegerWrapper).Value;
if Value < Value2 then
Result := -1
else if Value > Value2 then
Result := 1
else
Result := 0;
end;
{ TIntegerAssociationWrapper }
constructor TIntegerAssociationWrapper.Create(const Key: Integer; Value: TObject);
begin
inherited Create;
FAutoDestroy := true;
FKey := Key;
FValue := Value;
end;
destructor TIntegerAssociationWrapper.Destroy;
begin
if FAutoDestroy then
FValue.Free;
inherited Destroy;
end;
function TIntegerAssociationWrapper.GetAutoDestroy: Boolean;
begin
Result := FAutoDestroy;
end;
procedure TIntegerAssociationWrapper.SetAutoDestroy(Value: Boolean);
begin
FAutoDestroy := Value;
end;
function TIntegerAssociationWrapper.GetValue: TObject;
begin
Result := FValue;
end;
function TIntegerAssociationWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TIntegerAssociationWrapper).Value)
end;
function TIntegerAssociationWrapper.GetKey: Integer;
begin
Result := FKey;
end;
{ TStringAssociationWrapper }
constructor TStringAssociationWrapper.Create(const Key: String; Value: TObject);
begin
inherited Create;
FAutoDestroy := true;
FKey := Key;
FValue := Value;
end;
destructor TStringAssociationWrapper.Destroy;
begin
if FAutoDestroy then
FValue.Free;
inherited Destroy;
end;
function TStringAssociationWrapper.GetAutoDestroy: Boolean;
begin
Result := FAutoDestroy;
end;
procedure TStringAssociationWrapper.SetAutoDestroy(Value: Boolean);
begin
FAutoDestroy := Value;
end;
function TStringAssociationWrapper.GetValue: TObject;
begin
Result := FValue;
end;
function TStringAssociationWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TStringAssociationWrapper).Value)
end;
function TStringAssociationWrapper.GetKey: String;
begin
Result := FKey;
end;
{ TInterfaceWrapper }
constructor TInterfaceWrapper.Create(const Value: IUnknown);
begin
inherited Create;
FValue := Value;
end;
destructor TInterfaceWrapper.Destroy;
begin
FValue := nil;
inherited Destroy;
end;
function TInterfaceWrapper.GetValue: IUnknown;
begin
Result := FValue;
end;
function TInterfaceWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TInterfaceWrapper).Value)
end;
function TInterfaceWrapper.HashCode: Integer;
begin
Result := Integer(Pointer(FValue));
end;
{ TObjectWrapper }
constructor TObjectWrapper.Create(Value: TObject);
begin
inherited Create;
FAutoDestroy := true;
FValue := Value;
end;
destructor TObjectWrapper.Destroy;
begin
if FAutoDestroy then
FValue.Free;
inherited Destroy;
end;
function TObjectWrapper.GetAutoDestroy: Boolean;
begin
Result := FAutoDestroy;
end;
procedure TObjectWrapper.SetAutoDestroy(Value: Boolean);
begin
FAutoDestroy := Value;
end;
function TObjectWrapper.GetValue: TObject;
begin
Result := FValue;
end;
function TObjectWrapper.CompareTo(const Item: ICollectable): Integer;
var
Value1, Value2: Integer;
begin
Value1 := Integer(Pointer(Self));
if Item <> nil then
Value2 := Integer(Pointer(Item))
else
Value2 := Low(Integer);
if (Value1 < Value2) then
Result := -1
else if (Value1 > Value2) then
Result := 1
else
Result := 0;
end;
function TObjectWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TObjectWrapper).Value)
end;
function TObjectWrapper.HashCode: Integer;
begin
Result := Integer(Pointer(FValue));
end;
{ TStringWrapper }
constructor TStringWrapper.Create(Value: String);
begin
inherited Create;
FValue := Value;
end;
function TStringWrapper.GetValue: String;
begin
Result := FValue;
end;
function TStringWrapper.Equals(const Item: ICollectable): Boolean;
begin
Result := (Self.Value = (Item.GetInstance as TStringWrapper).Value)
end;
function TStringWrapper.HashCode: Integer;
var
I: Integer;
begin
Result := 0;
for I := 1 to Length(FValue) do
Result := (Result shl 1) xor Ord(FValue[I]);
end;
function TStringWrapper.CompareTo(const Item: ICollectable): Integer;
begin
Result := CompareStr(Self.Value, (Item.GetInstance as TStringWrapper).Value)
end;
end.