IMHO, the main question is how to handle the subclass relationships. The other difficulty is that several functions return pointers to internal data structures, these require only a (non owning) thin wrapper around the pointer with a lifetime to track the dependency. So there are two classes of C++ “values”: owning values and references.
For subclasses, there is a variety of possibilities.
- Traits: this is nice because owning and references can be treated uniformly (
impl T and impl T + 'a). The problem is that they have to be implemented for each subclass (one may want to think to a for of transitive system to minimize boilerplate) and they will have to be brought into scope. Constructors cannot be part of the trait (they many not have a uniform interface across subclasses). If several subclasses may populate a single variable, they will ahve to be treated as dyn Trait.
Deref: the nice thing is that it is applied transitively by the compiler (so if A is a subclass of B and B of C, C methods are accessible from A without having to do anything). Also several subclasses may be converted to the base class and be handled as a reference to the base class. For this, we need two types of values, say T for owning values and AT for references, with T deref to AT. If T is a subclass of U, then the Derefs are as follows: T → AT → AU and U → AU. I have adopted the second approach in my attempt and it works well (although having, say, Mesh and AMesh is a bit ugly) but now is the time to revisit that.
Note that Autocxx implements AsRef (but not AsMut) when it detects a subclass relationship (this doesn't work for abstract classes).
To use Deref for subclasses, given the signature of Deref::deref, references have to be handled as Rust references &'a AT. This may be dangerous if C++ mutates the pointer “under our feet” as it is UB. There is an ongoing “discussion” to have more safety using a CppRef<T> type. It is actually already present in autocxx but not enabled by default.
What do you think?
IMHO, the main question is how to handle the subclass relationships. The other difficulty is that several functions return pointers to internal data structures, these require only a (non owning) thin wrapper around the pointer with a lifetime to track the dependency. So there are two classes of C++ “values”: owning values and references.
For subclasses, there is a variety of possibilities.
impl Tandimpl T + 'a). The problem is that they have to be implemented for each subclass (one may want to think to a for of transitive system to minimize boilerplate) and they will have to be brought into scope. Constructors cannot be part of the trait (they many not have a uniform interface across subclasses). If several subclasses may populate a single variable, they will ahve to be treated asdyn Trait.Deref: the nice thing is that it is applied transitively by the compiler (so ifAis a subclass ofBandBofC,Cmethods are accessible fromAwithout having to do anything). Also several subclasses may be converted to the base class and be handled as a reference to the base class. For this, we need two types of values, sayTfor owning values andATfor references, withTderef toAT. IfTis a subclass ofU, then theDerefs are as follows:T → AT → AUandU → AU. I have adopted the second approach in my attempt and it works well (although having, say,MeshandAMeshis a bit ugly) but now is the time to revisit that.Note that Autocxx implements
AsRef(but notAsMut) when it detects a subclass relationship (this doesn't work for abstract classes).To use
Dereffor subclasses, given the signature ofDeref::deref, references have to be handled as Rust references&'a AT. This may be dangerous if C++ mutates the pointer “under our feet” as it is UB. There is an ongoing “discussion” to have more safety using aCppRef<T>type. It is actually already present in autocxx but not enabled by default.What do you think?