support dynamic cast from all parents/virtual base
parent
39f4d92061
commit
9f58d21030
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
☐ Casting from parent and grandparents
|
|
||||||
☐ Allow overloading methods. The current solution is annoying!!!
|
☐ Allow overloading methods. The current solution is annoying!!!
|
||||||
☐ forward declaration?
|
☐ forward declaration?
|
||||||
☐ Global functions
|
☐ Global functions
|
||||||
|
@ -12,6 +11,7 @@ TODO:
|
||||||
☐ CMake install script
|
☐ CMake install script
|
||||||
|
|
||||||
Completed/Cancelled:
|
Completed/Cancelled:
|
||||||
|
✔ Casting from parent and grandparents
|
||||||
✔ Allow overloading constructors. The current solution is annoying!!! @done (16-11-16 17:00)
|
✔ Allow overloading constructors. The current solution is annoying!!! @done (16-11-16 17:00)
|
||||||
✔ Support "print obj" @done (16-11-16 17:00)
|
✔ Support "print obj" @done (16-11-16 17:00)
|
||||||
✔ methods for FastVector: at, [], ... @done (16-11-16 17:00)
|
✔ methods for FastVector: at, [], ... @done (16-11-16 17:00)
|
||||||
|
|
|
@ -770,8 +770,8 @@ void Class::pyxInitParentObj(FileWriter& pyxFile, const std::string& pyObj,
|
||||||
pyxFile.oss << pyObj << "." << parentClass->pyxCythonObj() << " = "
|
pyxFile.oss << pyObj << "." << parentClass->pyxCythonObj() << " = "
|
||||||
<< "<" << parentClass->pyxSharedCythonClass() << ">("
|
<< "<" << parentClass->pyxSharedCythonClass() << ">("
|
||||||
<< cySharedObj << ")\n";
|
<< cySharedObj << ")\n";
|
||||||
// Find the parent class with name "parentClass" and point its cython obj to the same pointer
|
// Find the parent class with name "parentClass" and point its cython obj
|
||||||
// TODO: This search is not efficient. :-(
|
// to the same pointer
|
||||||
auto parent_it = find_if(allClasses.begin(), allClasses.end(),
|
auto parent_it = find_if(allClasses.begin(), allClasses.end(),
|
||||||
[this](const Class& cls) {
|
[this](const Class& cls) {
|
||||||
return cls.cythonClass() ==
|
return cls.cythonClass() ==
|
||||||
|
@ -785,6 +785,42 @@ void Class::pyxInitParentObj(FileWriter& pyxFile, const std::string& pyObj,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
/*
|
||||||
|
@staticmethod
|
||||||
|
def dynamic_cast(noiseModel_Base base):
|
||||||
|
cdef noiseModel_Gaussian ret = noiseModel_Gaussian()
|
||||||
|
ret.gtnoiseModel_Gaussian_ = <shared_ptr[gtsam.noiseModel_Gaussian]>dynamic_pointer_cast[gtsam.noiseModel_Gaussian, gtsam.noiseModel_Base](base.gtnoiseModel_Base_)
|
||||||
|
ret.gtnoiseModel_Base_ = <shared_ptr[gtsam.noiseModel_Base]>(ret.gtnoiseModel_Gaussian_)
|
||||||
|
return ret
|
||||||
|
*/
|
||||||
|
void Class::pyxDynamicCast(FileWriter& pyxFile, const Class& curLevel,
|
||||||
|
const std::vector<Class>& allClasses) const {
|
||||||
|
std::string me = this->pythonClass(), sharedMe = this->pyxSharedCythonClass();
|
||||||
|
if (curLevel.parentClass) {
|
||||||
|
std::string parent = curLevel.parentClass->pythonClass(),
|
||||||
|
parentObj = curLevel.parentClass->pyxCythonObj(),
|
||||||
|
parentCythonClass = curLevel.parentClass->pyxCythonClass();
|
||||||
|
pyxFile.oss << "def dynamic_cast_" << me << "_" << parent << "(" << parent
|
||||||
|
<< " parent):\n";
|
||||||
|
pyxFile.oss << "\treturn " << me << ".cyCreateFromShared(<" << sharedMe
|
||||||
|
<< ">dynamic_pointer_cast[" << pyxCythonClass() << ","
|
||||||
|
<< parentCythonClass << "](parent." << parentObj
|
||||||
|
<< "))\n";
|
||||||
|
// Move up higher to one level: Find the parent class with name "parentClass"
|
||||||
|
auto parent_it = find_if(allClasses.begin(), allClasses.end(),
|
||||||
|
[&curLevel](const Class& cls) {
|
||||||
|
return cls.cythonClass() ==
|
||||||
|
curLevel.parentClass->cythonClass();
|
||||||
|
});
|
||||||
|
if (parent_it == allClasses.end()) {
|
||||||
|
cerr << "Can't find parent class: " << parentClass->cythonClass();
|
||||||
|
throw std::runtime_error("Parent class not found!");
|
||||||
|
}
|
||||||
|
pyxDynamicCast(pyxFile, *parent_it, allClasses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Class::emit_cython_pyx(FileWriter& pyxFile, const std::vector<Class>& allClasses) const {
|
void Class::emit_cython_pyx(FileWriter& pyxFile, const std::vector<Class>& allClasses) const {
|
||||||
pyxFile.oss << "cdef class " << pythonClass();
|
pyxFile.oss << "cdef class " << pythonClass();
|
||||||
|
@ -853,6 +889,9 @@ void Class::emit_cython_pyx(FileWriter& pyxFile, const std::vector<Class>& allCl
|
||||||
|
|
||||||
for(const Method& m: methods_ | boost::adaptors::map_values)
|
for(const Method& m: methods_ | boost::adaptors::map_values)
|
||||||
m.emit_cython_pyx(pyxFile, *this);
|
m.emit_cython_pyx(pyxFile, *this);
|
||||||
|
|
||||||
|
pyxDynamicCast(pyxFile, *this, allClasses);
|
||||||
|
|
||||||
pyxFile.oss << "\n\n";
|
pyxFile.oss << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,8 @@ public:
|
||||||
void pyxInitParentObj(FileWriter& pyxFile, const std::string& pyObj,
|
void pyxInitParentObj(FileWriter& pyxFile, const std::string& pyObj,
|
||||||
const std::string& cySharedObj,
|
const std::string& cySharedObj,
|
||||||
const std::vector<Class>& allClasses) const;
|
const std::vector<Class>& allClasses) const;
|
||||||
|
void pyxDynamicCast(FileWriter& pyxFile, const Class& curLevel,
|
||||||
|
const std::vector<Class>& allClasses) const;
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Class& cls) {
|
friend std::ostream& operator<<(std::ostream& os, const Class& cls) {
|
||||||
os << "class " << cls.name() << "{\n";
|
os << "class " << cls.name() << "{\n";
|
||||||
|
|
|
@ -338,7 +338,8 @@ void Module::emit_cython_pxd(FileWriter& pxdFile) const {
|
||||||
"\t\tshared_ptr()\n"
|
"\t\tshared_ptr()\n"
|
||||||
"\t\tshared_ptr(T*)\n"
|
"\t\tshared_ptr(T*)\n"
|
||||||
"\t\tT* get()\n"
|
"\t\tT* get()\n"
|
||||||
"\t\tT& operator*()\n\n";
|
"\t\tT& operator*()\n\n"
|
||||||
|
"\tcdef shared_ptr[T] dynamic_pointer_cast[T,U](const shared_ptr[U]& r)\n";
|
||||||
|
|
||||||
for(const TypedefPair& types: typedefs)
|
for(const TypedefPair& types: typedefs)
|
||||||
types.emit_cython_pxd(pxdFile);
|
types.emit_cython_pxd(pxdFile);
|
||||||
|
@ -372,7 +373,8 @@ void Module::emit_cython_pyx(FileWriter& pyxFile) const {
|
||||||
string pxdHeader = name + "_wrapper";
|
string pxdHeader = name + "_wrapper";
|
||||||
pyxFile.oss << "cimport numpy as np\n"
|
pyxFile.oss << "cimport numpy as np\n"
|
||||||
"cimport " << pxdHeader << " as " << name << "\n"
|
"cimport " << pxdHeader << " as " << name << "\n"
|
||||||
"from "<< pxdHeader << " cimport shared_ptr\n";
|
"from "<< pxdHeader << " cimport shared_ptr\n"
|
||||||
|
"from "<< pxdHeader << " cimport dynamic_pointer_cast\n";
|
||||||
// import all typedefs, e.g. from gtsam cimport Key, so we don't need to say gtsam.Key
|
// import all typedefs, e.g. from gtsam cimport Key, so we don't need to say gtsam.Key
|
||||||
for(const Qualified& q: Qualified::BasicTypedefs) {
|
for(const Qualified& q: Qualified::BasicTypedefs) {
|
||||||
pyxFile.oss << "from " << pxdHeader << " cimport " << q.cythonClass() << "\n";
|
pyxFile.oss << "from " << pxdHeader << " cimport " << q.cythonClass() << "\n";
|
||||||
|
|
Loading…
Reference in New Issue