Constructors in fortran - fortran

I have 2 subclasses - ResultsPublisherInitial & ResultsPublisherFinal, both extending ResultsPublisher abstract class.
Abstract class is like:
type, public, abstract:: ResultsPublisher
type(LAConstraintManagementResults), public, pointer:: lacmResults => null()
type(LACM_InputModel), public, pointer:: inputModel => null()
type(LACM_ForecastResults), public, pointer:: forecast => null()
end type ResultsPublisher
Then i have 2 subclasses - ResultsPublisherInitial & ResultsPublisherFinal, each with constructor:
type, public, extends(ResultsPublisher):: ResultsPublisherInitial
type(LACM_Model), public, pointer:: lacmModel => null()
end type ResultsPublisherInitial
interface ResultsPublisherInitial
procedure:: ConstructorInitial
end interface
contains
type(ResultsPublisherInitial) function ConstructorInitial(lacmResults, inputModel, forecast, lacmModel)
type(LAConstraintManagementResults), pointer:: lacmResults
type(LACM_InputModel), pointer, intent(in):: inputModel
type(LACM_ForecastResults), pointer, intent(in):: forecast
type(LACM_Model), pointer, intent(in):: lacmModel
ConstructorInitial%lacmResults => lacmResults
ConstructorInitial%inputModel => inputModel
ConstructorInitial%forecast => forecast
ConstructorInitial%lacmModel => lacmModel
end function
-----------------
!
type, public, extends(ResultsPublisher):: ResultsPublisherFinal
type(LR_Model), public, pointer:: lrModel => null()
end type ResultsPublisherFinal
interface ResultsPublisherFinal
procedure:: ConstructorFinal
end interface
contains
type(ResultsPublisherFinal) function ConstructorFinal(lacmResults, inputModel, forecast, lacmModel)
type(LAConstraintManagementResults), pointer:: lacmResults
type(LACM_InputModel), pointer, intent(in):: inputModel
type(LACM_ForecastResults), pointer, intent(in):: forecast
type(LACM_Model), pointer, intent(in):: lacmModel
ConstructorFinal%lacmResults => lacmResults
ConstructorFinal%inputModel => inputModel
ConstructorFinal%forecast => forecast
ConstructorFinal%lacmModel => lacmModel
end function
As you can see, i have 2 constructors for each concrete type, introduced through interface procedure. Names of those procedures are ConstructorInitial and ConstructorFinal.
Why i didnt name them only Constructor, as they are in different modules-scope, they should not overload each other? I tried to give them same name, but then i have been getting error when calling the constructor in client code. -> That means that for every class i had to add additional suffix after "Constructor".
I would like to have option to, in no mater how many different classes, use only Constructor word for object construction in every class. But in client-side code for object creation i will use exact name of that type.
Is this possible?

Related

Understanding pointer to member of class of type - no polymorphism

