diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index a5ee2c5f..5beb21ac 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -225,9 +225,6 @@ using cast_op_type = typename std::conditional::type>::type, typename std::add_lvalue_reference::type>::type>::type; -/// Thrown then trying to cast a null pointer into a reference argument -class invalid_reference_cast : public std::exception { }; - /// Generic type caster for objects stored on the heap template class type_caster_base : public type_caster_generic { public: @@ -256,7 +253,7 @@ public: template using cast_op_type = pybind11::detail::cast_op_type; operator type*() { return (type *) value; } - operator type&() { if (!value) throw invalid_reference_cast(); return *((type *) value); } + operator type&() { if (!value) throw cast_error(); return *((type *) value); } protected: typedef void *(*Constructor)(const void *stream); @@ -763,7 +760,7 @@ public: NAMESPACE_END(detail) -template inline T cast(handle handle) { +template T cast(handle handle) { typedef detail::type_caster::type> type_caster; type_caster conv; if (!conv.load(handle, true)) @@ -771,7 +768,7 @@ template inline T cast(handle handle) { return conv.operator typename type_caster::template cast_op_type(); } -template inline object cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference, handle parent = handle()) { +template object cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference, handle parent = handle()) { if (policy == return_value_policy::automatic) policy = std::is_pointer::value ? return_value_policy::take_ownership : return_value_policy::copy; else if (policy == return_value_policy::automatic_reference) @@ -779,11 +776,11 @@ template inline object cast(const T &value, return_value_policy pol return object(detail::type_caster::type>::cast(value, policy, parent), false); } -template inline T handle::cast() const { return pybind11::cast(*this); } +template T handle::cast() const { return pybind11::cast(*this); } template <> inline void handle::cast() const { return; } template inline tuple make_tuple(Args&&... args_) { + typename... Args> tuple make_tuple(Args&&... args_) { const size_t size = sizeof...(Args); std::array args { { object(detail::type_caster::type>::cast( @@ -799,7 +796,7 @@ template inline object handle::call(Args&&... args) const { +template object handle::call(Args&&... args) const { tuple args_tuple = pybind11::make_tuple(std::forward(args)...); object result(PyObject_CallObject(m_ptr, args_tuple.ptr()), false); if (!result) diff --git a/include/pybind11/common.h b/include/pybind11/common.h index a82bb0eb..abf764af 100644 --- a/include/pybind11/common.h +++ b/include/pybind11/common.h @@ -280,7 +280,7 @@ template struct make_index_sequence : make_index_sequence template struct make_index_sequence <0, S...> { typedef index_sequence type; }; /// Strip the class from a method type -template struct remove_class {}; +template struct remove_class { }; template struct remove_class { typedef R type(A...); }; template struct remove_class { typedef R type(A...); }; @@ -305,12 +305,18 @@ to_string(T value) { return std::to_string((int) value); } NAMESPACE_END(detail) +#define PYBIND11_RUNTIME_EXCEPTION(name) \ + class name : public std::runtime_error { public: \ + name(const std::string &w) : std::runtime_error(w) { }; \ + name(const char *s) : std::runtime_error(s) { }; \ + name() : std::runtime_error("") { } \ + }; + // C++ bindings of core Python exceptions -struct stop_iteration : public std::runtime_error { public: stop_iteration(const std::string &w="") : std::runtime_error(w) {} }; -struct index_error : public std::runtime_error { public: index_error(const std::string &w="") : std::runtime_error(w) {} }; -struct error_already_set : public std::runtime_error { public: error_already_set() : std::runtime_error(detail::error_string()) {} }; -/// Thrown when pybind11::cast or handle::call fail due to a type casting error -struct cast_error : public std::runtime_error { public: cast_error(const std::string &w = "") : std::runtime_error(w) {} }; +class error_already_set : public std::runtime_error { public: error_already_set() : std::runtime_error(detail::error_string()) {} }; +PYBIND11_RUNTIME_EXCEPTION(stop_iteration) +PYBIND11_RUNTIME_EXCEPTION(index_error) +PYBIND11_RUNTIME_EXCEPTION(cast_error) /// Thrown when pybind11::cast or handle::call fail due to a type casting error [[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } [[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index b0ae5580..c9b40b4b 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -413,7 +413,7 @@ protected: try { if (kwargs_consumed == nkwargs) result = it->impl(it, args_, parent); - } catch (detail::invalid_reference_cast &) { + } catch (cast_error &) { result = PYBIND11_TRY_NEXT_OVERLOAD; } diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 8e316304..82725ce4 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -126,7 +126,7 @@ public: return result; } - template inline T cast() const { return operator object().cast(); } + template T cast() const { return operator object().cast(); } operator bool() const { if (attr) {