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; }
#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>
struct type_caster<
T, typename std::enable_if<std::is_integral<T>::value ||
@ -250,9 +257,9 @@ public:
py_value = (py_type) PyLong_AsUnsignedLong(src);
} else {
if (std::is_signed<T>::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 <typename type> class type_caster<holder_type> \
: public type_caster_holder<type, holder_type> { }; \
}}
template <> class type_caster<handle> {
template <typename type>
struct type_caster<type, typename std::enable_if<std::is_base_of<handle, type>::value>::type> {
public:
bool load(PyObject *src) {
value = handle(src);
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 = handle(src); return value.check(); }
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 */) {
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<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)
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);
#undef DECL_FMT
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>
struct vectorize_helper {

View File

@ -45,6 +45,7 @@ public:
template <typename T> T cast();
template <typename ... Args> 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 <typename T,
typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
int_(T value) {
@ -318,9 +324,9 @@ public:
return (T) PyLong_AsUnsignedLong(m_ptr);
} else {
if (std::is_signed<T>::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);
}
}
};