{
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 SmartObj;
{$MODE DELPHI}
interface
uses
SysUtils, Classes;
type
{ TSmartObj }
TSmartObj = class
private type TContainer = record
Instance: TSmartObj;
RefCount: PLongint;
procedure SmartFinalize();
class operator Initialize(var aRec: TContainer);
class operator Finalize(var aRec: TContainer);
class operator AddRef(var aRec: TContainer);
class operator Copy(constref aSource: TContainer; var aDest: TContainer);
class operator Implicit(aObj: TSmartObj): TContainer;
procedure Assign(const aValue: TSmartObj);
end;
private
Container: TContainer;
public
constructor Create;
destructor Destroy; override;
end;
implementation
{ TSmartObj }
constructor TSmartObj.Create;
begin
inherited Create;
Container.Instance:= Self;
end;
destructor TSmartObj.Destroy;
begin
Container.Instance:= nil;
inherited Destroy;
end;
procedure TSmartObj.TContainer.SmartFinalize();
begin
WriteLn( 'SmartFinalize' );
if RefCount <> nil then
if InterLockedDecrement(RefCount^)=0 then
begin
FreeMem(RefCount);
Instance.Free;
end;
end;
class operator TSmartObj.TContainer.Initialize(var aRec: TContainer);
begin
aRec.RefCount := nil;
WriteLn( 'Initialize' );
end;
class operator TSmartObj.TContainer.Finalize(var aRec: TContainer);
begin
aRec.SmartFinalize();
end;
class operator TSmartObj.TContainer.AddRef(var aRec: TContainer);
begin
WriteLn( 'AddRef' );
if aRec.RefCount <> nil then
InterLockedIncrement(aRec.RefCount^);
end;
class operator TSmartObj.TContainer.Copy(constref aSource: TContainer;
var aDest: TContainer);
begin
WriteLn( 'Copy' );
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 TSmartObj.TContainer.Implicit(aObj: TSmartObj): TContainer;
begin
Result.Assign(aObj);
end;
procedure TSmartObj.TContainer.Assign(const aValue: TSmartObj);
begin
WriteLn( 'Assign' );
if RefCount <> nil then
SmartFinalize();
GetMem(RefCount, SizeOf(LongInt));
RefCount^ := 0;
InterLockedIncrement(RefCount^);
Instance := aValue;
end;
end.