I thought it is straightforward that a 'pointer to member of class T of type DerivedT' can be used as a 'pointer to member of class T of type BaseT' if BaseT is base of DerivedT. The analogy seems to be obvious at least to me as DerivedT* can be used as a BaseT*, so DerivedT T::* should be able to be used as BaseT T::*
But it is not the case:
struct BaseT
{
};
struct DerivedT: public BaseT
{
};
struct T
{
DerivedT m_test;
};
using BaseTMemPtr = BaseT T::*;
int main()
{
T test;
BaseT* simplePtr = &test.m_test; //It is DerivedT*, but can be used as BaseT*
BaseT (T::*memPtr) = &T::m_test; //Error, BaseT T::* cannot be used as DerivedT T::*
BaseTMemPtr memPtr2 = &T::m_test; //Error, just the same
}
As I see there are two ways to interpret pointers to class members:
DerivedT T::* is a DerivedT pointer that points to a DerivedT object inside an object of T class (so points an object relative to another object)
DerivedT T::* points to some part of an object of class T which has by the way DerivedT type.
So the main difference between this two ways is while the first one can be interpreted as a kind of DerivedT pointer (enabling polymorphism), the later one kind of discards the type and restrict the usage a lot.
Why did C++ choose the second approach? What could be the unwanted consequence of enabling using DerivedT T::* as a BaseT T::* ? What are pointers to members in practice?
UPDATE:
I would like to achieve the following:
Desired solution
But it does not work if the members are not BaseMember types but BaseMember descendants.
The concept works if I use BaseMembers (but in this case I cannot implement the desired member functionality):
Works with broken functionality
UPDATE 2: Why
TLDR:
A way to compile time 'mark' (uniquely identify) a non-static member object of a runtime constructed class. Then check if a regular (non-member) pointer was compile-time marked or not in a runtime function that has
1, the compile time array of the marked members (can be anything, in my mind the polymorphic pointers-to-members)
2. 'this' pointer of the containing object (that has the marked and unmarked members)
3, the regular (non-pointer-to-member) pointer to the non-static member object.
Timeline: class definition (compile time) -> add class members (compile time) -> mark class members as enabled - e.g. in an array - (compile time) -> construction (runtime) -> members will call register function (runtime) -> in register function we need to check if the caller (we receive it as a regular pointer) is allowed to call this function or not (runtime).
Long description:
In a library I have a CRTP base class (DataBinding) that the users should descend from if they would like to use its compile- and runtime functionality.
Then in the library I also have an interface class: BaseMember, and many derived classes of it. The end user can use the derived classes to add non-static class member objects in their user-defined DataBinding-descendant classes.
In the user code, in DataBinding-descendant user classes the user can have BaseMember based non-static class members. And here comes the new functionality that requires pointer-to-member polymorphism: The user should be able to mark some of BaseMember-based class members in compile time(!) (the class itself does not have constexpr constructor) - in my mind this 'mark' could be storing the pointer-to-member of the BaseMember descendant member object -, and only the marked objects should be allowed to runtime-call a class member function (registerMember) in DataBinding (CRTP base of the current class).
In the registerMember runtime function I have the "this" object pointer (the containing object), I have the compile time user defined list that marks the enabled pointers-to-members (it can be replaced with any kind of unique identification) and I have the actual member pointer. I need to check if the actual member pointer is allowed to call the function (it was marked compile time).
A pointer-to-data-member is normally represented by a simple integer value, telling the offset of the beginning of the owner class to the beginning of the member. So the algorithm of retrieving a data member given a pointer to its owner is as simple as "add the offset to the address and dereference".
However, in order to go from a pointer-to-derived to a pointer-to-base, such a simple description is not enough. The offset is not necessarily constant, because of virtual inheritance. In order to find the offset, we need an actual derived object. The offset is stored in there somewhere. So in the general case, a pointer-to-data-member would have to be represented as a combination of at least two offsets, and fetching the member would require a decision (is a virtual base present?)
I guess the standard could have provided such conversion for the non-virtual inheritance case only. In this case the offset is constant and the conversion would consist of adding the two offsets (unless I'm missing some other corner case). However this is not being done, and the reason is, of course, that no one felt motivated enough to write a proposal. Pointers to data members (as opposed to pointers to member functions) were originally considered by Stroustrup "an artifact of generalization rather than something genuinely useful" (D&E, 13.11 Pointers to Members). They are now being used (mostly) to describe class layouts in an implementation-independent way, but there is no real need to use them polymorphically.

How do I call a super class method from a subclass when that super class contains deferred methods in fortran?

I trying to set up a parent class with two child subclasses. The parent class will contain at least one deferred method and at least one non-deferred method.
Parent Class
TYPE, ABSTRACT :: parent
CONTAINS
PROCEDURE (parent_deferred_method), DEFERRED :: deferred_method
PROCEDURE :: non_deferred_method => parent_non_deferred_method
END TYPE
ABSTRACT INTERFACE
FUNCTION parent_deferred_method(this)
IMPORT
CLASS (parent), INTENT(in) :: this
INTEGER :: parent_deferred_method
END FUNCTION
END INTERFACE
CONTAINS
FUNCTION parent_non_deferred_method(this)
CLASS (parent), INTENT(in) :: this
INTEGER :: parent_non_deferred_method
parent_non_deferred_method = 1
END FUNCTION
Because I have the a deferred method, I need to make the parent type as abstract. Now I want to define two child class. One child will not override the non-deferred method of the parent class.
Child 1 Class
TYPE, EXTENDS(parent) :: child1
CONTAINS
PROCEDURE :: deferred_method => child1_deferred_method
END TYPE
CONTAINS
FUNCTION child1_deferred_method(this)
CLASS (child1), INTENT(in) :: this
INTEGER :: child1_deferred_method
child1_deferred_method = 2
END FUNCTION
But the other will override. The problem I'm having is that I want to second child class to call the method of the parent class. However, this gives me an error since the parent class is ABSTRACT.
Child 2 Class
TYPE, EXTENDS(parent) :: child2
CONTAINS
PROCEDURE :: deferred_method => child2_deferred_method
PROCEDURE :: non_deferred_method => child2_non_deferred_method
END TYPE
CONTAINS
FUNCTION child2_deferred_method(this)
CLASS (child2), INTENT(in) :: this
INTEGER :: child2_deferred_method
child2_deferred_method = 3
END FUNCTION
FUNCTION child2_non_deferred_method(this)
CLASS (child2), INTENT(in) :: this
INTEGER :: child2_non_deferred_method
child2_non_deferred_method = 4 + &
& this%parent%non_deferred_method()
END FUNCTION
How do I call a super class method when that super class contains deferred methods?

Can I build a list of Strings using each constructor of a class?

I have a simple data type such as:
data Class = Class1
| Class2
| Class3
deriving (Show, Eq)
Is there a simple way for me to build a list of Strings that contains the String version of each of these such that:
func Class = ["Class1", "Class2", "Class3"]
The answer is yes, but with a caveat. What is the type of func? It looks like its first argument would be a type, not a value. More on the later...
Deriving Enum gets you get the ability to list off successive constructors and deriving Bounded gets you the ability to get the "first" and "last" elements of this enumeration.
data Class = Class1
| Class2
| Class3
deriving (Show, Eq, Enum, Bounded)
Then, we can get a list of all the elements via enumFromTo minBound maxBound (or just [minBound .. maxBound]).
However, back to the initial question on the type of func. You need to pass in a type as an argument. The usual way of doing this is using Proxy and ScopedTypeVariables.
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Proxy (Proxy(..))
func :: forall a. (Enum a, Bounded a, Show a) => Proxy a -> [String]
func Proxy = map show $ enumFromTo minBound (maxBound :: a)
Try this out at GHCi:
ghci> func (Proxy :: Proxy Class)
["Class1","Class2","Class3"]
ghci> func (Proxy :: Proxy Bool)
["True","False"]
You could, perhaps, do something like this:
data Class = Class1 | Class2 | Class3 deriving (Show, Eq, Enum)
GHCI:
Prelude> fmap show $ enumFrom Class1
["Class1","Class2","Class3"]

Hacklang - Why are protected members invariant?

The public member case
With the carte blanche access the calling scope has to them, it's no surprise that public members are invariant:
<?hh // strict
class Foo<+T> {
public function __construct(
public T $v
) {}
}
class ViolateType {
public static function violate(Foo<int> $foo): void {
self::cast_and_set($foo);
echo $foo->v + 1; // string + integer
}
public static function cast_and_set(Foo<arraykey> $foo): void {
$foo->v = "Poof! The integer `violate()` expects is now a string.";
}
}
// call ViolateType::foo(new Foo(1)); and watch the fireworks
The problem here is that both violate and cast_and_set can read and modify the same value (Foo->v) with different expectations of its type.
This problem, however, doesn't seem to exist for protected members.
Attempt to create a violation for protected members
Since the only distinction between private and protected is visibility to descendants, let's take a class (ImplCov) that, outside of some number of protected members, is otherwise validly covariant on a type, and extend it into a class (ImplInv) invariant on that type. Notably, being invariant on T allows me to expose a public setter — violate(T $v): T — where I'll try to break types.
<?hh // strict
// helper class hierarchy
class Base {}
class Derived extends Base {}
class ImplCov<+T> {
public function __construct(
protected T $v
) {}
}
class ImplInv<T> extends ImplCov<T> {
public function violate(T $v): T {
// Try to break types here
}
}
With an instance of ImplInv<Derived>, I'm compelled to cast to an ImplCov<Derived>, then leverage covariance to cast to an ImplCov<Base>. It like the most dangerous thing to do, with all three types referring to the same object. Let's inspect the relationships between each type:
ImplInv<Derived> and ImplCov<Base>: The violation in the public member case occured when the property was changed to a supertype (int->arraykey) or disjoint type with a common supertype (int->string). However, because ImplCov<Base> is covariant on T, there cannot exist methods that can be passed a Base instance and make v a true Base. ImplCov's methods cannot spawn a new Base() either and assign it to v because it doesn't know the eventual type of T.1
Meanwhile, because casting ImplCov<Derived> --> ImplCov<Base> --> ... can only cause it to be less derived, ImplInv::violate(T) is guaranteed to at worst set v to a subtype of the eventual ImplCov's T, guaranteeing a valid cast to that eventual T. The Derived of ImplInv<Derived> can't be cast, so once parameterized, that type is set in stone.
ImplInv<Derived> and ImplCov<Derived>: these can coexist by merit of T being the same between them, the cast being only of the outermost type.
ImplCov<Derived> and ImplCov<Base>: these can coexist by the assumption that ImplCov is validly covariant. The protected visibility of v is indistinguishable from private, since they are the same class.
All of this seems to point to protected visibility being kosher for covariant types. Am I missing something?
1. We can actually spawn new Base() by introducing the super constraint: ImplCov<T super Base>, but this is even weaker, since by definition ImplInv has to parameterize ImplCov in the extends statement with a supertype, making ImplInv's operations with v safe. Plus, ImplCov can't assume anything about the members of T.
Remember that a subclass can modify a protected member of any object of that class, not just $this. So this slight modification of your example above uses a protected member to similarly break the type system -- all we have to do is make ViolateType a subclass of Foo (and it doesn't matter what we set T to, or if we make ViolateType generic or whatever).
<?hh // strict
class Foo<+T> {
public function __construct(
/* HH_IGNORE_ERROR[4120] */
protected T $v
) {}
}
class ViolateType extends Foo<void> {
public static function violate(Foo<int> $foo): void {
self::cast_and_set($foo);
echo $foo->v + 1; // string + integer
}
public static function cast_and_set(Foo<arraykey> $foo): void {
$foo->v = "Poof! The integer `violate()` expects is now a string.";
}
}
This passes the typechecker with only the one error suppression for the protected member -- so allowing protected members to be covariant would break the type system.

Does SystemVerilog support downcasting?

Does SystemVerilog support downcasting (casting a base object to a derived object)? If so, how?
The following downcast example does not work:
class base;
int a = 5;
endclass
class extend extends base;
int b = 1;
endclass
module test;
initial begin
base m_base;
extend m_extend;
m_base = new();
m_extend = new();
$cast(m_extend, m_base);
$display(m_extend.a);
end
endmodule
Modify and rerun the example on EDA Playground: http://www.edaplayground.com/s/4/581
Yes, you can downcast. Your example is the correct syntax, and it actually does compile. However you are getting a runtime error because the cast fails.
The cast in you example is failing because you can only successfully downcast if the handle to the base object is actual referencing an object of the derived type. You can call $cast as a function and it will return a boolean indicating whether the cast was successful or not.
Here is an example:
class animal;
function void eat();
endfunction
endclass
class dog extends animal;
function void bark();
$display("woof");
endfunction
endclass
class cat extends animal;
function void meow();
$display("meow");
endfunction
endclass
module test;
initial begin
dog a_dog = new();
cat a_cat = new();
animal animals[$];
animals.push_back(a_dog);
animals.push_back(a_cat);
foreach (animals[i]) begin
dog another_dog;
animals[i].eat();
if ($cast(another_dog, animals[i])) begin
$display("Found a dog!");
another_dog.bark();
end
end
end
endmodule
Outputs:
# Found a dog!
# woof
See http://www.edaplayground.com/s/474/586
IEEE Std 1800-2012 § 8.16 "Casting" states:
It is always legal to assign an expression of subclass type to a variable of a class type higher in the inheritance tree (a superclass or ancestor of the expression type). It shall be illegal to directly assign a variable of a superclass type to a variable of one of its subclass types. However, $cast may be used to assign a superclass handle to a variable of a subclass type provided the superclass handle refers to an object that is assignment compatible with the subclass variable.
The following cast failes because a superclass object not be read as an childclass.
m_base = new();
$cast(m_extend, m_base); // destination type != source object type
To cast correctly the object of the source handle must be compatible with the destination typetypes must be comparable:
m_extend = new();
m_base = m_extend;
$cast(m_extend, m_base); // destination type == source object type
Downcasting can work through levels of inheritance. The following example demonstrates a base class handle pointing a grandchild object being casted to the extend class (the grandchild object's parent class):
class ext_more extends extend;
int c;
endclass
initial begin
base m_base;
extend m_extend;
ext_more m_ext_more;
m_ext_more = new();
m_base = m_ext_more;
$cast(m_extend, m_base); // legal, casting a subclass object to a parent handle
$display(m_extend.a);
end
Here are some working example: http://www.edaplayground.com/s/6/587
In this solution, you are nowhere downcasted, you just use the $cast to check if classes are compatible or not. If yes, print that particular class (DOG in your case) is found.
In you $cast function first parameter (destination) you are taking another_dog as a child class and in the second parameter (source) you are picking from queues that is again queues of child classes