Skip to content

Commit

Permalink
[Delegator] Improve error messages when return types are missing
Browse files Browse the repository at this point in the history
  • Loading branch information
speth committed Jan 21, 2023
1 parent d484dfb commit a302610
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
31 changes: 23 additions & 8 deletions include/cantera/base/Delegator.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ namespace Cantera
class Delegator
{
public:
//! Get the name of the user-defined class in the extension language
std::string delegatorName() const {
return m_delegatorName;
}

//! Set the name of the user-defined class in the extension language
void setDelegatorName(const std::string& delegatorName) {
m_delegatorName = delegatorName;
}

//! Set delegates for member functions with the signature `void()`.
void setDelegate(const std::string& name, const std::function<void()>& func,
const std::string& when)
Expand Down Expand Up @@ -215,7 +225,7 @@ class Delegator
throw NotImplementedError("Delegator::setDelegate",
"for function named '{}' with signature 'double(void*)'.", name);
}
*m_funcs_d_vp[name] = makeDelegate(func, when, m_base_d_vp[name]);
*m_funcs_d_vp[name] = makeDelegate(name, func, when, m_base_d_vp[name]);
}

//! Set delegates for member functions with the signature `string(size_t)`
Expand All @@ -228,7 +238,7 @@ class Delegator
"for function named '{}' with signature "
"'string(size_t)'.", name);
}
*m_funcs_s_sz[name] = makeDelegate(func, when, m_base_s_sz[name]);
*m_funcs_s_sz[name] = makeDelegate(name, func, when, m_base_s_sz[name]);
}

//! Set delegates for member functions with the signature `size_t(string)`
Expand All @@ -238,10 +248,10 @@ class Delegator
{
if (!m_funcs_sz_csr.count(name)) {
throw NotImplementedError("Delegator::setDelegate",
"for function named '{}' with signature "
"for function '{}' with signature "
"'size_t(const string&)'.", name);
}
*m_funcs_sz_csr[name] = makeDelegate(func, when, m_base_sz_csr[name]);
*m_funcs_sz_csr[name] = makeDelegate(name, func, when, m_base_sz_csr[name]);
}

void holdExternalHandle(const shared_ptr<ExternalHandle>& handle) {
Expand Down Expand Up @@ -382,6 +392,7 @@ class Delegator
//! Create a delegate for a function with a return value
template <typename ReturnType, class ... Args>
std::function<ReturnType(Args ...)> makeDelegate(
const std::string& name,
const std::function<int(ReturnType&, Args ...)>& func,
const std::string& when,
const std::function<ReturnType(Args ...)>& base)
Expand Down Expand Up @@ -413,20 +424,21 @@ class Delegator
}
};
} else if (when == "replace") {
return [base, func](Args ... args) {
return [base, name, func, this](Args ... args) {
ReturnType ret;
int has_ret = func(ret, args ...);
if (!has_ret) {
throw CanteraError("Lambda generated by Delegator::makeDelegate",
"Delegate for function of type '{}'\ndid not return a value",
demangle(typeid(base)));
"Method '{}' of class '{}' did not return a value of type '{}'.",
name, delegatorName(), demangle(typeid(ret)));
}
return ret;
};
} else {
throw CanteraError("Delegator::makeDelegate",
"For function named '{}':\n"
"'when' must be one of 'before', 'after', or 'replace';"
" not '{}", when);
" not '{}'", name, when);
}
}

Expand Down Expand Up @@ -486,6 +498,9 @@ class Delegator

//! Cleanup functions to be called from the destructor
std::list<shared_ptr<ExternalHandle>> m_handles;

//! Name of the class in the extension language
std::string m_delegatorName;
};

}
Expand Down
2 changes: 2 additions & 0 deletions interfaces/cython/cantera/delegator.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ cdef extern from "cantera/base/Delegator.h" namespace "Cantera":
cdef cppclass CxxDelegator "Cantera::Delegator":
Delegator()

void setDelegatorName(string&)

void setDelegate(string&, function[void()], string&) except +translate_exception
void setDelegate(string&, function[void(cbool)], string&) except +translate_exception
void setDelegate(string&, function[void(double)], string&) except +translate_exception
Expand Down
2 changes: 2 additions & 0 deletions interfaces/cython/cantera/delegator.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ cdef int assign_delegates(obj, CxxDelegator* delegator) except -1:
if present, indicates that the delegate is required, how it is executed with
respect to the base class method (that is, ``before``, ``after``, or ``replace``).
"""
delegator.setDelegatorName(stringify(obj.__class__.__name__))

# Find all delegate methods, and make sure there aren't multiple
# conflicting implementations
cdef string cxx_name
Expand Down

0 comments on commit a302610

Please sign in to comment.