Reputation: 13687
Let's assume that I have a derived type Coordinates
with its type-bound procedure swap
:
module myTypes
implicit none
public :: Coordinates
type Coordinates
real :: x,y
contains
procedure :: swap ! Error here
end type
contains
subroutine swap(this)
class (Coordinates) :: this
this%x = this%x + this%y
this%y = -(this%y - this%x)
this%x = this%x - this%y
end subroutine
end module
Now, if I have an instance of Coordinates
called point_A
, and if I want to call the type-bound procedure swap
for it, I would just write: call point_A%swap
. But if I have an array of instances of Coordinates
, like:
type(Coordinates), dimension(:), allocatable :: setOfPoints
then to call the swap
for all the elements of setOfPoints
, I would like to write:
call setOfPoints(:)%swap
In order to achieve that, I change the code of swap
procedure to:
subroutine swap(these)
class (Coordinates), dimension(:) :: these
integer :: i
do i = 1, size(this)
this(i)%x = this(i)%x + this(i)%y
this(i)%y = -(this(i)%y - this(i)%x)
this(i)%x = this(i)%x - this(i)%y
end do
end subroutine
Unfortunately, gfortran doesn't like my idea. On the line that I marked in the first piece of code it says:
Error: Passed-object dummy argument of 'swap' must be scalar.
Question: how can I call the type-bound procedure for all the instances of the derived type at once? I don't want to put the call in the loop, but I want to do this as I wrote it before, like what we always do with arrays in Fortran.
I read about the ELEMENTAL
keyword, but if I want to use it, I need the type-bound procedure to be 'pure', which is not my case.
I tried to place a DEFERRED
keyword after the word procedure
, but then compiler says:
Error: Interface must be specified for DEFERRED binding
I created an interface for swap
, but I couldn't figure out where to place it. I tried many positions and compiler said that 'interface was unexpected there'.
Also, I read about SELECT TYPE
, but I think it won't help in my case.
Upvotes: 3
Views: 465
Reputation: 59998
Your specific example is perfectly fine with ELEMENTAL
module myTypes
implicit none
public :: Coordinates
type Coordinates
real :: x,y
contains
procedure :: swap ! Error here
end type
contains
elemental subroutine swap(this)
class (Coordinates), intent(inout) :: this
this%x = this%x + this%y
this%y = -(this%y - this%x)
this%x = this%x - this%y
end subroutine
end module
use myTypes
type(Coordinates) :: arr(10)
arr = Coordinates(1.,2.)
call arr%swap
end
Your subroutine is pure. If it cannot be, consider using impure elemental
.
Upvotes: 2