{
This file is part of the Free Pascal run time library.
Copyright (c) 1999-2014 by Maciej Izak aka hnb (NewPascal project)
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
unit SmartLinkedList;
{$MODE DELPHI}
interface
uses
SysUtils, Classes;
type
TSmartLinkedListItem<T: TObject> = record
public type
PSmartLinkedListItem = ^TSmartLinkedListItem < T >;
public
// similar as overloading [] operators for property x[v: string]: integer read gx write sx; default;
Instance: T; //default; // default keyword for non property.
RefCount: PLongint;
Next: PSmartLinkedListItem;
procedure SmartFinalize();
class operator Initialize(var aRec: TSmartLinkedListItem<T>);
class operator Finalize(var aRec: TSmartLinkedListItem<T>);
class operator AddRef(var aRec: TSmartLinkedListItem<T>);
class operator Copy(constref aSource: TSmartLinkedListItem<T>; var aDest: TSmartLinkedListItem<T>);
function Append( AItem: T ): PSmartLinkedListItem;
// implicit or explicit operator is used before "default" field
class operator Implicit(aObj: T): TSmartLinkedListItem<T>;
procedure Assign(const aValue: T);
end;
implementation
procedure TSmartLinkedListItem<T>.SmartFinalize();
begin
WriteLn( 'Finalizing record.. ' );
if ( Assigned( Next )) then begin
Dispose( Next );
Next:= nil;
end;
if RefCount <> nil then
if InterLockedDecrement(RefCount^)=0 then begin
FreeMem(RefCount);
Instance.Free;
end;
end;
class operator TSmartLinkedListItem<T>.Initialize(var aRec: TSmartLinkedListItem<T>);
begin
WriteLn( 'Initializing record.. ' );
aRec.RefCount := nil;
end;
class operator TSmartLinkedListItem<T>.Finalize(var aRec: TSmartLinkedListItem<T>);
begin
aRec.SmartFinalize();
end;
class operator TSmartLinkedListItem<T>.AddRef(var aRec: TSmartLinkedListItem<T>);
begin
if aRec.RefCount <> nil then
InterLockedIncrement(aRec.RefCount^);
end;
class operator TSmartLinkedListItem<T>.Copy(constref aSource: TSmartLinkedListItem<T>; var aDest: TSmartLinkedListItem<T>);
begin
if aDest.RefCount <> nil then
aDest.SmartFinalize();
if aSource.RefCount <> nil then
InterLockedIncrement(aSource.RefCount^);
aDest.RefCount := aSource.RefCount;
aDest.Instance := aSource.Instance;
end;
class operator TSmartLinkedListItem<T>.Implicit(aObj: T): TSmartLinkedListItem<T>;
begin
Result.Assign(aObj);
end;
procedure TSmartLinkedListItem<T>.Assign(const aValue: T);
begin
if RefCount <> nil then
SmartFinalize();
GetMem(RefCount, SizeOf(LongInt));
RefCount^ := 0;
InterLockedIncrement(RefCount^);
Instance := aValue;
end;
function TSmartLinkedListItem<T>.Append( AItem: T ): PSmartLinkedListItem;
begin
New( Next );
Next^.Assign( AItem );
Result:= Next;
end;
end.