Switch in Co-array Fortran

Switch statements express conditionals across many branches.

Here’s a basic switch.

program main
    implicit none
    integer :: i

    i = 2
    print *, "Write ", i, " as "
    select case (i)
        case (1)
            print *, "one"
        case (2)
            print *, "two"
        case (3)
            print *, "three"
    end select
end program main

You can use commas to separate multiple expressions in the same case statement. We use the optional default case in this example as well.

program weekdays
    use, intrinsic :: iso_fortran_env, only: wp => real64
    implicit none
    integer :: current_day, saturday, sunday

    ! ISO C binding for system time
    interface
        function current_wday() bind(c, name='current_wday') result(day)
            integer(c_int) :: day
        end function current_wday
    end interface

    current_day = current_wday()
    saturday = 6
    sunday = 7

    select case (current_day)
        case (saturday, sunday)
            print *, "It's the weekend"
        case default
            print *, "It's a weekday"
    end select
end program weekdays

switch without an expression is an alternate way to express if/else logic. Here we also show how the case expressions can be non-constants.

program if_else
    use, intrinsic :: iso_fortran_env, only: wp => real64
    implicit none
    real(wp) :: t_hour

    ! Mock function to represent current hour
    t_hour = 15.0  ! Assuming it's 3 PM

    select case
        case (t_hour < 12)
            print *, "It's before noon"
        case default
            print *, "It's after noon"
    end select
end program if_else

A type switch compares types instead of values. You can use this to discover the type of a value. In this example, the variable t will have the type corresponding to its clause.

Fortran does not directly support type comparisons in the same way, but a rough equivalent could be implemented using select type constructs.

program type_switch
    implicit none

    call whatAmI(.true.)
    call whatAmI(1)
    call whatAmI('hey')

contains

    subroutine whatAmI(i)
        class(*), intent(in) :: i
        select type(i)
            type is (logical)
                print *, "I'm a bool"
            type is (integer)
                print *, "I'm an int"
            type is (character(*))
                print *, "Don't know type ", i
            class default
                print *, "Unknown type"
        end select
    end subroutine whatAmI

end program type_switch
Output:
Write 2 as 
 two
It's a weekday
It's after noon
I'm a bool
I'm an int
Don't know type hey