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.
>>-SELECT_TYPE_statement---------------------------------------><
>>-+--------------------------------+--------------------------><
| .----------------------------. |
| V | |
'---type_guard_statement_block-+-'
>>-END_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
-
>>-type_guard_statement----------------------------------------><
>>-statement_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:
- 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.
- 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.
- 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.
- Otherwise, if there is a CLASS DEFAULT type
guard statement, the block following that statement is executed.
Within the block following a TYPE IS type
guard statement, the associating entity is not polymorphic, has the
type named in the type guard statement, and has the type parameters
of the selector.
Within the block following a CLASS IS type
guard statement, the associating entity is polymorphic and has the
declared type named in the type guard statement. The type parameters
of the associating entity are those of the type specified in the CLASS
IS type guard statement.
Within the block following a CLASS DEFAULT type
guard 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.
Examples
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 :: P3
TYPE(COLOR_POINT), TARGET :: C
CLASS(POINT), POINTER :: P_OR_C
P_OR_C => C
SELECT TYPE ( A => P_OR_C )
CLASS IS ( POINT )
! "CLASS ( POINT ) :: A" implied here
PRINT *, A%X, A%Y ! This block gets executed
TYPE IS ( POINT_3D )
! "TYPE ( POINT_3D ) :: A" implied here
PRINT *, A%X, A%Y, A%Z
END SELECT