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

Difficult to assign polymorphic objects

Andrew_Smith
Valued Contributor I
547 Views
This example shows how to implement a collection of polymorphic objects with a method to add an object on the end.

The code to assign the new object is nested select type construct since we are not allowed to intrinsic assign polymorphic types in F2003. We also need code to explictly allocate the copy. What if we had many levels of inheritance? The code becomes stupidly hard to write and maintain.

I know that the restriction on polymorphic intrinsic assignment has been lifted in F2008. Is Intel considering implementing this F2008 feature soon?

I realise that if I made item a pointer instead of an allocatable then the code might become simpler (not much probably). But we would then no longer have the safety of allocatables in terms of memory recovery.

[fortran]module things
   implicit none

   type BaseType
      integer a
   end type
   
   type, extends(BaseType) :: ExtendedType
      integer b
   end type
   
   type Collection
      class(BaseType), allocatable :: item
   end type
contains
   subroutine addObject(aCollection, anObject)
      type(Collection), allocatable, intent(inout) :: aCollection(:)
      class(BaseType), intent(in) :: anObject
      
      type(Collection), allocatable :: tempCollection(:)
      integer i, n
      n = size(aCollection)
      allocate(tempCollection(n + 1))
      do i = 1, n
         !tempCollection(i) = aCollection(i) !Error8296
         select type(new => aCollection(i)%item)
         type is(BaseType)
            allocate(BaseType::tempCollection(i)%item)
            select type(temp => tempCollection(i)%item)
            type is(BaseType)
               temp = new
            end select
         type is(ExtendedType)      
            allocate(ExtendedType::tempCollection(i)%item)
            select type(temp => tempCollection(i)%item)
            type is(ExtendedType)
               temp = new
            end select
         end select
      end do
      n = n + 1
 
      !tempCollection(i+1)%item = anObject !Error8296
      select type(new => anObject)
      type is(BaseType)
         allocate(BaseType::tempCollection(n)%item)
         select type(temp => tempCollection(n)%item)
         type is(BaseType)
            temp = new
         end select
      type is(ExtendedType)      
         allocate(ExtendedType::tempCollection(n)%item)
         select type(temp => tempCollection(n)%item)
         type is(ExtendedType)
            temp = new
         end select
      end select

      deallocate(aCollection)
      call move_alloc(tempCollection, aCollection)
   end subroutine
end module

program AssignClass
   use things
   type(Collection), allocatable :: someObjects(:)
   type(BaseType) :: part
   type(ExtendedType) :: newPart
   
   allocate(someObjects(2))
   allocate(BaseType::someObjects(1)%item)
   allocate(ExtendedType::someObjects(2)%item)
   
   !Assign some values to help debug
   someObjects(1)%item%a = 1
   someObjects(2)%item%a = 2
   select type(p => someObjects(2)%item)
   type is(ExtendedType)
      p%b = 20
   end select
   part%a = 3
   newPart%a = 4
   newPart%b = 40

   call addObject(someObjects, part)
   call addObject(someObjects, newPart)
end program[/fortran]
0 Kudos
3 Replies
joseph_battelle
Beginner
547 Views
Some of this gets easier even in F2003 when Intel supports (and fully debugs) allocate(..., source=poly) and move_alloc where poly is a regular or unlimited polymorphic source. Right now you have to do a lot of the select type and separate assignment gymnastics due to limitations in F2003 support. I don't think it's a big deal to have to create an assignment operator for polymorphic types but implementing the assignment operator or copy constructor with today's compiler is not as easy as it could be.
0 Kudos
thomas_boehme
New Contributor II
547 Views

I would also welcome a comment from Intel on this issue.

We are facing the same problem. The solution with the select type statements is cumbersome, as it has to be extended for each new derived type.

Best regards,
Thomas

0 Kudos
Wendy_Doerner__Intel
Valued Contributor I
547 Views
With our 12.0 Compiler, the above code compiles and we have added Fortran 2008 support for

GENERIC, OPERATOR, and ASSIGNMENT overloading in type-bound procedures

We are unable to comment on future products, but take input on missing features to be implmented into account when prioritizing features for the next release.

------

Wendy

Attaching or including files in a post

0 Kudos
Reply