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

Polymorphic Variable Detecting Arrays

Vasili_M_
Beginner
1,610 Views

Is it possible for an unlimited polymorphic variable to detecd an array.

 

subroutine test (tn)
  class (*), Intent (Out) :: tn

  Select type (tn)

  Type Is (Integer, dimension(:))
    tn = 3

  End Select

end subroutine

 

0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,610 Views

Fortran 2015 (and TS29113 "Further Interoperability with C") extends the language to include "assumed rank". You can query the rank of an assumed-rank dummy argument, but you're somewhat limited in what you can do with it. However, your code could be implemented this way (in a compiler with this support, which ifort doesn't yet have):

subroutine test (tn)
  use, intrinsic :: iso_c_binding
  class (*), dimension(..), Intent (Out) :: tn

  integer, pointer, dimension(:) :: tn_i_1
  integer, pointer, dimension(:,:) :: tn_i_2

  Select type (tn)

  Type Is (Integer)
   select case (rank(tn))
   case(1)
   call c_f_pointer (c_loc(tn),tn_i_1,shape(tn))
    tn_i_1 = 3
   case(2)
    call c_f_pointer(c_loc(tn),tn_i_2,shape(tn))
    tn_i_2 = 4
    end select

  End Select

end subroutine

Still not as nice as you'd like, but at least doable.

View solution in original post

0 Kudos
2 Replies
IanH
Honored Contributor III
1,610 Views

Not in that manner. 

An unlimited polymorphic object can be an array, but you cannot change its "arrayness" with SELECT TYPE.

SUBROUTINE sub(arg)
  CLASS(*), INTENT(IN) :: arg(:,:)    !<-- Rank two array here.
  SELECT TYPE (arg)
  TYPE IS (INTEGER)
     PRINT *, arg(1,2)    !<-- Still a rank two array.
  ...

You can make the array a component of a derived type and then select on that type.

TYPE :: Rank2Type
  INTEGER, ALLOCATABLE :: array(:,:)
END TYPE Rank2Type

TYPE :: Rank3Type
  INTEGER, ALLOCATABLE :: array(:,:,:)
END TYPE Rank3Type

SUBROUTINE sub(arg)
  CLASS(*), INTENT(IN) :: arg   !<-- A scalar.
  SELECT TYPE (arg)
  TYPE IS (Rank2Type)
    PRINT *, arg%array(1,2)    !<-- Component is a rank two array.
  TYPE IS (Rank3Type)
    PRINT *, arg%array(1,2,3)  !<-- Component is a rank three array.
  ...

 

0 Kudos
Steven_L_Intel1
Employee
1,611 Views

Fortran 2015 (and TS29113 "Further Interoperability with C") extends the language to include "assumed rank". You can query the rank of an assumed-rank dummy argument, but you're somewhat limited in what you can do with it. However, your code could be implemented this way (in a compiler with this support, which ifort doesn't yet have):

subroutine test (tn)
  use, intrinsic :: iso_c_binding
  class (*), dimension(..), Intent (Out) :: tn

  integer, pointer, dimension(:) :: tn_i_1
  integer, pointer, dimension(:,:) :: tn_i_2

  Select type (tn)

  Type Is (Integer)
   select case (rank(tn))
   case(1)
   call c_f_pointer (c_loc(tn),tn_i_1,shape(tn))
    tn_i_1 = 3
   case(2)
    call c_f_pointer(c_loc(tn),tn_i_2,shape(tn))
    tn_i_2 = 4
    end select

  End Select

end subroutine

Still not as nice as you'd like, but at least doable.

0 Kudos
Reply