On Wednesday, 17 June 2020 at 10:04:59 UTC, Atila Neves wrote:
[snip]
I was going to say "it should work" but instead I wrote the
code and... it does. It all falls out of how UFCS works and
usual language rules.
https://github.com/atilaneves/tardy/blob/feb26282608081098134c8846be87d398772ccb0/tests/ut/polymorphic.d#L102
https://github.com/atilaneves/tardy/blob/feb26282608081098134c8846be87d398772ccb0/tests/modules/ufcs/template_.d
Cool.
Am I right that the shared static constructor in vtable means
that there is one vtable for all the instances?
All instances of the same concrete type share the same vtable
pointer, yes. Originally I built the vtable on the spot with
`new` and assigned to each function pointer but then I realised
that was a waste of time and allocations - the vtable is unique
per concrete type.
Are there any technical issues preventing Polymorphism from
accepting a class in addition to an interface?
None. It could even accept a struct, really.
If I'm understanding you correctly, you could modify Polymorphic
(and a similar change to VirtualTable) to
struct Polymorphic(Interface, InstanceAllocator =
DefaultAllocator)
if(is(Interface == interface) || is(Interface == class) ||
is(Interface == struct))
and the current functionality would still work.
However, compared to normal inheritance, it would be missing the
"base" class's member variables that don't exist in the "derived"
one. You also couldn't call the "base" class member functions.
Polymorphic is assuming the member functions are all implemented
in the instance passed to it, correct?
I suppose I was more asking if there were any issues preventing
the ability to get these things to work. In other words,
Polymorphism works with interfaces now and the behavior is like
inheriting from an interface. Could it work for classes (and by
implication structs), such that the behavior is like inheriting
from classes, and not just treating the class like an interface.
In the case of structs, which may be a little simpler to
implement than classes, something as simple as below might be
able to get this functionality working.
static if (Interface == struct) {
Interface base;
alias base this;
}
so that member variables and functions missing from the instance
can get forwarded to the alias this. Though this wouldn't handle
super constructors.