[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