3

I'm looking for some general advice as to the best approach to creating a derived type that stores arbitrary data with arbitrary rank.

Say I have a derived type Result with a data component (amongst others):

type, public :: Result
    private
    class(*), allocatable :: data
    ...
end type

which is initialised by some procedure (called from an interface Result):

function init(data) result(this)
  type(Result) :: this
  class(*), intent(in) :: data

  allocate(this%data, source=data)
end function

This works fine for scalar data, but I'm unsure about how to go about setting it up for arbitrary-rank data. I know procedures can accept assumed-rank parameters, so data in the init(data) function could be data(..), but I'm not sure it's possible to specify the derived type property this%data as being a assumed rank?

The other way I thought of doing it would be to store the arbitrary rank data as a scalar, if such a thing is possible in Fortran? This would be equivalent to using the serialize() and unserialize() functions in PHP. If anyone has any guidance on a similar approach, I'd be very grateful.

Ultimately I'd like to be able to do something like this:

type(Result) :: scalarResult
type(Result) :: 2DResult

scalarResult = Result(data=1.234)
2DResult = Result(data=[[1,2,3],[4,5,6]])
Sam Harrison
  • 123
  • 5
  • I'd recommend to have separate types for different ranks and generic function with specifics for each type OR - if your compiler supports it - parametrize the type with a rank type parameter. – Vladimir F Героям слава Jun 15 '17 at 11:01
  • What are you going to do with the variables after you construct them? – IanH Jun 20 '17 at 09:18
  • I'm using them to return from functions along with an error message: The `type(Result)` also has an `error` component, not shown here, that is another derived type `type(ErrorInstance)`, so that each function returns data and possibly an error. The end use of the data itself will be varied, e.g. it might be passed to other functions, printed somewhere, etc. I've decided to go with Vladimir's suggestion of having separate types, though this has the obvious limitation of only being able to deal with finite dimensions. – Sam Harrison Jun 20 '17 at 09:25

1 Answers1

2

It's not possible to have an assumed rank derived type component. You'll need to find another solution, such as what Vladimir suggests. Another idea, which is sort of a kluge, is to store the C_LOC of the data and the rank, call out to a C routine that constructs an appropriate C descriptor and then calls back in to a Fortran routine with an assumed-rank argument.

Do keep in mind that you can't do a lot with assumed rank in Fortran - SELECT RANK doesn't exist until F2015.

Steve Lionel
  • 6,972
  • 18
  • 31