# SELECT TYPE

Statement: Marks the beginning of a SELECT TYPE construct. The construct selects for execution at most one of its constituent blocks. The selection is based on the dynamic type of a specified expression.

[name:] SELECT TYPE ([ assoc-name => ] selector)

[type-guard-stmt

block]...

END SELECT [name]

name | (Optional) Is the name of the SELECT TYPE construct.
assoc-name | (Optional) Is an identifier that becomes associated with the selector. It becomes the associating entity. The identifier name must be unique within the construct. If selector is not a named variable, assoc-name => must appear.
selector | Is an expression or variable. It must be polymorphic. It is evaluated when the SELECT TYPE statement is executed.
type-guard-stmt | (Optional) Is one of the following: TYPE IS (type) [name] CLASS IS (type) [name] CLASS DEFAULT [name] CLASS DEFAULT can be specified only once in the construct. The same type and kind parameter values can only be specified in one TYPE IS statement and one CLASS IS statement.
type | Is an intrinsic type specifier or a derived-type specifier. It must specify that each length type parameter is assumed. It cannot be a sequence derived type or a type with the BIND attribute.
block | (Optional) Is a sequence of zero or more statements or constructs.

## Description

If a construct name is specified at the beginning of a SELECT TYPE statement, the same name must appear in the corresponding END SELECT statement. The same construct name must not be used for different named constructs in the same scoping unit. If no name is specified at the beginning of a SELECT TYPE statement, you cannot specify one following the END SELECT statement or any type-guard-stmt. If a type-guard-stmt specifies a construct name, it must match the construct name on the corresponding SELECT TYPE statement.

A branch to the END SELECT statement is allowed from within the SELECT TYPE construct, but it is not allowed from anywhere outside the construct.

Execution of a SELECT TYPE construct whose selector is not a variable causes the selector expression to be evaluated.

A SELECT TYPE construct selects at most one block to be executed. During execution of that block, the associate name identifies an entity that is associated with the selector. The entity associated with the associate name has the declared type and type parameters of the selector. The entity is polymorphic only if the selector is polymorphic.

The following steps determine which block is selected for execution:

1. If a TYPE IS statement matches the selector, the block following that statement is executed. A TYPE IS statement matches the selector if the dynamic type and type parameter values of the selector are the same as those specified by the statement.

2. Otherwise, if exactly one CLASS IS statement matches the selector, the block following that statement is executed. A CLASS IS statement matches the selector if the dynamic type of the selector is an extension of the type specified by the statement and the kind type parameters specified by the statement are the same as the corresponding type parameters of the dynamic type of the selector.

3. Otherwise, if several CLASS IS statements match the selector, one of these statements must specify a type that is an extension of all the types specified in the others. In this case, the block following that statement is executed.

4. Otherwise, if there is a CLASS DEFAULT statement, the block following that statement is executed.

Within the block following a TYPE IS statement, the associating entity is not polymorphic, it has the type named in the TYPE IS statement, and has the type parameters of the selector.

Within the block following a CLASS IS statement, the associating entity is polymorphic and has the declared type named in the CLASS IS statement. The type parameters of the associating entity are the corresponding type parameters of the selector.

Within the block following a CLASS DEFAULT statement, the associating entity is polymorphic and has the same declared type as the selector. The type parameters of the associating entity are those of the declared type of the selector.

If the declared type of the selector is M, specifying CLASS DEFAULT has the same effect as specifying CLASS IS (M).

A type-guard-stmt cannot be a branch target statement. You can branch to an END SELECT statement only from within its SELECT TYPE construct.

## Example

The following example shows a SELECT TYPE construct:

    TYPE POINT
       REAL :: X, Y
    END TYPE POINT
    TYPE, EXTENDS(POINT) :: POINT_3D
       REAL :: Z
    END TYPE POINT_3D
    TYPE, EXTENDS(POINT) :: COLOR_POINT
       INTEGER :: COLOR
    END TYPE COLOR_POINT

    TYPE(POINT), TARGET :: P
    TYPE(POINT_3D), TARGET :: P3D
    TYPE(COLOR_POINT), TARGET :: CP
    CLASS(POINT), POINTER :: P_OR_CP
    P_OR_CP=> CP
    SELECT TYPE ( AN => P_OR_CP )
    CLASS IS ( POINT )
                      ! "CLASS ( POINT ) :: AN" is implied here
       PRINT *, AN%X, AN%Y     ! This block gets executed
    TYPE IS ( POINT_3D )
                      ! "TYPE ( POINT_3D ) :: AN" is implied here
       PRINT *, AN%X, AN%Y, AN%Z
    END SELECT

The following example uses declarations from the above example, but it omits the associate name AN:

    P_OR_CP => P3D
    SELECT TYPE ( P_OR_CP )
    CLASS IS ( POINT )
                      ! "CLASS ( POINT ) :: P_OR_CP" is implied here
       PRINT *, P_OR_CP%X, P_OR_CP%Y
    TYPE IS ( POINT_3D )
                      ! "TYPE ( POINT_3D ) :: P_OR_CP" is implied here
       PRINT *, P_OR_CP%X, P_OR_CP%Y, P_OR_CP%Z    ! This block gets executed
    END SELECT

Parent topic: S

## See Also

Construct Association
Additional Attributes Of Associate Names