Skip to content

Revert noexcept deduction in favour of SFINAE lambda function matching #677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 6 additions & 17 deletions include/pybind11/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,17 +202,6 @@ extern "C" {
} \
PyObject *pybind11_init()

// Function return value and argument type deduction support. When compiling under C++17 these
// differ as C++17 makes the noexcept specifier part of the function type, while it is not part of
// the type under earlier standards.
#ifdef __cpp_noexcept_function_type
# define PYBIND11_NOEXCEPT_TPL_ARG , bool NoExceptions
# define PYBIND11_NOEXCEPT_SPECIFIER noexcept(NoExceptions)
#else
# define PYBIND11_NOEXCEPT_TPL_ARG
# define PYBIND11_NOEXCEPT_SPECIFIER
#endif

NAMESPACE_BEGIN(pybind11)

using ssize_t = Py_ssize_t;
Expand Down Expand Up @@ -643,16 +632,16 @@ struct nodelete { template <typename T> void operator()(T*) { } };
NAMESPACE_BEGIN(detail)
template <typename... Args>
struct overload_cast_impl {
template <typename Return /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
constexpr auto operator()(Return (*pf)(Args...) PYBIND11_NOEXCEPT_SPECIFIER) const noexcept
template <typename Return>
constexpr auto operator()(Return (*pf)(Args...)) const noexcept
-> decltype(pf) { return pf; }

template <typename Return, typename Class /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
constexpr auto operator()(Return (Class::*pmf)(Args...) PYBIND11_NOEXCEPT_SPECIFIER, std::false_type = {}) const noexcept
template <typename Return, typename Class>
constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept
-> decltype(pmf) { return pmf; }

template <typename Return, typename Class /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
constexpr auto operator()(Return (Class::*pmf)(Args...) const PYBIND11_NOEXCEPT_SPECIFIER, std::true_type) const noexcept
template <typename Return, typename Class>
constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept
-> decltype(pmf) { return pmf; }
};
NAMESPACE_END(detail)
Expand Down
8 changes: 4 additions & 4 deletions include/pybind11/functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
NAMESPACE_BEGIN(pybind11)
NAMESPACE_BEGIN(detail)

