mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +00:00
considerable simplifications to the Python type casters
This commit is contained in:
parent
9b0b40e0b0
commit
d1a24823bc
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user