WHERE construct

The WHERE construct masks the evaluation of expressions and assignments of values in array assignment statements. It does this according to the value of a logical array expression.

Read syntax diagramSkip visual syntax diagramWHERE_construct_statementwhere_body_constructmasked_ELSEWHERE_blockELSEWHERE_blockEND_WHERE_statement
WHERE_construct_statement
See WHERE for syntax details.
where_body_construct

Read syntax diagramSkip visual syntax diagramwhere_assignment_statementWHERE_statementWHERE_construct
where_assignment_statement
Is an assignment_statement.
masked_ELSEWHERE_block

Read syntax diagramSkip visual syntax diagrammasked_ELSEWHERE_statementwhere_body_construct
masked_ELSEWHERE_statement
Is an ELSEWHERE statement that specifies a mask_expr. See ELSEWHERE for syntax details.
ELSEWHERE_block

Read syntax diagramSkip visual syntax diagramELSEWHERE_statementwhere_body_construct
ELSEWHERE_statement
Is an ELSEWHERE statement that does not specify a mask_expr. See ELSEWHERE for syntax details.
END_WHERE_statement
See END (Construct) for syntax details.
Rules:
  • mask_expr is a logical array expression.
  • In each where_assignment_statement, the mask_expr and the variable being defined must be arrays of the same shape.
  • A statement that is part of a where_body_construct must not be a branch target statement. Also, ELSEWHERE, masked ELSEWHERE, and END WHERE statements must not be branch target statements.
  • A where_assignment_statement that is a defined assignment must be an elemental defined assignment.
  • The mask_expr on the WHERE construct statement and all corresponding masked ELSEWHERE statements must have the same shape. The mask_expr on a nested WHERE statement or nested WHERE construct statement must have the same shape as the mask_expr on the WHERE construct statement of the construct in which it is nested.
  • If a construct name appears on a WHERE construct statement, it must also appear on the corresponding END WHERE statement. A construct name is optional on the masked ELSEWHERE and ELSEWHERE statements in the WHERE construct.

Examples

REAL, DIMENSION(10) :: A,B,C,D
WHERE (A>0.0)
  A = LOG(A)          ! Only the positive elements of A
                      !   are used in the LOG calculation.
  B = A               ! The mask uses the original array A
                      !   instead of the new array A.
  C = A / SUM(LOG(A)) ! A is evaluated by LOG, but
                      !   the resulting array is an
                      !   argument to a non-elemental
                      !   function. All elements in A will
                      !   be used in evaluating SUM.
END WHERE

WHERE (D>0.0)
  C = CSHIFT(A, 1)    ! CSHIFT applies to all elements in array A,
                      ! and the array element values of D determine
                      ! which CSHIFT expression determines the
                      ! corresponding element values of C.
ELSEWHERE
  C = CSHIFT(A, 2)
END WHERE
END
The following example shows an array constructor in a WHERE construct statement and in a masked ELSEWHERE mask_expr:
CALL SUB((/ 0, -4, 3, 6, 11, -2, 7, 14 /))

CONTAINS
  SUBROUTINE SUB(ARR)
  INTEGER ARR(:)
  INTEGER N

  N = SIZE(ARR)

  ! Data in array ARR at this point:
  !
  ! A = | 0 -4 3 6 11 -2 7 14 |

  WHERE (ARR < 0)
    ARR = 0
  ELSEWHERE (ARR < ARR((/(N-I, I=0, N-1)/)))
    ARR = 2
  END WHERE

  ! Data in array ARR at this point:
  !
  ! A = | 2 0 3 2 11 0 7 14 |

  END SUBROUTINE
END
The following example shows a nested WHERE construct statement and masked ELSEWHERE statement with a where_construct_name:
INTEGER :: A(10, 10), B(10, 10)
...
OUTERWHERE: WHERE (A < 10)
  INNERWHERE: WHERE (A < 0)
    B = 0
  ELSEWHERE (A < 5) INNERWHERE
    B = 5
  ELSEWHERE INNERWHERE
    B = 10
  END WHERE INNERWHERE
ELSEWHERE OUTERWHERE
  B = A
END WHERE OUTERWHERE
...