pyx: add constructors and fixing inheritance
parent
2d3d6d99f9
commit
1e84da1cfa
|
@ -120,6 +120,29 @@ void Argument::emit_cython_pxd(FileWriter& file) const {
|
||||||
file.oss << cythonType << " " << name;
|
file.oss << cythonType << " " << name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
void Argument::emit_cython_pyx(FileWriter& file) const {
|
||||||
|
string typeName = type.pythonClassName();
|
||||||
|
string cythonType = typeName;
|
||||||
|
// use numpy for Vector and Matrix
|
||||||
|
if (typeName=="Vector" || typeName == "Matrix")
|
||||||
|
cythonType = "np.ndarray";
|
||||||
|
file.oss << cythonType << " " << name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
void Argument::emit_cython_pyx_asParam(FileWriter& file) const {
|
||||||
|
string cythonType = type.cythonClassName();
|
||||||
|
string cythonVar;
|
||||||
|
if (cythonType == "Vector" || cythonType == "Matrix") {
|
||||||
|
cythonVar = "Map[" + cythonType + "Xd](" + name + ")";
|
||||||
|
} else {
|
||||||
|
cythonVar = name + "." + type.pyxCythonObj();
|
||||||
|
if (!is_ptr) cythonVar = "deref(" + cythonVar + ")";
|
||||||
|
}
|
||||||
|
file.oss << cythonVar;
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
string ArgumentList::types() const {
|
string ArgumentList::types() const {
|
||||||
string str;
|
string str;
|
||||||
|
@ -207,6 +230,22 @@ void ArgumentList::emit_cython_pxd(FileWriter& file) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
void ArgumentList::emit_cython_pyx(FileWriter& file) const {
|
||||||
|
for (size_t j = 0; j < size(); ++j) {
|
||||||
|
at(j).emit_cython_pyx(file);
|
||||||
|
if (j < size() - 1) file.oss << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
void ArgumentList::emit_cython_pyx_asParams(FileWriter& file) const {
|
||||||
|
for (size_t j = 0; j < size(); ++j) {
|
||||||
|
at(j).emit_cython_pyx_asParam(file);
|
||||||
|
if (j < size() - 1) file.oss << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void ArgumentList::proxy_check(FileWriter& proxyFile) const {
|
void ArgumentList::proxy_check(FileWriter& proxyFile) const {
|
||||||
// Check nr of arguments
|
// Check nr of arguments
|
||||||
|
|
|
@ -67,6 +67,8 @@ struct Argument {
|
||||||
* @param file output stream
|
* @param file output stream
|
||||||
*/
|
*/
|
||||||
void emit_cython_pxd(FileWriter& file) const;
|
void emit_cython_pxd(FileWriter& file) const;
|
||||||
|
void emit_cython_pyx(FileWriter& file) const;
|
||||||
|
void emit_cython_pyx_asParam(FileWriter& file) const;
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Argument& arg) {
|
friend std::ostream& operator<<(std::ostream& os, const Argument& arg) {
|
||||||
os << (arg.is_const ? "const " : "") << arg.type << (arg.is_ptr ? "*" : "")
|
os << (arg.is_const ? "const " : "") << arg.type << (arg.is_ptr ? "*" : "")
|
||||||
|
@ -114,6 +116,8 @@ struct ArgumentList: public std::vector<Argument> {
|
||||||
* @param file output stream
|
* @param file output stream
|
||||||
*/
|
*/
|
||||||
void emit_cython_pxd(FileWriter& file) const;
|
void emit_cython_pxd(FileWriter& file) const;
|
||||||
|
void emit_cython_pyx(FileWriter& file) const;
|
||||||
|
void emit_cython_pyx_asParams(FileWriter& file) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* emit checking arguments to MATLAB proxy
|
* emit checking arguments to MATLAB proxy
|
||||||
|
|
|
@ -673,10 +673,9 @@ void Class::python_wrapper(FileWriter& wrapperFile) const {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Class::emit_cython_pxd(FileWriter& pxdFile) const {
|
void Class::emit_cython_pxd(FileWriter& pxdFile) const {
|
||||||
string cythonClassName = qualifiedName("_", 1);
|
|
||||||
pxdFile.oss << "cdef extern from \"" << includeFile << "\" namespace \""
|
pxdFile.oss << "cdef extern from \"" << includeFile << "\" namespace \""
|
||||||
<< qualifiedNamespaces("::") << "\":" << endl;
|
<< qualifiedNamespaces("::") << "\":" << endl;
|
||||||
pxdFile.oss << "\tcdef cppclass " << cythonClassName << " \"" << qualifiedName("::") << "\"";
|
pxdFile.oss << "\tcdef cppclass " << cythonClassName() << " \"" << qualifiedName("::") << "\"";
|
||||||
if (templateArgs.size()>0) {
|
if (templateArgs.size()>0) {
|
||||||
pxdFile.oss << "[";
|
pxdFile.oss << "[";
|
||||||
for(size_t i = 0; i<templateArgs.size(); ++i) {
|
for(size_t i = 0; i<templateArgs.size(); ++i) {
|
||||||
|
@ -688,7 +687,7 @@ void Class::emit_cython_pxd(FileWriter& pxdFile) const {
|
||||||
if (parentClass) pxdFile.oss << "(" << parentClass->qualifiedName("_") << ")";
|
if (parentClass) pxdFile.oss << "(" << parentClass->qualifiedName("_") << ")";
|
||||||
pxdFile.oss << ":\n";
|
pxdFile.oss << ":\n";
|
||||||
|
|
||||||
constructor.emit_cython_pxd(pxdFile, cythonClassName);
|
constructor.emit_cython_pxd(pxdFile, cythonClassName());
|
||||||
if (constructor.nrOverloads()>0) pxdFile.oss << "\n";
|
if (constructor.nrOverloads()>0) pxdFile.oss << "\n";
|
||||||
|
|
||||||
for(const StaticMethod& m: static_methods | boost::adaptors::map_values)
|
for(const StaticMethod& m: static_methods | boost::adaptors::map_values)
|
||||||
|
@ -706,17 +705,62 @@ void Class::emit_cython_pxd(FileWriter& pxdFile) const {
|
||||||
pxdFile.oss << "\n\n";
|
pxdFile.oss << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Class::emit_cython_pyx(FileWriter& pyxFile) const {
|
void Class::pyxInitParentObj(FileWriter& pyxFile, const std::string& pyObj, const std::string& cySharedObj, const std::vector<Class>& allClasses) const {
|
||||||
string cythonClassName = qualifiedName("_", 1);
|
if (parentClass) {
|
||||||
pyxFile.oss << "cdef class " << name();
|
pyxFile.oss << pyObj << "." << parentClass->pyxCythonObj() << " = "
|
||||||
if (parentClass) pyxFile.oss << "(" << parentClass->name() << ")";
|
<< "<" << parentClass->pyxSharedCythonClass() << ">("
|
||||||
|
<< cySharedObj << ")\n";
|
||||||
|
// Find the parent class with name "parentClass" and point its cython obj to the same pointer
|
||||||
|
// TODO: This search is not efficient. :-(
|
||||||
|
auto parent_it = find_if(allClasses.begin(), allClasses.end(),
|
||||||
|
[this](const Class& cls) {
|
||||||
|
return cls.cythonClassName() ==
|
||||||
|
this->parentClass->cythonClassName();
|
||||||
|
});
|
||||||
|
if (parent_it == allClasses.end()) {
|
||||||
|
cerr << "Can't find parent class: " << parentClass->cythonClassName();
|
||||||
|
throw std::runtime_error("Parent class not found!");
|
||||||
|
}
|
||||||
|
parent_it->pyxInitParentObj(pyxFile, pyObj, cySharedObj, allClasses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Class::emit_cython_pyx(FileWriter& pyxFile, const std::vector<Class>& allClasses) const {
|
||||||
|
pyxFile.oss << "cdef class " << pythonClassName();
|
||||||
|
if (parentClass) pyxFile.oss << "(" << parentClass->pythonClassName() << ")";
|
||||||
pyxFile.oss << ":\n";
|
pyxFile.oss << ":\n";
|
||||||
pyxFile.oss << "\tcdef shared_ptr[" << cythonClassName << "] "
|
|
||||||
<< "gt" << name() << "_\n";
|
|
||||||
|
|
||||||
constructor.emit_cython_pyx(pyxFile, cythonClassName);
|
pyxFile.oss << "\tcdef " << pyxSharedCythonClass() << " " << pyxCythonObj() << "\n";
|
||||||
|
|
||||||
|
pyxFile.oss << "\tdef __cinit__(self):\n"
|
||||||
|
"\t\tself." << pyxCythonObj() << " = "
|
||||||
|
<< pyxSharedCythonClass() << "(new " << pyxCythonClass() << "())\n";
|
||||||
|
pyxInitParentObj(pyxFile, "\t\tself", "self." + pyxCythonObj(), allClasses);
|
||||||
pyxFile.oss << "\n";
|
pyxFile.oss << "\n";
|
||||||
|
|
||||||
|
pyxFile.oss << "\t@staticmethod\n";
|
||||||
|
pyxFile.oss << "\tcdef " << pythonClassName() << " cyCreate(" << pyxSharedCythonClass() << " other):\n"
|
||||||
|
<< "\t\tcdef " << pythonClassName() << " ret = " << pythonClassName() << "()\n"
|
||||||
|
<< "\t\tret." << pyxCythonObj() << " = other\n";
|
||||||
|
pyxInitParentObj(pyxFile, "\t\tret", "other", allClasses);
|
||||||
|
pyxFile.oss << "\t\treturn ret" << "\n";
|
||||||
|
|
||||||
|
constructor.emit_cython_pyx(pyxFile, *this);
|
||||||
|
// if (constructor.nrOverloads()>0) pyxFile.oss << "\n";
|
||||||
|
|
||||||
|
// for(const StaticMethod& m: static_methods | boost::adaptors::map_values)
|
||||||
|
// m.emit_cython_pxd(pyxFile);
|
||||||
|
// if (static_methods.size()>0) pyxFile.oss << "\n";
|
||||||
|
|
||||||
|
// for(const Method& m: nontemplateMethods_ | boost::adaptors::map_values)
|
||||||
|
// m.emit_cython_pxd(pyxFile);
|
||||||
|
// for(const TemplateMethod& m: templateMethods_ | boost::adaptors::map_values)
|
||||||
|
// m.emit_cython_pxd(pyxFile);
|
||||||
|
// size_t numMethods = constructor.nrOverloads() + static_methods.size() +
|
||||||
|
// methods_.size() + templateMethods_.size();
|
||||||
|
// if (numMethods == 0)
|
||||||
|
// pyxFile.oss << "\t\tpass";
|
||||||
|
pyxFile.oss << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -149,7 +149,11 @@ public:
|
||||||
|
|
||||||
// emit cython wrapper
|
// emit cython wrapper
|
||||||
void emit_cython_pxd(FileWriter& pxdFile) const;
|
void emit_cython_pxd(FileWriter& pxdFile) const;
|
||||||
void emit_cython_pyx(FileWriter& pyxFile) const;
|
void emit_cython_pyx(FileWriter& pyxFile,
|
||||||
|
const std::vector<Class>& allClasses) const;
|
||||||
|
void pyxInitParentObj(FileWriter& pyxFile, const std::string& pyObj,
|
||||||
|
const std::string& cySharedObj,
|
||||||
|
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";
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "Constructor.h"
|
#include "Constructor.h"
|
||||||
|
#include "Class.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace wrap;
|
using namespace wrap;
|
||||||
|
@ -131,7 +132,23 @@ void Constructor::emit_cython_pxd(FileWriter& pxdFile, Str className) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Constructor::emit_cython_pyx(FileWriter& pyxFile, Str className) const {
|
void Constructor::emit_cython_pyx(FileWriter& pyxFile, const Class& cls) const {
|
||||||
|
// FIXME: handle overloads properly! This is lazy...
|
||||||
|
for (size_t i = 0; i < nrOverloads(); i++) {
|
||||||
|
ArgumentList args = argumentList(i);
|
||||||
|
pyxFile.oss << "\t@staticmethod\n";
|
||||||
|
pyxFile.oss << "\tdef " << cls.cythonClassName()
|
||||||
|
<< ((i > 0) ? "_" + to_string(i) : "") << "(";
|
||||||
|
args.emit_cython_pyx(pyxFile);
|
||||||
|
pyxFile.oss << "): \n";
|
||||||
|
pyxFile.oss << "\t\treturn " << cls.cythonClassName() << ".cyCreate("
|
||||||
|
// shared_ptr[gtsam.Values](new gtsam.Values(deref(other.gtValues_))))
|
||||||
|
<< cls.pyxSharedCythonClass() << "(new "
|
||||||
|
<< cls.pyxCythonClass() << "(";
|
||||||
|
args.emit_cython_pyx_asParams(pyxFile);
|
||||||
|
pyxFile.oss << "))"
|
||||||
|
<< ")\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
|
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
class Class;
|
||||||
|
|
||||||
// Constructor class
|
// Constructor class
|
||||||
struct Constructor: public OverloadedFunction {
|
struct Constructor: public OverloadedFunction {
|
||||||
|
|
||||||
|
@ -80,7 +83,7 @@ struct Constructor: public OverloadedFunction {
|
||||||
|
|
||||||
// emit cython wrapper
|
// emit cython wrapper
|
||||||
void emit_cython_pxd(FileWriter& pxdFile, Str className) const;
|
void emit_cython_pxd(FileWriter& pxdFile, Str className) const;
|
||||||
void emit_cython_pyx(FileWriter& pyxFile, Str className) const;
|
void emit_cython_pyx(FileWriter& pyxFile, const Class& cls) const;
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Constructor& m) {
|
friend std::ostream& operator<<(std::ostream& os, const Constructor& m) {
|
||||||
for (size_t i = 0; i < m.nrOverloads(); i++)
|
for (size_t i = 0; i < m.nrOverloads(); i++)
|
||||||
|
|
|
@ -302,8 +302,8 @@ void Module::cython_code(const string& toolboxPath) const {
|
||||||
pxdFile.emit(true);
|
pxdFile.emit(true);
|
||||||
|
|
||||||
// create cython pyx file
|
// create cython pyx file
|
||||||
for(const Class& cls: uninstantiatedClasses)
|
for(const Class& cls: expandedClasses)
|
||||||
cls.emit_cython_pyx(pyxFile);
|
cls.emit_cython_pyx(pyxFile, expandedClasses);
|
||||||
pyxFile.oss << "\n";
|
pyxFile.oss << "\n";
|
||||||
pyxFile.emit(true);
|
pyxFile.emit(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,30 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// the Cython class in pxd
|
||||||
|
std::string cythonClassName() const {
|
||||||
|
return qualifiedName("_", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// the Python class in pyx
|
||||||
|
std::string pythonClassName() const {
|
||||||
|
return cythonClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return the Cython class in pxd corresponding to a Python class in pyx
|
||||||
|
std::string pyxCythonClass() const {
|
||||||
|
return namespaces_[0] + "." + cythonClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// the internal Cython shared obj in a Python class wrappper
|
||||||
|
std::string pyxCythonObj() const {
|
||||||
|
return "gt" + cythonClassName() + "_";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string pyxSharedCythonClass() const {
|
||||||
|
return "shared_ptr[" + pyxCythonClass() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Qualified& q) {
|
friend std::ostream& operator<<(std::ostream& os, const Qualified& q) {
|
||||||
os << q.qualifiedName("::");
|
os << q.qualifiedName("::");
|
||||||
return os;
|
return os;
|
||||||
|
|
Loading…
Reference in New Issue