Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Polymorphic type-bound procedure

cporter
Beginner
535 Views
I'm having a difficult time with creating a type-bound procedure that is polymorphic (the GetValues procedure in the code below). The compile errors I get are:
error #8182: The name is neither an abstract interface nor a procedure with an explicit interface. [GETVALUES]
and
error #8169: The specified interface is not declared. [GETVALUES]
Any suggestions?
Thanks,
Cheryl
Intel VF 11.1.067
!======================================================================
Module SimpleGeneric_Module
Implicit None
Type :: RealDataType
Character (len=10) :: ID
Real X
End Type RealDataType
Type :: IntegerDataType
Character (len=10) :: ID
Integer N
End Type IntegerDataType
TYPE DataExchangeType
Integer NReal
Integer NInt
Type (RealDataType), Allocatable :: RealData(:)
Type (IntegerDataType), Allocatable :: IntegerData(:)
CONTAINS
Procedure, Public, NOPASS :: GetValues
End Type DataExchangeType
Class (DataExchangeType), Public, Allocatable :: SharedData
INTERFACE GetValues
Module Procedure GetReal, GetInteger
END INTERFACE GetValues
PUBLIC :: GetValues
!-----------------------------------------------------------------------
CONTAINS
!-----------------------------------------------------------------------
Subroutine GetReal(Label, X)
Character(len=*), Intent(in) :: Label
Real, intent(out) :: X
Integer i
DO i = 1, SharedData % NReal
if (Label == trim(SharedData % RealData(i) % ID)) then
X = SharedData % RealData(i) % X
return
endif
enddo
X = -99.
Return
End Subroutine GetReal
!-----------------------------------------------------------------------
Subroutine GetInteger(Label, N)
Character(len=*) :: Label
Integer, intent(out) :: N
Integer i
DO i = 1, SharedData % NInt
if (Label == trim(SharedData % IntegerData(i) % ID)) then
N = SharedData % IntegerData(i) % N
return
endif
enddo
N = -99
Return
End Subroutine GetInteger
!-----------------------------------------------------------------------
End Module SimpleGeneric_Module
!======================================================================
0 Kudos
3 Replies
mecej4
Honored Contributor III
535 Views
Taking liberties with your intentions, I adapted your source code to build a working program. Starting with this as a basis, you may add/delete features as they suit you.

Caution: this program compiles and runs with GFortran 4.5, but support for OO programming in IFort is not yet sufficient for this program.
[fortran]!======================================================================
    Module SimpleGeneric_Module
      Implicit None
      Type :: RealDataType
        Character (len=10) :: ID
        Real X
      End Type RealDataType
      Type :: IntegerDataType
        Character (len=10) :: ID
        Integer N
      End Type IntegerDataType
      TYPE DataExchangeType
        Integer NReal
        Integer NInt
        Type (RealDataType), Allocatable :: RealData(:)
        Type (IntegerDataType), Allocatable :: IntegerData(:)
        CONTAINS
          procedure, public, nopass :: GetVI => GetInteger
          procedure, public, nopass :: GetVR => GetReal
          generic :: GetVal => GetvI, GetVR
      End Type DataExchangeType
      Class (DataExchangeType), Public, Allocatable :: SharedData
!-----------------------------------------------------------------------
      CONTAINS
!-----------------------------------------------------------------------
      Subroutine GetReal(Label, X)
        Character(len=*), Intent(in) :: Label
        Real, intent(out) :: X
        Integer i
        DO i = 1, SharedData % NReal
          if (Label == trim(SharedData % RealData(i) % ID)) then
            X = SharedData % RealData(i) % X
            return
          endif
        enddo
        X = -99.
        Return
      End Subroutine GetReal
!-----------------------------------------------------------------------
      Subroutine GetInteger(Label, N)
        Character(len=*), Intent(in) :: Label
        Integer, intent(out) :: N
        Integer i
        DO i = 1, SharedData % NInt
          if (Label == trim(SharedData % IntegerData(i) % ID)) then
            N = SharedData % IntegerData(i) % N
            return
          endif
        enddo
        N = -99
        Return
      End Subroutine GetInteger
!-----------------------------------------------------------------------
    End Module SimpleGeneric_Module
!======================================================================

program useMyMod
  use SimpleGeneric_Module
  integer :: i,j
  real :: X,Y

  allocate(SharedData)
  SharedData%Nreal = 2
  SharedData%Nint = 3
  allocate(SharedData%RealData(2))
  allocate(SharedData%IntegerData(3))

  do i=1,2
     SharedData%RealData(i)%X=2*i+3
     write(SharedData%RealData(i)%ID,'(A4,1x,I1)')'Real',i
  end do
  do i=1,3
     SharedData%IntegerData(i)%N=4*i-2
     write(SharedData%IntegerData(i)%ID,'(A4,1x,I1)')'Intg',i
  end do

! call specific procedures directly

  call getreal('Real 2',X)
  call getinteger('Intg 3',i)
  write(*,*)' Real 2 = ',X,'  Intg 3 = ',i

! call generic procedure with different argument types

  call SharedData%getVal('Real 2',Y)
  call SharedData%getVal('Intg 3',j)
  write(*,*)' Real 2 = ',Y,'  Intg 3 = ',j

end program useMyMod
[/fortran]
0 Kudos
cporter
Beginner
535 Views
Many thanks for your suggested code, mecej4! As you state in your message, it does not yet work with Intel VF.
Steve - is this capability possible in IVF?
Thanks,
Cheryl
0 Kudos
Steven_L_Intel1
Employee
535 Views
Version 11.1 does not support GENERIC but the next major release, due out next month does. I just tried it:

[plain]c:Projects>ifort -nologo t.f90

c:Projects>t.exe
  Real 2 =    7.000000       Intg 3 =           10
  Real 2 =    7.000000       Intg 3 =           10[/plain]
0 Kudos
Reply