template <typename Return, typename... Args /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
struct type_caster<std::function<Return(Args...) PYBIND11_NOEXCEPT_SPECIFIER>> {
using type = std::function<Return(Args...) PYBIND11_NOEXCEPT_SPECIFIER>;
template <typename Return, typename... Args>
struct type_caster<std::function<Return(Args...)>> {
using type = std::function<Return(Args...)>;
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
using function_type = Return (*) (Args...) PYBIND11_NOEXCEPT_SPECIFIER;
using function_type = Return (*) (Args...);

public:
bool load(handle src_, bool) {
Expand Down
17 changes: 8 additions & 9 deletions include/pybind11/numpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -1140,23 +1140,22 @@ template <typename T, int Flags> struct handle_type_name<array_t<T, Flags>> {

NAMESPACE_END(detail)

template <typename Func, typename Return, typename... Args /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
template <typename Func, typename Return, typename... Args>
detail::vectorize_helper<Func, Return, Args...>
vectorize(const Func &f, Return (*) (Args ...) PYBIND11_NOEXCEPT_SPECIFIER) {
vectorize(const Func &f, Return (*) (Args ...)) {
return detail::vectorize_helper<Func, Return, Args...>(f);
}

template <typename Return, typename... Args /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
detail::vectorize_helper<Return (*) (Args ...) PYBIND11_NOEXCEPT_SPECIFIER, Return, Args...>
vectorize(Return (*f) (Args ...) PYBIND11_NOEXCEPT_SPECIFIER) {
template <typename Return, typename... Args>
detail::vectorize_helper<Return (*) (Args ...), Return, Args...>
vectorize(Return (*f) (Args ...)) {
return vectorize<Return (*) (Args ...), Return, Args...>(f, f);
}

template <typename Func>
template <typename Func, typename FuncType = typename detail::remove_class<decltype(&std::remove_reference<Func>::type::operator())>::type>
auto vectorize(Func &&f) -> decltype(
vectorize(std::forward<Func>(f), (typename detail::remove_class<decltype(&std::remove_reference<Func>::type::operator())>::type *) nullptr)) {
return vectorize(std::forward<Func>(f), (typename detail::remove_class<decltype(
&std::remove_reference<Func>::type::operator())>::type *) nullptr);
vectorize(std::forward<Func>(f), (FuncType *) nullptr)) {
return vectorize(std::forward<Func>(f), (FuncType *) nullptr);
}

NAMESPACE_END(pybind11)
Expand Down
29 changes: 15 additions & 14 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,31 @@ class cpp_function : public function {
cpp_function() { }

/// Construct a cpp_function from a vanilla function pointer
template <typename Return, typename... Args, typename... Extra /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
cpp_function(Return (*f)(Args...) PYBIND11_NOEXCEPT_SPECIFIER, const Extra&... extra) {
template <typename Return, typename... Args, typename... Extra>
cpp_function(Return (*f)(Args...), const Extra&... extra) {
initialize(f, f, extra...);
}

/// Construct a cpp_function from a lambda function (possibly with internal state)
template <typename Func, typename... Extra> cpp_function(Func &&f, const Extra&... extra) {
template <typename Func, typename... Extra,
typename FuncType = typename detail::remove_class<decltype(&std::remove_reference<Func>::type::operator())>::type>
cpp_function(Func &&f, const Extra&... extra) {
initialize(std::forward<Func>(f),
(typename detail::remove_class<decltype(
&std::remove_reference<Func>::type::operator())>::type *) nullptr, extra...);
(FuncType *) nullptr, extra...);
}

/// Construct a cpp_function from a class method (non-const)
template <typename Return, typename Class, typename... Arg, typename... Extra /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
cpp_function(Return (Class::*f)(Arg...) PYBIND11_NOEXCEPT_SPECIFIER, const Extra&... extra) {
template <typename Return, typename Class, typename... Arg, typename... Extra>
cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) {
initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); },
(Return (*) (Class *, Arg...) PYBIND11_NOEXCEPT_SPECIFIER) nullptr, extra...);
(Return (*) (Class *, Arg...)) nullptr, extra...);
}

/// Construct a cpp_function from a class method (const)
template <typename Return, typename Class, typename... Arg, typename... Extra /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
cpp_function(Return (Class::*f)(Arg...) const PYBIND11_NOEXCEPT_SPECIFIER, const Extra&... extra) {
template <typename Return, typename Class, typename... Arg, typename... Extra>
cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) {
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); },
(Return (*)(const Class *, Arg ...) PYBIND11_NOEXCEPT_SPECIFIER) nullptr, extra...);
(Return (*)(const Class *, Arg ...)) nullptr, extra...);
}

/// Return the function name
Expand All @@ -80,8 +81,8 @@ class cpp_function : public function {
}

/// Special internal constructor for functors, lambda functions, etc.
template <typename Func, typename Return, typename... Args, typename... Extra /*,*/ PYBIND11_NOEXCEPT_TPL_ARG>
void initialize(Func &&f, Return (*)(Args...) PYBIND11_NOEXCEPT_SPECIFIER, const Extra&... extra) {
template <typename Func, typename Return, typename... Args, typename... Extra>
void initialize(Func &&f, Return (*)(Args...), const Extra&... extra) {

struct capture { typename std::remove_reference<Func>::type f; };

Expand Down Expand Up @@ -162,7 +163,7 @@ class cpp_function : public function {
if (cast_in::has_kwargs) rec->has_kwargs = true;

/* Stash some additional information used by an important optimization in 'functional.h' */
using FunctionType = Return (*)(Args...) PYBIND11_NOEXCEPT_SPECIFIER;
using FunctionType = Return (*)(Args...);
constexpr bool is_function_ptr =
std::is_convertible<Func, FunctionType>::value &&
sizeof(capture) == sizeof(void *);
Expand Down