support global function overloads
parent
338c73669e
commit
6ef6457e51
|
@ -149,7 +149,7 @@ void GlobalFunction::emit_cython_pxd(FileWriter& file) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void GlobalFunction::emit_cython_pyx(FileWriter& file) const {
|
void GlobalFunction::emit_cython_pyx_no_overload(FileWriter& file) const {
|
||||||
string funcName = pyRename(name_);
|
string funcName = pyRename(name_);
|
||||||
|
|
||||||
// Function definition
|
// Function definition
|
||||||
|
@ -173,6 +173,44 @@ void GlobalFunction::emit_cython_pyx(FileWriter& file) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
void GlobalFunction::emit_cython_pyx(FileWriter& file) const {
|
||||||
|
string funcName = pyRename(name_);
|
||||||
|
|
||||||
|
size_t N = nrOverloads();
|
||||||
|
if (N == 1) {
|
||||||
|
emit_cython_pyx_no_overload(file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dealing with overloads..
|
||||||
|
file.oss << "def " << funcName << "(*args, **kwargs):\n";
|
||||||
|
file.oss << pyx_checkDuplicateNargsKwArgs(1);
|
||||||
|
for (size_t i = 0; i < N; ++i) {
|
||||||
|
file.oss << "\tsuccess, results = " << funcName << "_" << i
|
||||||
|
<< "(*args, **kwargs)\n";
|
||||||
|
file.oss << "\tif success:\n\t\t\treturn results\n";
|
||||||
|
}
|
||||||
|
file.oss << "\traise TypeError('Could not find the correct overload')\n";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < N; ++i) {
|
||||||
|
ArgumentList args = argumentList(i);
|
||||||
|
file.oss << "def " + funcName + "_" + to_string(i) +
|
||||||
|
"(*args, **kwargs):\n";
|
||||||
|
file.oss << pyx_resolveOverloadParams(args, false, 1); // lazy: always return None even if it's a void function
|
||||||
|
|
||||||
|
/// Call cython corresponding function
|
||||||
|
string ret = pyx_functionCall("pxd", funcName, i);
|
||||||
|
if (!returnVals_[i].isVoid()) {
|
||||||
|
file.oss << "\tcdef " << returnVals_[i].pyx_returnType()
|
||||||
|
<< " ret = " << ret << "\n";
|
||||||
|
file.oss << "\treturn True, " << returnVals_[i].pyx_casting("ret") << "\n";
|
||||||
|
} else {
|
||||||
|
file.oss << "\t" << ret << "\n";
|
||||||
|
file.oss << "\treturn True, None\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
||||||
} // \namespace wrap
|
} // \namespace wrap
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct GlobalFunction: public FullyOverloadedFunction {
|
||||||
// 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;
|
||||||
|
void emit_cython_pyx_no_overload(FileWriter& pyxFile) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -71,20 +71,22 @@ public:
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string pyx_resolveOverloadParams(const ArgumentList& args, bool isVoid) const {
|
std::string pyx_resolveOverloadParams(const ArgumentList& args, bool isVoid, size_t indentLevel = 2) const {
|
||||||
|
std::string indent;
|
||||||
|
for (size_t i = 0; i<indentLevel; ++i) indent += "\t";
|
||||||
std::string s;
|
std::string s;
|
||||||
s += "\t\tif len(args)+len(kwargs) !=" + std::to_string(args.size()) + ":\n";
|
s += indent + "if len(args)+len(kwargs) !=" + std::to_string(args.size()) + ":\n";
|
||||||
s += "\t\t\treturn False";
|
s += indent + "\treturn False";
|
||||||
s += (!isVoid) ? ", None\n" : "\n";
|
s += (!isVoid) ? ", None\n" : "\n";
|
||||||
if (args.size() > 0) {
|
if (args.size() > 0) {
|
||||||
s += "\t\t__params = kwargs.copy()\n";
|
s += indent + "__params = kwargs.copy()\n";
|
||||||
s += "\t\t__names = [" + args.pyx_paramsList() + "]\n";
|
s += indent + "__names = [" + args.pyx_paramsList() + "]\n";
|
||||||
s += "\t\tfor i in range(len(args)):\n";
|
s += indent + "for i in range(len(args)):\n";
|
||||||
s += "\t\t\t__params[__names[i]] = args[i]\n";
|
s += indent + "\t__params[__names[i]] = args[i]\n";
|
||||||
s += "\t\ttry:\n";
|
s += indent + "try:\n";
|
||||||
s += args.pyx_castParamsToPythonType();
|
s += args.pyx_castParamsToPythonType();
|
||||||
s += "\t\texcept:\n";
|
s += indent + "except:\n";
|
||||||
s += "\t\t\treturn False";
|
s += indent + "\treturn False";
|
||||||
s += (!isVoid) ? ", None\n" : "\n";
|
s += (!isVoid) ? ", None\n" : "\n";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
@ -92,7 +94,9 @@ public:
|
||||||
|
|
||||||
/// if two overloading methods have the same number of arguments, they have
|
/// if two overloading methods have the same number of arguments, they have
|
||||||
/// to be resolved via keyword args
|
/// to be resolved via keyword args
|
||||||
std::string pyx_checkDuplicateNargsKwArgs() const {
|
std::string pyx_checkDuplicateNargsKwArgs(size_t indentLevel = 2) const {
|
||||||
|
std::string indent;
|
||||||
|
for (size_t i = 0; i<indentLevel; ++i) indent += "\t";
|
||||||
std::unordered_set<size_t> nargsSet;
|
std::unordered_set<size_t> nargsSet;
|
||||||
std::vector<size_t> nargsDuplicates;
|
std::vector<size_t> nargsDuplicates;
|
||||||
for (size_t i = 0; i < nrOverloads(); ++i) {
|
for (size_t i = 0; i < nrOverloads(); ++i) {
|
||||||
|
@ -105,13 +109,13 @@ public:
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
if (nargsDuplicates.size() > 0) {
|
if (nargsDuplicates.size() > 0) {
|
||||||
s += "\t\tif len(kwargs)==0 and len(args)+len(kwargs) in [";
|
s += indent + "if len(kwargs)==0 and len(args)+len(kwargs) in [";
|
||||||
for (size_t i = 0; i < nargsDuplicates.size(); ++i) {
|
for (size_t i = 0; i < nargsDuplicates.size(); ++i) {
|
||||||
s += std::to_string(nargsDuplicates[i]);
|
s += std::to_string(nargsDuplicates[i]);
|
||||||
if (i < nargsDuplicates.size() - 1) s += ",";
|
if (i < nargsDuplicates.size() - 1) s += ",";
|
||||||
}
|
}
|
||||||
s += "]:\n";
|
s += "]:\n";
|
||||||
s += "\t\t\traise TypeError('Overloads with the same number of "
|
s += indent + "\traise TypeError('Overloads with the same number of "
|
||||||
"arguments exist. Please use keyword arguments to "
|
"arguments exist. Please use keyword arguments to "
|
||||||
"differentiate them!')\n";
|
"differentiate them!')\n";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue