Enum Class in Fortran – Code Review Stack Exchange

I tried to implement something like a C++ enum class in Fortran. That means it should be typesafe and scope bound. (No comparison between integers and enum values for example.)

The following works, but it is still possible to compare two instances of different enum classes at compile time. Do you have suggestions for possible improvements?

module enum_class_mod
    implicit none(type, external)
    private
    public :: EnumBase_t

    type, abstract :: EnumBase_t
        integer :: val
    contains
        private
        procedure :: eq_EnumBase_t
        procedure :: neq_EnumBase_t
        generic, public :: operator(==) => eq_EnumBase_t
        generic, public :: operator(/=) => neq_EnumBase_t
    end type


contains

    logical elemental function eq_EnumBase_t(this, other)
        class(EnumBase_t), intent(in) :: this, other
        if (.not. SAME_TYPE_AS(this, other)) error stop 'Can only compare objects of same type'
        eq_EnumBase_t = this%val == other%val
    end function

    logical elemental function neq_EnumBase_t(this, other)
        class(EnumBase_t), intent(in) :: this, other
        if (.not. SAME_TYPE_AS(this, other)) error stop 'Can only compare objects of same type'
        neq_EnumBase_t = this%val /= other%val
    end function
end module

program test_enum_class
    use enum_class_mod, only: EnumBase_t
    implicit none(type, external)

    type, extends(EnumBase_t) :: Color_t
    end type

    type :: PossibleColors_t
        type(Color_t) :: Red = Color_t(1), Blue = Color_t(2)
    end type

    type(PossibleColors_t), parameter :: possible_colors = PossibleColors_t()

    type, extends(EnumBase_t) :: Day_t
    end type

    type :: PossibleDays_t
        type(Day_t) :: Monday = Day_t(1), Tuesday = Day_t(2)
    end type

    type(PossibleDays_t), parameter :: possible_days = PossibleDays_t()


    write(*, *) possible_colors%Red == possible_colors%Blue
    write(*, *) possible_colors%Red == possible_colors%Red

    write(*, *) possible_days%Monday == possible_days%Tuesday

    ! fails at runtime, I would like it to fail at compile time
    write(*, *) possible_days%Monday == possible_colors%Red
end program

```