SELECT TYPE construct (Fortran 2003)

The SELECT TYPE construct selects, at most, one of its constituent blocks for execution. The selection is based on the dynamic type of an expression. A name is associated with the expression, in the same way as for the ASSOCIATE construct.

Read syntax diagramSkip visual syntax diagramSELECT_TYPE_statement

Read syntax diagramSkip visual syntax diagramtype_guard_statement_block

Read syntax diagramSkip visual syntax diagramEND_SELECT_statement
SELECT_TYPE_statement
defines the selector expression that is to be evaluated and optionally associates a name (an associate name) with the selector expression. If you do not specify an associate name in the SELECT_TYPE_statement, the selector expression must be a named variable. The name of this variable becomes the associate name. Execution of a SELECT TYPE construct whose selector is not a variable causes the selector expression to be evaluated. See SELECT TYPE (Fortran 2003) for syntax details.
type_guard_statement_block

Read syntax diagramSkip visual syntax diagramtype_guard_statement

Read syntax diagramSkip visual syntax diagramstatement_block
type_guard_statement
The dynamic type of the selector expression is compared to the type specified in the type_guard_statement. If the rules for type comparison succeed for a particular type_guard_statement the subsequent statement block is executed. A type guard statement cannot be a branch target statement. It is permissible to branch to an end-select-type-stmt only from within its SELECT TYPE construct. See Type Guard (Fortran 2003) for syntax details. The other attributes of the associating entity are described in Associate names.
END_SELECT_statement
terminates the SELECT TYPE construct. See END (Construct) for syntax details.
The block to be executed is selected as follows:
  1. If a TYPE IS type guard statement matches the selector, the block following that statement is executed. A TYPE IS type guard statement matches the selector if the dynamic type and kind type parameter values of the selector are the same as those specified by the statement.
  2. Otherwise, if exactly one CLASS IS type guard statement matches the selector, the block following that statement is executed. A CLASS IS type guard 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 parameter values specified by the statement are the same as the corresponding type parameter values of the dynamic type of the selector.
  3. Otherwise, if several CLASS IS type guard statements match the selector, one of these statements must specify a type that is an extension of all the types specified in the others; the block following that statement is executed.
  4. Otherwise, if there is a CLASS DEFAULT type guard statement, the block following that statement is executed.
If the associating entity follows a TYPE IS, CLASS IS, or CLASS DEFAULT type guard statement, its polymorphism, type, and type parameter are determined as follows:
Table 1. Characteristics of the associating entity in different locations within the construct
Location Polymorphism Type Type parameter
Within the block following a TYPE IS type guard statement Not polymorphic The type named in the type guard statement The type parameter values of the selector
Within the block following a CLASS IS type guard statement Polymorphic The declared type named in the type guard statement The type parameter values of the selector
Within the block following a CLASS DEFAULT type guard statement Polymorphic The same declared type as the selector The type parameter values of the declared type of the selector

Examples

PROGRAM p
  TYPE base
    INTEGER::i
  END TYPE

  TYPE,EXTENDS(base)::child
    INTEGER::j
  END TYPE

  CLASS(base), POINTER :: bptr
  TYPE(base), TARGET :: base_target = base(10)
  TYPE(child), TARGET :: child_target = child(20, 30)

  bptr => base_target

  SELECT type(bptr)
    TYPE IS (base)
    PRINT *, "base type: component value: ", bptr%i
    TYPE IS (child)
    PRINT *, "child type: component values: ", bptr%i, bptr%j
  END SELECT

  bptr => child_target

  SELECT type(bptr)
    TYPE IS (base)
    PRINT *, "base type: component value: ", bptr%i
    TYPE IS (child)
    PRINT *, "child type: component values: ", bptr%i, bptr%j
  END SELECT

END PROGRAM p
The output is as follows:
base type: component value: 10
child type: component values: 20 30