fortranfortran2003custom-typefortran2008

Access Fortran custom type attributes by default


is it possible with modern Fortran (90, 2003 or even 2008) to have a custom type where one of the attributes would be accessed by default:

program test
    use iso_fortran_env
    type MYTYPE_t
        real(real64) :: data
    end type MYTYPE_t

    type(MYTYPE_T) :: test
    real(real64) :: foo

    ! This works
    test%data = 5.0
    ! Is there a way to be able things like this:
    test = 5.0
    print*, sqrt(test)

    foo = test + 3
end program

Solution

  • You must overload all the possible assignments, operators and intrinsics. Yes, it is a lot of work. No, there is no magic faster way that would cause automatic conversion in all contexts.

    module types
        use iso_fortran_env
    
        implicit none
    
        type MYTYPE_t
            real(real64) :: data
        contains
            procedure assign
            procedure add
            generic :: assignment(=) => assign
            generic :: operator(+) => add
        end type MYTYPE_t
    
        interface sqrt
          procedure sqrt_MTYPE
        end interface
    
    contains
    
        subroutine assign(l,r)
          class(MYTYPE_t), intent(out) :: l
          real(real32), intent(in) :: r
          l%data = r
        end subroutine
    
        real(real64) function sqrt_MTYPE(x)
          type(MYTYPE_t), intent(in) :: x
          sqrt_MTYPE = sqrt(x%data)
        end function
    
        real(real64) function add(x, y)
          class(MYTYPE_t), intent(in) :: x
          integer, intent(in) :: y
    
          add = x%data + y
        end function
    end module types
    
    program test_program
        use types
    
        implicit none
    
        type(MYTYPE_T) :: test
        real(real64) :: foo
    
        ! This works
        test%data = 5.0
        ! Is there a way to be able things like this:
        test = 5.0
        print*, sqrt(test)
    
        foo = test + 3
    end program
    

    test:

    > gfortran override3.f90 
    > ./a.out 
       2.2360679774997898