diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index c9c0f36f2..456af7ebb 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -229,6 +229,13 @@ protected: operator type*() { return &value; } \ operator type&() { return value; } +#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type) \ + namespace pybind11 { namespace detail { \ + template class type_caster \ + : public type_caster_holder { }; \ + }} + + template struct type_caster< T, typename std::enable_if::value || @@ -250,9 +257,9 @@ public: py_value = (py_type) PyLong_AsUnsignedLong(src); } else { if (std::is_signed::value) - py_value = (py_type) detail::PyLong_AsLongLong(src); + py_value = (py_type) detail::PyLong_AsLongLong_(src); else - py_value = (py_type) detail::PyLong_AsUnsignedLongLong(src); + py_value = (py_type) detail::PyLong_AsUnsignedLongLong_(src); } if ((py_value == (py_type) -1 && PyErr_Occurred()) || @@ -556,42 +563,22 @@ protected: holder_type holder; }; -#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type) \ - namespace pybind11 { namespace detail { \ - template class type_caster \ - : public type_caster_holder { }; \ - }} - -template <> class type_caster { +template +struct type_caster::value>::type> { public: - bool load(PyObject *src) { - value = handle(src); - return true; - } + template ::value, int>::type = 0> + bool load(PyObject *src, bool /* convert */) { value = handle(src); return value.check(); } + + template ::value, int>::type = 0> + bool load(PyObject *src, bool /* convert */) { value = type(src, true); return value.check(); } + static PyObject *cast(const handle &src, return_value_policy /* policy */, PyObject * /* parent */) { src.inc_ref(); return (PyObject *) src.ptr(); } - PYBIND11_TYPE_CASTER(handle, "handle"); + PYBIND11_TYPE_CASTER(type, typeid(type)); }; -#define PYBIND11_TYPE_CASTER_PYTYPE(name) \ - template <> class type_caster { \ - public: \ - bool load(PyObject *src, bool) { value = name(src, true); return true; } \ - static PyObject *cast(const name &src, return_value_policy /* policy */, PyObject * /* parent */) { \ - src.inc_ref(); return (PyObject *) src.ptr(); \ - } \ - PYBIND11_TYPE_CASTER(name, #name); \ - }; - -PYBIND11_TYPE_CASTER_PYTYPE(object) PYBIND11_TYPE_CASTER_PYTYPE(buffer) -PYBIND11_TYPE_CASTER_PYTYPE(capsule) PYBIND11_TYPE_CASTER_PYTYPE(dict) -PYBIND11_TYPE_CASTER_PYTYPE(float_) PYBIND11_TYPE_CASTER_PYTYPE(int_) -PYBIND11_TYPE_CASTER_PYTYPE(list) PYBIND11_TYPE_CASTER_PYTYPE(slice) -PYBIND11_TYPE_CASTER_PYTYPE(tuple) PYBIND11_TYPE_CASTER_PYTYPE(function) -PYBIND11_TYPE_CASTER_PYTYPE(set) PYBIND11_TYPE_CASTER_PYTYPE(iterator) - NAMESPACE_END(detail) template inline T cast(PyObject *object) { diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index d3d8e1030..d1196e074 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -148,17 +148,7 @@ DECL_FMT(double, NPY_DOUBLE); DECL_FMT(bool, NPY_BOOL); DECL_FMT(std::complex, NPY_CDOUBLE); #undef DECL_FMT - NAMESPACE_BEGIN(detail) -PYBIND11_TYPE_CASTER_PYTYPE(array) -PYBIND11_TYPE_CASTER_PYTYPE(array_t) PYBIND11_TYPE_CASTER_PYTYPE(array_t) -PYBIND11_TYPE_CASTER_PYTYPE(array_t) PYBIND11_TYPE_CASTER_PYTYPE(array_t) -PYBIND11_TYPE_CASTER_PYTYPE(array_t) PYBIND11_TYPE_CASTER_PYTYPE(array_t) -PYBIND11_TYPE_CASTER_PYTYPE(array_t) PYBIND11_TYPE_CASTER_PYTYPE(array_t) -PYBIND11_TYPE_CASTER_PYTYPE(array_t) PYBIND11_TYPE_CASTER_PYTYPE(array_t) -PYBIND11_TYPE_CASTER_PYTYPE(array_t>) -PYBIND11_TYPE_CASTER_PYTYPE(array_t>) -PYBIND11_TYPE_CASTER_PYTYPE(array_t) template struct vectorize_helper { diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index b7f42dc4c..01776d7eb 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -45,6 +45,7 @@ public: template T cast(); template object call(Args&&... args_); operator bool() const { return m_ptr != nullptr; } + bool check() const { return m_ptr != nullptr; } protected: PyObject *m_ptr; }; @@ -211,21 +212,26 @@ private: }; #if PY_MAJOR_VERSION >= 3 -using ::PyLong_AsUnsignedLongLong; -using ::PyLong_AsLongLong; +inline long long PyLong_AsLongLong_(PyObject *o) { return PyLong_AsLongLong(o); } +inline unsigned long long PyLong_AsUnsignedLongLong_(PyObject *o) { return PyLong_AsUnsignedLongLong(o); } +inline bool PyLong_Check_(PyObject *o) { return PyLong_Check(o); } #else -inline long long PyLong_AsLongLong(PyObject *o) { +inline long long PyLong_AsLongLong_(PyObject *o) { if (PyInt_Check(o)) /// workaround: PyLong_AsLongLong doesn't accept 'int' on Python 2.x return (long long) PyLong_AsLong(o); else - return ::PyLong_AsLongLong(o); + return PyLong_AsLongLong(o); } -inline unsigned long long PyLong_AsUnsignedLongLong(PyObject *o) { +inline unsigned long long PyLong_AsUnsignedLongLong_(PyObject *o) { if (PyInt_Check(o)) /// workaround: PyLong_AsUnsignedLongLong doesn't accept 'int' on Python 2.x return (unsigned long long) PyLong_AsUnsignedLong(o); else - return ::PyLong_AsUnsignedLongLong(o); + return PyLong_AsUnsignedLongLong(o); +} + +inline bool PyLong_Check_(PyObject *o) { + return PyInt_Check(o) || PyLong_Check(o); } #endif @@ -291,7 +297,7 @@ public: class int_ : public object { public: - PYBIND11_OBJECT_DEFAULT(int_, object, PyLong_Check) + PYBIND11_OBJECT_DEFAULT(int_, object, detail::PyLong_Check_) template ::value, int>::type = 0> int_(T value) { @@ -318,9 +324,9 @@ public: return (T) PyLong_AsUnsignedLong(m_ptr); } else { if (std::is_signed::value) - return (T) detail::PyLong_AsLongLong(m_ptr); + return (T) detail::PyLong_AsLongLong_(m_ptr); else - return (T) detail::PyLong_AsUnsignedLongLong(m_ptr); + return (T) detail::PyLong_AsUnsignedLongLong_(m_ptr); } } };