S
Skybuck Flying
Yeah this is some very nice code:
Enumerator successfully buid into TDynamicIndex ! =D
alternative version 0.07:
// *** Begin of Test Program ***
program TestProgram;
{$APPTYPE CONSOLE}
{
TDynamicIndex
alternative version 0.06 created on 3 july 2011 by Skybuck Flying.
TDynamicIndex reduced to the most basic/simpelst form so that it can be used
for many other types/arrays and so forth.
Instead TMemory is created which accepts TDynamicIndex as parameters to do
lookups. TMemory also has been made more generic so it can contain
different kinds of types.
A more realistic example.
There might still be room to improve this technique if TDynamicIndex could
be used as the loop variable. This will be examined in a next (alternative)
version !
(It's all about reducing the ammount of code and keep it as simple and well
readable/understandable/self documenting as possible
with quick insight into what everthing does which is good for algorithm
design/development/inspection)
(re-created from my usenet posting from my archive, delphi overwrite
this example with the project file of another folder ?!
fortunately nothing was lost in the process except this text slightly
reformatted.)
}
{
alternative version 0.07 created on 3 july 2011 by Skybuck Flying.
Very nice :
TDynamicIndex improvements:
+ Build-in support for enumerators
+ Build-in enumerator for TDynamicIndex
+ Implicit conversion to integer (index is returned as integer)
+ Implicit conversion to string (index is returned as string)
+ Additional properties to get value (index) and dimension.
DynamicIndex can now be used in for in loops ! =D
TMemory improvements:
+ memory cleaned up via setting count property to zero
}
uses
SysUtils;
type
{
TDynamicIndexEnumerator = record
private
FArray: TBytes;
FIndex: Integer;
function GetCurrent : integer;
public
end;
}
TDynamicIndex = record
private
mIndex : integer;
mDimension : integer;
function GetCurrent : TDynamicIndex; inline;
function StoreIndex( ParaIndex : integer ) : TDynamicIndex; inline;
public
constructor Create( ParaDimension : integer );
property IndexOperator[ ParaIndex : integer ] : TDynamicIndex read
StoreIndex; default;
property Dimension : integer read mDimension write mDimension;
property Value : integer read mIndex write mIndex;
class operator Multiply( ParaA, ParaB : TDynamicIndex ) : TDynamicIndex;
// enumerator functions
function MoveNext : Boolean; inline;
property Current : TDynamicIndex read GetCurrent;
function GetEnumerator : TDynamicIndex;
// implicit operator so .Value doesn't need to be used when assinging the
dynamic index to an integer
class operator Implicit( ParaDynamicIndex : TDynamicIndex ) : integer;
// another implicit operator so it automatically gets converted to a
string !
class operator Implicit( ParaDynamicIndex : TDynamicIndex ) : string;
end;
constructor TDynamicIndex.Create( ParaDimension : integer );
begin
mIndex := 0;
mDimension := 1;
if ParaDimension > 1 then
begin
mDimension := ParaDimension;
end;
end;
function TDynamicIndex.StoreIndex( ParaIndex : integer ) : TDynamicIndex;
begin
mIndex := ParaIndex;
result.mIndex := mIndex;
result.mDimension := mDimension;
end;
class operator TDynamicIndex.Multiply( ParaA, ParaB : TDynamicIndex ) :
TDynamicIndex;
begin
result.mIndex := ParaA.mIndex + (ParaA.mDimension * ParaB.mIndex);
result.mDimension := ParaA.mDimension * ParaB.mDimension;
end;
function TDynamicIndex.MoveNext : Boolean;
begin
result := false;
mIndex := mIndex + 1;
if mIndex < mDimension then
begin
result := true;
end;
end;
function TDynamicIndex.GetCurrent : TDynamicIndex;
begin
result.mIndex := mIndex;
result.mDimension := mDimension;
end;
function TDynamicIndex.GetEnumerator : TDynamicIndex;
begin
result.mIndex := -1;
result.mDimension := mDimension;
end;
class operator TDynamicIndex.Implicit( ParaDynamicIndex : TDynamicIndex ) :
integer;
begin
result := ParaDynamicIndex.mIndex;
end;
class operator TDynamicIndex.Implicit( ParaDynamicIndex : TDynamicIndex ) :
string;
begin
result := IntToStr( ParaDynamicIndex.mIndex );
end;
type
TMemory<GenericType> = class
private
protected
mMemory : array of GenericType;
mCount : integer;
procedure SetCount( ParaCount : integer );
function GetElement( ParaIndex : TDynamicIndex ) : GenericType;
procedure SetElement( ParaIndex : TDynamicIndex; ParaValue :
GenericType );
public
constructor Create;
destructor Destroy; override;
property Count : integer read mCount write SetCount;
property Element[ ParaIndex : TDynamicIndex ] : GenericType read
GetElement write SetElement; default;
end;
constructor TMemory<GenericType>.Create;
begin
inherited Create;
end;
destructor TMemory<GenericType>.Destroy;
begin
Count := 0;
inherited Destroy;
end;
procedure TMemory<GenericType>.SetCount( ParaCount : integer );
begin
mCount := ParaCount;
SetLength( mMemory, mCount );
end;
function TMemory<GenericType>.GetElement( ParaIndex : TDynamicIndex ) :
GenericType;
begin
result := mMemory[ParaIndex.Value];
end;
procedure TMemory<GenericType>.SetElement( ParaIndex : TDynamicIndex;
ParaValue : GenericType );
begin
mMemory[ParaIndex.Value] := ParaValue;
end;
procedure Main;
var
mBlockCount : integer;
mElementCount : integer;
mMemory : TMemory<integer>;
mBlock : TDynamicIndex;
mElement : TDynamicIndex;
vBlockIndex : TDynamicIndex;
vElementIndex : TDynamicIndex;
begin
// smaller values set to make the program end soon to test clean up too
mBlockCount := 2;
mElementCount := 800;
mMemory := TMemory<integer>.Create;
mMemory.Count := mBlockCount * mElementCount;
// functions as a dimension holder
mBlock := TDynamicIndex.Create( mBlockCount );
mElement := TDynamicIndex.Create( mElementCount );
// functions as index iterators
vBlockIndex := mBlock;
vElementIndex := mElement;
for vBlockIndex in mBlock do
begin
for vElementIndex in mElement do
begin
mMemory[ vBlockIndex * vElementIndex ] := vElementIndex; // nice and
short !
end;
end;
for vBlockIndex in mBlock do
begin
for vElementIndex in mElement do
begin
writeln( 'BlockIndex: ' + vBlockIndex + ' ElementIndex: ' + vElementIndex
+ ' mMemory: ', mMemory[ vBlockIndex * vElementIndex ] );
// I would still ike to be able to write it like this, but I don't know
if it's possible to make writeln recgonized it
// and how to do it the above method is better for dialogs though
// writeln( 'BlockIndex: ', vBlockIndex, ' ElementIndex: ', vElementIndex,
'mMemory: ', mMemory[ vBlockIndex * vElementIndex ] );
end;
end;
mMemory.Free;
end;
begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.
/// *** End of Test Program ***
Bye,
Skybuck.
Enumerator successfully buid into TDynamicIndex ! =D
alternative version 0.07:
// *** Begin of Test Program ***
program TestProgram;
{$APPTYPE CONSOLE}
{
TDynamicIndex
alternative version 0.06 created on 3 july 2011 by Skybuck Flying.
TDynamicIndex reduced to the most basic/simpelst form so that it can be used
for many other types/arrays and so forth.
Instead TMemory is created which accepts TDynamicIndex as parameters to do
lookups. TMemory also has been made more generic so it can contain
different kinds of types.
A more realistic example.
There might still be room to improve this technique if TDynamicIndex could
be used as the loop variable. This will be examined in a next (alternative)
version !
(It's all about reducing the ammount of code and keep it as simple and well
readable/understandable/self documenting as possible
with quick insight into what everthing does which is good for algorithm
design/development/inspection)
(re-created from my usenet posting from my archive, delphi overwrite
this example with the project file of another folder ?!
fortunately nothing was lost in the process except this text slightly
reformatted.)
}
{
alternative version 0.07 created on 3 july 2011 by Skybuck Flying.
Very nice :
TDynamicIndex improvements:
+ Build-in support for enumerators
+ Build-in enumerator for TDynamicIndex
+ Implicit conversion to integer (index is returned as integer)
+ Implicit conversion to string (index is returned as string)
+ Additional properties to get value (index) and dimension.
DynamicIndex can now be used in for in loops ! =D
TMemory improvements:
+ memory cleaned up via setting count property to zero
}
uses
SysUtils;
type
{
TDynamicIndexEnumerator = record
private
FArray: TBytes;
FIndex: Integer;
function GetCurrent : integer;
public
end;
}
TDynamicIndex = record
private
mIndex : integer;
mDimension : integer;
function GetCurrent : TDynamicIndex; inline;
function StoreIndex( ParaIndex : integer ) : TDynamicIndex; inline;
public
constructor Create( ParaDimension : integer );
property IndexOperator[ ParaIndex : integer ] : TDynamicIndex read
StoreIndex; default;
property Dimension : integer read mDimension write mDimension;
property Value : integer read mIndex write mIndex;
class operator Multiply( ParaA, ParaB : TDynamicIndex ) : TDynamicIndex;
// enumerator functions
function MoveNext : Boolean; inline;
property Current : TDynamicIndex read GetCurrent;
function GetEnumerator : TDynamicIndex;
// implicit operator so .Value doesn't need to be used when assinging the
dynamic index to an integer
class operator Implicit( ParaDynamicIndex : TDynamicIndex ) : integer;
// another implicit operator so it automatically gets converted to a
string !
class operator Implicit( ParaDynamicIndex : TDynamicIndex ) : string;
end;
constructor TDynamicIndex.Create( ParaDimension : integer );
begin
mIndex := 0;
mDimension := 1;
if ParaDimension > 1 then
begin
mDimension := ParaDimension;
end;
end;
function TDynamicIndex.StoreIndex( ParaIndex : integer ) : TDynamicIndex;
begin
mIndex := ParaIndex;
result.mIndex := mIndex;
result.mDimension := mDimension;
end;
class operator TDynamicIndex.Multiply( ParaA, ParaB : TDynamicIndex ) :
TDynamicIndex;
begin
result.mIndex := ParaA.mIndex + (ParaA.mDimension * ParaB.mIndex);
result.mDimension := ParaA.mDimension * ParaB.mDimension;
end;
function TDynamicIndex.MoveNext : Boolean;
begin
result := false;
mIndex := mIndex + 1;
if mIndex < mDimension then
begin
result := true;
end;
end;
function TDynamicIndex.GetCurrent : TDynamicIndex;
begin
result.mIndex := mIndex;
result.mDimension := mDimension;
end;
function TDynamicIndex.GetEnumerator : TDynamicIndex;
begin
result.mIndex := -1;
result.mDimension := mDimension;
end;
class operator TDynamicIndex.Implicit( ParaDynamicIndex : TDynamicIndex ) :
integer;
begin
result := ParaDynamicIndex.mIndex;
end;
class operator TDynamicIndex.Implicit( ParaDynamicIndex : TDynamicIndex ) :
string;
begin
result := IntToStr( ParaDynamicIndex.mIndex );
end;
type
TMemory<GenericType> = class
private
protected
mMemory : array of GenericType;
mCount : integer;
procedure SetCount( ParaCount : integer );
function GetElement( ParaIndex : TDynamicIndex ) : GenericType;
procedure SetElement( ParaIndex : TDynamicIndex; ParaValue :
GenericType );
public
constructor Create;
destructor Destroy; override;
property Count : integer read mCount write SetCount;
property Element[ ParaIndex : TDynamicIndex ] : GenericType read
GetElement write SetElement; default;
end;
constructor TMemory<GenericType>.Create;
begin
inherited Create;
end;
destructor TMemory<GenericType>.Destroy;
begin
Count := 0;
inherited Destroy;
end;
procedure TMemory<GenericType>.SetCount( ParaCount : integer );
begin
mCount := ParaCount;
SetLength( mMemory, mCount );
end;
function TMemory<GenericType>.GetElement( ParaIndex : TDynamicIndex ) :
GenericType;
begin
result := mMemory[ParaIndex.Value];
end;
procedure TMemory<GenericType>.SetElement( ParaIndex : TDynamicIndex;
ParaValue : GenericType );
begin
mMemory[ParaIndex.Value] := ParaValue;
end;
procedure Main;
var
mBlockCount : integer;
mElementCount : integer;
mMemory : TMemory<integer>;
mBlock : TDynamicIndex;
mElement : TDynamicIndex;
vBlockIndex : TDynamicIndex;
vElementIndex : TDynamicIndex;
begin
// smaller values set to make the program end soon to test clean up too
mBlockCount := 2;
mElementCount := 800;
mMemory := TMemory<integer>.Create;
mMemory.Count := mBlockCount * mElementCount;
// functions as a dimension holder
mBlock := TDynamicIndex.Create( mBlockCount );
mElement := TDynamicIndex.Create( mElementCount );
// functions as index iterators
vBlockIndex := mBlock;
vElementIndex := mElement;
for vBlockIndex in mBlock do
begin
for vElementIndex in mElement do
begin
mMemory[ vBlockIndex * vElementIndex ] := vElementIndex; // nice and
short !
end;
end;
for vBlockIndex in mBlock do
begin
for vElementIndex in mElement do
begin
writeln( 'BlockIndex: ' + vBlockIndex + ' ElementIndex: ' + vElementIndex
+ ' mMemory: ', mMemory[ vBlockIndex * vElementIndex ] );
// I would still ike to be able to write it like this, but I don't know
if it's possible to make writeln recgonized it
// and how to do it the above method is better for dialogs though
// writeln( 'BlockIndex: ', vBlockIndex, ' ElementIndex: ', vElementIndex,
'mMemory: ', mMemory[ vBlockIndex * vElementIndex ] );
end;
end;
mMemory.Free;
end;
begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.
/// *** End of Test Program ***
Bye,
Skybuck.