Reputation: 421
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
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