user1407220
user1407220

Reputation: 421

Fortran Assignment operator Interface in derived data type

I have the following code:

    Module Hello
      Implicit None
    Type, Public :: TestOne
       Private
       Integer :: One, Two, Three
     contains
       Procedure, Pass, Public :: Set => SetSub
    End type TestOne
    Private :: SetSub
    Interface Assignment(=)
       Module Procedure SubgetValue
    End Interface Assignment(=)
    contains
      Subroutine SetSub(this)
        Implicit none
        Class(TestOne), Intent(InOut) :: this
        this%one=1
        this%two=2
        this%three=3
      End Subroutine SetSub
      Subroutine SubGetValue(ISOut,TSIn)
        Implicit None
        Integer, Intent(Out) :: ISOut
        Class(TestOne), Intent(In) :: TSIn
        ISOut=TSIn%one
      End Subroutine SubGetValue
    End Module Hello
    Program Test
      use Hello
      Implicit None
      Type(TestOne) :: TSTest
      Integer :: b
      call TSTest%Set()
      b=TSTest
      write(*,*) b
    End Program Test

In this version, I can access only "TSTest%One" via "=". The question is how I can create an interface assignment such that I can access "TSTest%one", "TSTest%two" or "TSTest%three". If "One", "Two" and "Three" were not private, that would be trivial. However, the goal is to keep them private and access them via the interface assignment. Any additional module procedure for accessing "Two" or "Three" would have the same dummy arguments resulting in a compile time error.

However, another way to solve that issue would be a "setter"/"getter" routine, but I have read somewhere on the web that accessing varialbe via assignments is much faster than via a "getter" routine.

Any suggestions.

Thanks

Upvotes: 1

Views: 1831

Answers (1)

IanH
IanH

Reputation: 21431

Your defined assignment routine has the same overhead as a "getter" - because that's what it is.

If (when) compiler inter-procedural optimisation is up to scratch, there shouldn't be any additional overhead, particularly in the case where the TSTest object is not polymorphic.

Prior to your edit...

Beyond any obvious single candidate for extraction by the mixed type assignment, my preferred approach for this is to have separate bindings to access each component.

TYPE, PUBLIC :: TestOne
  PRIVATE
  INTEGER :: One, Two, Three
CONTAINS
  PROCEDURE :: GetOne
  PROCEDURE :: GetTwo
  PROCEDURE :: GetThree
  ...

FUNCTION GetOne(this)
  CLASS(TestOne), INTENT(IN) :: this
  INTEGER :: GetOne
  GetOne = this%One
END FUNCTION GetOne
...

b = TSTTest%GetTwo()

If I'm then feeling creative, I may also add some generic type bindings for unary "access" operators to the type:

TYPE, PUBLIC :: TestOne
  PRIVATE
  INTEGER :: One, Two, Three
CONTAINS
  PROCEDURE :: GetOne
  ...
  GENERIC :: OPERATOR(.TheOneOutOf.) => GetOne
...

b = .TheOneOutOf. TSTTest

though sometimes this creativity has just led to me becoming overly familiar with my compiler vendor's support channels.

(Consider making the defined assignment type bound.)

Upvotes: 4

Related Questions