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

IfExist Command?

holysword
Novice
1,168 Views
Hi there everybody,
I have a simple question. I have an (abstract) class c_father and some other classes, c_child1, c_child2, c_child3and c_child4 (non-abstract). The class c_child1 and c_child2 have an attribute named attribA.
At some point in my code, I have to use it in the following fashion
[fortran]CLASS(c_father) :: myclass
IF (EXISTS(myclass%attribA)) THEN
    PRINT *, myclass%attribA
END IF[/fortran]
I could naturally use SELECT TYPE, but then whenever a new c_father which has attribA is implemented, someone would have to dig in until find this routine and then add the new class - we want to avoid this kind of thing (the code is big, and the personal responsible for c_father don't really know anything about the part which will print attribA attribute).
Other option would be to add the attribA to c_father class and then just set it to something funny by default - let's say 0 - and instead of checking the existence, we check if the value was changed or not. The truth is that this is just a workaround, and not a real solution. Moreover, I gave a simple example, and in the real one we have attribA, attribB, ...
There is any elegant and neat way for doing that with the current Intel Compiler?
0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,168 Views
The Fortran language doesn't have such an "EXISTS" feature, but I wonder if you could get the effect you want with a type-bound PRINT procedure that is overridden in the child types. Then you'd just call myclass%Print and it would "do the right thing".

View solution in original post

0 Kudos
7 Replies
Steven_L_Intel1
Employee
1,169 Views
The Fortran language doesn't have such an "EXISTS" feature, but I wonder if you could get the effect you want with a type-bound PRINT procedure that is overridden in the child types. Then you'd just call myclass%Print and it would "do the right thing".
0 Kudos
holysword
Novice
1,168 Views
Thank you for your answer. Well, that would be the same as having attribA in every single child of c_father. It was just an example, but in the real case, attribB is not going to be printed, it is going to be added to something else, or etc. The children are really very different from each other.
I will just use a workaround in this case.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,168 Views
How about this:

Create a parameter enumeration (unique codes for) your attribute types.
Have as a requirement for all child classes to have a function that returns a reference/pointer/value to the member variable in the child that represents the attribute parameter .OR. return NULL .OR. return a default reference/value (argument passed into the query function).

With this technique the child need not know future additions to the attributeparameter enumeration table and the child need not know the operation to be performed by the caller. This does requie each child to have a query attribute (get reference to attribute) function.

Jim Dempsey

0 Kudos
Hirchert__Kurt_W
New Contributor II
1,168 Views
One classic way to do this is to create another abstract class based on c_father. All this class would do is extend the representation of c_father objects by adding the component attribA. For sake of discussion, lets call this class c_fatherA. Classes c_child1 and c_child2 and any other classes needing attribA would be based on c_fatherA instead of being based directly on c_father.

In your code, you could then do a SELECT TYPE looking for CLASS(c_fatherA).

You really need this SELECT TYPE or something equivalent. The designator myclass%attribA, is never legal when myclass is declared CLASS(c_father), because the c_father has no component named attribA. In order to be able to legally write this designator, you need to use SELECT TYPE to establish a local myclass which is effectively declared with a type (or class) that has attribA.
0 Kudos
Hirchert__Kurt_W
New Contributor II
1,168 Views
Quoting holysword
Well, that would be the same as having attribA in every single child of c_father.

No, it is quite different. Putting attribA into c_father would take space in every class c_father object. Putting a type-bound procedure in class_father adds space only to the dispatch table shared by all the objects of the same type. As a result this approach is much more memory efficient.

Using type-bound procedures is the other classic way of address the kind of problem you present, as it is the other way to start with an object of a general class and end up with an object that is syntactically recognized to be of a more specific type or class (so you can actually access attribA).

You might want to combine this approach with the intermediate class approach by putting a "do nothing" operation in c_father and overriding it with the operation that manipulates attribA in c_fatherA.

0 Kudos
holysword
Novice
1,168 Views
If I understood it right, you suggest the creation of something like
[fortran]FUNCTION DoExist(AttribCode) RESULT(ThePointer)[/fortran]
If every children have such function, then we could tell the function to set ThePointer to the correct reference, or to NULL in case it doesn't exist. That would be a good workaround; however, each Attribute may have a completely different type (actually the attribA normally is pointer to a function). I would have to create a DoExist for each kind of output.
0 Kudos
holysword
Novice
1,168 Views
Well, unfortunatelly, some classes may have attribA and attribB. That means that I would have to create c_fatherA, c_fatherB, and c_fatherAB. It gets much worse if I add a 3rd or 4th attribute. The SELECT TYPE would get very complex again.

The designator myclass%attribA, is never legal when myclass is declared CLASS(c_father)
That's truth, but that's more of a limitation of FORTRAN I believe. In some languages you could at least do a try-catch statement like
[fortran]try  
   PRINT *, c_father%attribA
catch (e)  
   PRINT *, 'Doesnt have attribA'[/fortran]
0 Kudos
Reply