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_);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -54,6 +54,7 @@ struct GlobalFunction: public FullyOverloadedFunction {
|
|||
// emit cython wrapper
|
||||
void emit_cython_pxd(FileWriter& pxdFile) const;
|
||||
void emit_cython_pyx(FileWriter& pyxFile) const;
|
||||
void emit_cython_pyx_no_overload(FileWriter& pyxFile) const;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -71,20 +71,22 @@ public:
|
|||
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;
|
||||
s += "\t\tif len(args)+len(kwargs) !=" + std::to_string(args.size()) + ":\n";
|
||||
s += "\t\t\treturn False";
|
||||
s += indent + "if len(args)+len(kwargs) !=" + std::to_string(args.size()) + ":\n";
|
||||
s += indent + "\treturn False";
|
||||
s += (!isVoid) ? ", None\n" : "\n";
|
||||
if (args.size() > 0) {
|
||||
s += "\t\t__params = kwargs.copy()\n";
|
||||
s += "\t\t__names = [" + args.pyx_paramsList() + "]\n";
|
||||
s += "\t\tfor i in range(len(args)):\n";
|
||||
s += "\t\t\t__params[__names[i]] = args[i]\n";
|
||||
s += "\t\ttry:\n";
|
||||
s += indent + "__params = kwargs.copy()\n";
|
||||
s += indent + "__names = [" + args.pyx_paramsList() + "]\n";
|
||||
s += indent + "for i in range(len(args)):\n";
|
||||
s += indent + "\t__params[__names[i]] = args[i]\n";
|
||||
s += indent + "try:\n";
|
||||
s += args.pyx_castParamsToPythonType();
|
||||
s += "\t\texcept:\n";
|
||||
s += "\t\t\treturn False";
|
||||
s += indent + "except:\n";
|
||||
s += indent + "\treturn False";
|
||||
s += (!isVoid) ? ", None\n" : "\n";
|
||||
}
|
||||
return s;
|
||||
|
@ -92,7 +94,9 @@ public:
|
|||
|
||||
/// if two overloading methods have the same number of arguments, they have
|
||||
/// 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::vector<size_t> nargsDuplicates;
|
||||
for (size_t i = 0; i < nrOverloads(); ++i) {
|
||||
|
@ -105,13 +109,13 @@ public:
|
|||
|
||||
std::string s;
|
||||
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) {
|
||||
s += std::to_string(nargsDuplicates[i]);
|
||||
if (i < nargsDuplicates.size() - 1) s += ",";
|
||||
}
|
||||
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 "
|
||||
"differentiate them!')\n";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue