[fpc-devel] New feature announcement: constant parameters for generics
Ryan Joseph
genericptr at gmail.com
Sun Apr 26 10:09:43 CEST 2020
> On Apr 26, 2020, at 2:38 PM, Michael Van Canneyt <michael at freepascal.org> wrote:
>
> As the original author, can you say something about the intended use of this feature ?
It was meant for a pretty narrow use of array types. If I knew how much work it would be to implement I probably would have not done it. :P I personally wanted it for static array lists that had methods like Add/Delete.
Here's an example of something I came across in a C++ project for decoding some data files old DOS games.
==================
{$mode objfpc}
program Block;
type
generic TBlock<T, const Alpha, Depth: Integer> = record
bits: array[0..(Alpha + Depth) - 1] of T;
end;
type
TBlock32 = specialize TBlock<UInt32, 4, 1>;
{ ... other block types ... }
begin
end.
Here's an example from the bug tracker by another user (Akira) that helped with testing. More arrays you'll note.
==================
program ConstMatrixExampleObjFPC;
{$mode ObjFPC}
{$modeswitch AdvancedRecords}
type
String3 = String[3];
generic TRawMatrix<T; const N: SizeUInt> = array[0..N-1] of array[0..N-1] of T;
generic TMatrix<T; const N: SizeUInt> = record
private type
ArrayType = specialize TRawMatrix<T, N>;
private
Data: ArrayType;
public
class operator :=(constref Arr: ArrayType): TMatrix; inline;
procedure Display;
end;
class operator TMatrix.:=(constref Arr: ArrayType): TMatrix;
begin
Result.Data := Arr;
end;
procedure TMatrix.Display;
var I, J: SizeInt;
begin
WriteLn('[');
for I := 0 to N - 1 do begin
Write(' [');
for J := 0 to N - 2 do
Write(Data[I, J], ', ');
Write(Data[I, N - 1]);
Writeln('] ');
end;
Write(']');
end;
const RawMat: specialize TRawMatrix<String3, 4> = (
('AAA', 'BBB', 'CCC', 'DDD'),
('EEE', 'FFF', 'GGG', 'HHH'),
('III', 'JJJ', 'KKK', 'LLL'),
('MMM', 'NNN', 'OOO', 'PPP')
);
var Mat: specialize TMatrix<String3, 4>;
begin
Mat := RawMat;
Mat.Display();
end.
And another example from him that gets pretty clever. ;)
==================
program Example;
// using Delphi-mode here as a matter of preference...
{$mode Delphi}
type
Meters<const Value: Double> = record
public const
ToKilometers = Value / 1000;
Unconverted = Value;
ToCentimeters = Value * 100;
ToMillimeters = Value * 1000;
ToFeet = Value * 3.28084;
end;
procedure Test;
type
TenMeters = Meters<10>;
const
KILOMETER_VALUE = TenMeters.ToKilometers;
UNCONVERTED_VALUE = TenMeters.Unconverted;
CENTIMETER_VALUE = TenMeters.ToCentimeters;
MILLIMETER_VALUE = TenMeters.ToMillimeters;
FOOT_VALUE = TenMeters.ToFeet;
begin
WriteLn(KILOMETER_VALUE : 0 : 4);
WriteLn(UNCONVERTED_VALUE);
WriteLn(CENTIMETER_VALUE);
WriteLn(MILLIMETER_VALUE);
WriteLn(FOOT_VALUE : 0 : 4);
end;
begin
Test();
end.
Regards,
Ryan Joseph
More information about the fpc-devel
mailing list