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
```