Struct Embedding in Co-array Fortran

Co-array Fortran supports a form of composition through the use of derived types. While it doesn’t have a direct equivalent to struct embedding, we can achieve similar functionality using derived types and type-bound procedures.

module base_module
  implicit none
  private

  type, public :: base
    integer :: num
  contains
    procedure :: describe
  end type base

contains
  function describe(self) result(desc)
    class(base), intent(in) :: self
    character(:), allocatable :: desc
    character(len=20) :: num_str

    write(num_str, '(I0)') self%num
    desc = "base with num=" // trim(adjustl(num_str))
  end function describe
end module base_module

module container_module
  use base_module
  implicit none
  private

  type, public :: container
    type(base) :: base_component
    character(:), allocatable :: str
  contains
    procedure :: describe => container_describe
  end type container

contains
  function container_describe(self) result(desc)
    class(container), intent(in) :: self
    character(:), allocatable :: desc
    
    desc = self%base_component%describe()
  end function container_describe
end module container_module

program main
  use container_module
  implicit none

  type(container) :: co
  
  ! Initialize the container
  co%base_component%num = 1
  co%str = "some name"

  ! Access fields directly
  print '(A,I0,A,A)', "co={num: ", co%base_component%num, ", str: ", co%str

  ! Access through the full path
  print '(A,I0)', "also num: ", co%base_component%num

  ! Call the describe method
  print '(A,A)', "describe: ", co%describe()

end program main

In this Co-array Fortran version:

  1. We define a base type in the base_module with an integer num and a describe method.

  2. We create a container type in the container_module that includes a base component and a string str.

  3. The container type also has a describe method that delegates to the base component’s describe method.

  4. In the main program, we create a container instance, initialize its fields, and demonstrate how to access the fields and call methods.

To run this program, you would typically save it in a file (e.g., struct_composition.f90) and compile it using a Fortran compiler that supports Co-array features. For example:

$ gfortran -fcoarray=single struct_composition.f90 -o struct_composition
$ ./struct_composition
co={num: 1, str: some name}
also num: 1
describe: base with num=1

This example demonstrates how to achieve a form of composition in Co-array Fortran, which is conceptually similar to struct embedding in other languages. The container type includes a base component and can use its methods, providing a way to reuse and extend functionality.