I'm trying to write a program that requires the type of a variable to be specified at run time by user input. Here is a minimal example where I attempt to do this with derived types, though I use the boolean is_complex as a proxy for user input.
program add_complex_or_real
use iso_fortran_env, only: stdout => output_unit
implicit none
type, abstract :: number_t
! TODO: I would like to define a function e.g. print,
! which prints in a specific format depending on the
! extended type
endtype number_t
type, extends(number_t) :: real_number_t
real :: val = 0
endtype real_number_t
type, extends(number_t) :: complex_number_t
complex :: val = cmplx(0,0)
endtype complex_number_t
class(number_t), allocatable :: x, y
logical :: is_complex = .false.
if (is_complex) then
allocate(complex_number_t :: x, y)
else
allocate(real_number_t :: x, y)
endif
! want to be able to call here something like
! class(number_t) z = x + y
! call z%print()
contains
end program add_complex_or_real
This doesn't work since I can't define val in the number_t abstract type. I also tried defining two different types using the fypp preprocessor (which I am happy to use) but that didn't work out either. I know I could easily do this with the C preprocessor (#ifdef IS_COMPLEX) but then I end up with two binaries (one for real, one for complex) and I would rather not do that. I am also trying to avoid unnecessary code repetition such that I can simply use it in an equation without needing a select type(x) and having the same equation twice.
Stackoverflow suggested this question while I was writing, which is very close. With this I can put class(*), allocatable :: val in number_t but then must remove val from the children types, and it still does not solve the problem with repeated code (in the link, the Square function is just the same thing repeated a few times -- is there a way to just do val**2 without wrapping it in an if statement that checks for the complex flag?).