A Tour of Morfa

Template parameter specification

As template constraints, template parameter specification is a mechanism for restricting a range of parameters to which a particular template applies.

Parameter specification also allows you to perform pattern matching on type template parameters which, combined with const and alias templates, allows you to program on the level of types.

The is keyword

Recall that in the section on template constraints we used the const template IsNumberType to define a template constraint for the declaration of the function sum. The template IsNumberType can be defined using the parameter specification as follows:

public template <T is int64>   const IsNumberType = true;
public template <T is int32>   const IsNumberType = true;
public template <T is int16>   const IsNumberType = true;
public template <T is int8>    const IsNumberType = true;
public template <T is float64> const IsNumberType = true;
public template <T is float32> const IsNumberType = true;
// The default case:
public template <T>            const IsNumberType = false;

The clause is int64 is the specification of the template parameter T and is used to constrain possible arguments for the template. Thus T is int64 means that the template will accept only one type, namely int64, as the argument.

Later on you will see that a specification may match more than one type.

Note that the expression such as IsNumberType<int8> matches two variants of IsNumberType: the one with is int8 and the one without parameter specification. In such cases the compiler chooses a variant with a type specification.

A specification of a template parameter may refer to the value of another parameter. For example, an operation that tests for the identity of two specified types can be easily defined using a const template:

public operator istype { kind = infix, precedence = compare }

public template <T, U is T> const istype = true;
public template <T, U>      const istype = false;

static assert (text istype typeof("morfa"));
static assert (not (typeof(3.14) istype int));