considerable simplifications to the Python type casters

This commit is contained in:
Wenzel Jakob 2015-12-16 12:11:01 +01:00
parent 9b0b40e0b0
commit d1a24823bc
3 changed files with 33 additions and 50 deletions

View File

@ -229,6 +229,13 @@ protected:
operator type*() { return &value; } \ operator type*() { return &value; } \
operator type&() { return value; } operator type&() { return value; }
#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type) \
namespace pybind11 { namespace detail { \
template <typename type> class type_caster<holder_type> \
: public type_caster_holder<type, holder_type> { }; \
}}
template <typename T> template <typename T>
struct type_caster< struct type_caster<
T, typename std::enable_if<std::is_integral<T>::value || T, typename std::enable_if<std::is_integral<T>::value ||
@ -250,9 +257,9 @@ public:
py_value = (py_type) PyLong_AsUnsignedLong(src); py_value = (py_type) PyLong_AsUnsignedLong(src);
} else { } else {
if (std::is_signed<T>::value) if (std::is_signed<T>::value)
py_value = (py_type) detail::PyLong_AsLongLong(src); py_value = (py_type) detail::PyLong_AsLongLong_(src);
else 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()) || if ((py_value == (py_type) -1 && PyErr_Occurred()) ||
@ -556,42 +563,22 @@ protected:
holder_type holder; holder_type holder;
}; };
#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type) \ template <typename type>
namespace pybind11 { namespace detail { \ struct type_caster<type, typename std::enable_if<std::is_base_of<handle, type>::value>::type> {
template <typename type> class type_caster<holder_type> \
: public type_caster_holder<type, holder_type> { }; \
}}
template <> class type_caster<handle> {
public: public:
bool load(PyObject *src) { template <typename T = type, typename std::enable_if<std::is_same<T, handle>::value, int>::type = 0>
value = handle(src); bool load(PyObject *src, bool /* convert */) { value = handle(src); return value.check(); }
return true;
} template <typename T = type, typename std::enable_if<!std::is_same<T, handle>::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 */) { static PyObject *cast(const handle &src, return_value_policy /* policy */, PyObject * /* parent */) {
src.inc_ref(); src.inc_ref();
return (PyObject *) src.ptr(); 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<name> { \
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) NAMESPACE_END(detail)
template <typename T> inline T cast(PyObject *object) { template <typename T> inline T cast(PyObject *object) {

View File

@ -148,17 +148,7 @@ DECL_FMT(double, NPY_DOUBLE); DECL_FMT(bool, NPY_BOOL); DECL_FMT(std::complex<fl
DECL_FMT(std::complex<double>, NPY_CDOUBLE); DECL_FMT(std::complex<double>, NPY_CDOUBLE);
#undef DECL_FMT #undef DECL_FMT
NAMESPACE_BEGIN(detail) NAMESPACE_BEGIN(detail)
PYBIND11_TYPE_CASTER_PYTYPE(array)
PYBIND11_TYPE_CASTER_PYTYPE(array_t<int8_t>) PYBIND11_TYPE_CASTER_PYTYPE(array_t<uint8_t>)
PYBIND11_TYPE_CASTER_PYTYPE(array_t<int16_t>) PYBIND11_TYPE_CASTER_PYTYPE(array_t<uint16_t>)
PYBIND11_TYPE_CASTER_PYTYPE(array_t<int32_t>) PYBIND11_TYPE_CASTER_PYTYPE(array_t<uint32_t>)
PYBIND11_TYPE_CASTER_PYTYPE(array_t<int64_t>) PYBIND11_TYPE_CASTER_PYTYPE(array_t<uint64_t>)
PYBIND11_TYPE_CASTER_PYTYPE(array_t<float>) PYBIND11_TYPE_CASTER_PYTYPE(array_t<double>)
PYBIND11_TYPE_CASTER_PYTYPE(array_t<std::complex<float>>)
PYBIND11_TYPE_CASTER_PYTYPE(array_t<std::complex<double>>)
PYBIND11_TYPE_CASTER_PYTYPE(array_t<bool>)
template <typename Func, typename Return, typename... Args> template <typename Func, typename Return, typename... Args>
struct vectorize_helper { struct vectorize_helper {

View File

@ -45,6 +45,7 @@ public:
template <typename T> T cast(); template <typename T> T cast();
template <typename ... Args> object call(Args&&... args_); template <typename ... Args> object call(Args&&... args_);
operator bool() const { return m_ptr != nullptr; } operator bool() const { return m_ptr != nullptr; }
bool check() const { return m_ptr != nullptr; }
protected: protected:
PyObject *m_ptr; PyObject *m_ptr;
}; };
@ -211,21 +212,26 @@ private:
}; };
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
using ::PyLong_AsUnsignedLongLong; inline long long PyLong_AsLongLong_(PyObject *o) { return PyLong_AsLongLong(o); }
using ::PyLong_AsLongLong; inline unsigned long long PyLong_AsUnsignedLongLong_(PyObject *o) { return PyLong_AsUnsignedLongLong(o); }
inline bool PyLong_Check_(PyObject *o) { return PyLong_Check(o); }
#else #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 if (PyInt_Check(o)) /// workaround: PyLong_AsLongLong doesn't accept 'int' on Python 2.x
return (long long) PyLong_AsLong(o); return (long long) PyLong_AsLong(o);
else 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 if (PyInt_Check(o)) /// workaround: PyLong_AsUnsignedLongLong doesn't accept 'int' on Python 2.x
return (unsigned long long) PyLong_AsUnsignedLong(o); return (unsigned long long) PyLong_AsUnsignedLong(o);
else else
return ::PyLong_AsUnsignedLongLong(o); return PyLong_AsUnsignedLongLong(o);
}
inline bool PyLong_Check_(PyObject *o) {
return PyInt_Check(o) || PyLong_Check(o);
} }
#endif #endif
@ -291,7 +297,7 @@ public:
class int_ : public object { class int_ : public object {
public: public:
PYBIND11_OBJECT_DEFAULT(int_, object, PyLong_Check) PYBIND11_OBJECT_DEFAULT(int_, object, detail::PyLong_Check_)
template <typename T, template <typename T,
typename std::enable_if<std::is_integral<T>::value, int>::type = 0> typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
int_(T value) { int_(T value) {
@ -318,9 +324,9 @@ public:
return (T) PyLong_AsUnsignedLong(m_ptr); return (T) PyLong_AsUnsignedLong(m_ptr);
} else { } else {
if (std::is_signed<T>::value) if (std::is_signed<T>::value)
return (T) detail::PyLong_AsLongLong(m_ptr); return (T) detail::PyLong_AsLongLong_(m_ptr);
else else
return (T) detail::PyLong_AsUnsignedLongLong(m_ptr); return (T) detail::PyLong_AsUnsignedLongLong_(m_ptr);
} }
} }
}; };