[fpc-devel] New feature announcement: constant parameters for generics
Sven Barth
pascaldragon at googlemail.com
Sun Apr 26 00:13:21 CEST 2020
The Free Pascal team is happy to announce the addition of a new language
feature: constant parameters for generics.
This allows to declare generic types or routines that aside from type
parameters can also take constant parameters that can be used inside the
generic as if one would use untyped constants. Together with inlining
and optimizations this allows to generate optimal code that is yet flexible.
This feature was developed by Ryan Joseph. Thank you very much Ryan for
your contribution and your patience until this feature was included.
A generic constant parameter is declared like this:
CONSTPARAM::=const <IDLIST>: <TYPE>
IDLIST::=<ID>[, <ID>]
TYPE::=<ID>
The following types are supported for constant parameters:
- integer types (including range types)
- floating point types
- string types
- set types
- enum types
- Boolean types
- Pointer types
While the type declaration might look like a typed constant it is in
fact an untyped constant. The type is used to allow the author of a
generic to restrict the range of the type. This has some implications:
- the constant parameter can be used inside the generic whereever an
untyped constant can be used (e.g. variable initializers, constant
initializers, default parameters, array indices, compile time intrinsics
and operations)
- types that can't be used for untyped constants can't be used for
generic constant parameters either
Example:
=== code begin ===
{$mode objfpc}
type
generic TStaticArray<T; const N: Integer> = array[0..N-1] of T;
generic function TimesX<const N: Integer>(aArg: Integer): Integer;
begin
Result := aArg * N;
end;
var
myArray: specialize TStaticArray<LongInt, 2>;
i: LongInt;
begin
i := specialize TimesX<2>(21);
end.
=== code end ===
Important: Unlike C++ FPC does not support default specializations, thus
doing recursive specializations together with operations on constants
will result in out of stack exceptions or infinite loops:
=== code begin ===
{$mode objfpc}
type
generic TTest<const N: Integer> = class
const
N1 = N - 1;
type
TSubTest = specialize TTest<N1>;
// the following does not work currently for a different reason:
// TSubTest = specialize TTest<N - 1>;
end;
begin
end.
=== code end ===
Delphi compatibility: this feature is NOT Delphi compatible. However to
not inconvience users that prefer mode Delphi this feature is also
available in that mode as our stance usually is that Delphi code should
compile with FPC while the inverse is not necessarily true.
Also this feature will NOT be part of 3.2.
Please give the generic constant parameters a try and report bugs in the
bugtracker.
Regards,
Sven
More information about the fpc-devel
mailing list