nicer code separation, cleanup logic, std::function type caster
diff --git a/include/pybind/cast.h b/include/pybind/cast.h
index 3013047..c59fbcf 100644
--- a/include/pybind/cast.h
+++ b/include/pybind/cast.h
@@ -12,7 +12,6 @@
#include <pybind/pytypes.h>
#include <pybind/typeid.h>
-#include <map>
#include <array>
NAMESPACE_BEGIN(pybind)
@@ -167,14 +166,14 @@
PYBIND_TYPE_CASTER_NUMBER(float, float, PyFloat_AsDouble, PyFloat_FromDouble)
PYBIND_TYPE_CASTER_NUMBER(double, double, PyFloat_AsDouble, PyFloat_FromDouble)
-template <> class type_caster<detail::void_type> {
+template <> class type_caster<void_type> {
public:
bool load(PyObject *, bool) { return true; }
- static PyObject *cast(detail::void_type, return_value_policy /* policy */, PyObject * /* parent */) {
+ static PyObject *cast(void_type, return_value_policy /* policy */, PyObject * /* parent */) {
Py_INCREF(Py_None);
return Py_None;
}
- PYBIND_TYPE_CASTER(detail::void_type, "None");
+ PYBIND_TYPE_CASTER(void_type, "None");
};
template <> class type_caster<bool> {
@@ -192,23 +191,6 @@
PYBIND_TYPE_CASTER(bool, "bool");
};
-template <typename T> class type_caster<std::complex<T>> {
-public:
- bool load(PyObject *src, bool) {
- Py_complex result = PyComplex_AsCComplex(src);
- if (result.real == -1.0 && PyErr_Occurred()) {
- PyErr_Clear();
- return false;
- }
- value = std::complex<T>((T) result.real, (T) result.imag);
- return true;
- }
- static PyObject *cast(const std::complex<T> &src, return_value_policy /* policy */, PyObject * /* parent */) {
- return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
- }
- PYBIND_TYPE_CASTER(std::complex<T>, "complex");
-};
-
template <> class type_caster<std::string> {
public:
bool load(PyObject *src, bool) {
@@ -265,83 +247,6 @@
char *value;
};
-template <typename Value> struct type_caster<std::vector<Value>> {
- typedef std::vector<Value> type;
- typedef type_caster<Value> value_conv;
-public:
- bool load(PyObject *src, bool convert) {
- if (!PyList_Check(src))
- return false;
- size_t size = (size_t) PyList_GET_SIZE(src);
- value.reserve(size);
- value.clear();
- for (size_t i=0; i<size; ++i) {
- value_conv conv;
- if (!conv.load(PyList_GetItem(src, (ssize_t) i), convert))
- return false;
- value.push_back((Value) conv);
- }
- return true;
- }
-
- static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) {
- PyObject *list = PyList_New(src.size());
- size_t index = 0;
- for (auto const &value: src) {
- PyObject *value_ = value_conv::cast(value, policy, parent);
- if (!value_) {
- Py_DECREF(list);
- return nullptr;
- }
- PyList_SetItem(list, index++, value_);
- }
- return list;
- }
- PYBIND_TYPE_CASTER(type, "list<" + value_conv::name() + ">");
-};
-
-template <typename Key, typename Value> struct type_caster<std::map<Key, Value>> {
-public:
- typedef std::map<Key, Value> type;
- typedef type_caster<Key> key_conv;
- typedef type_caster<Value> value_conv;
-
- bool load(PyObject *src, bool convert) {
- if (!PyDict_Check(src))
- return false;
-
- value.clear();
- PyObject *key_, *value_;
- ssize_t pos = 0;
- key_conv kconv;
- value_conv vconv;
- while (PyDict_Next(src, &pos, &key_, &value_)) {
- if (!kconv.load(key_, convert) || !vconv.load(value_, convert))
- return false;
- value[kconv] = vconv;
- }
- return true;
- }
-
- static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) {
- PyObject *dict = PyDict_New();
- for (auto const &kv: src) {
- PyObject *key = key_conv::cast(kv.first, policy, parent);
- PyObject *value = value_conv::cast(kv.second, policy, parent);
- if (!key || !value || PyDict_SetItem(dict, key, value) < 0) {
- Py_XDECREF(key);
- Py_XDECREF(value);
- Py_DECREF(dict);
- return nullptr;
- }
- Py_DECREF(key);
- Py_DECREF(value);
- }
- return dict;
- }
- PYBIND_TYPE_CASTER(type, "dict<" + key_conv::name() + ", " + value_conv::name() + ">");
-};
-
template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
typedef std::pair<T1, T2> type;
public:
@@ -354,8 +259,8 @@
}
static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) {
- PyObject *o1 = type_caster<typename detail::decay<T1>::type>::cast(src.first, policy, parent);
- PyObject *o2 = type_caster<typename detail::decay<T2>::type>::cast(src.second, policy, parent);
+ PyObject *o1 = type_caster<typename decay<T1>::type>::cast(src.first, policy, parent);
+ PyObject *o2 = type_caster<typename decay<T2>::type>::cast(src.second, policy, parent);
if (!o1 || !o2) {
Py_XDECREF(o1);
Py_XDECREF(o2);
@@ -375,11 +280,11 @@
return type(first, second);
}
protected:
- type_caster<typename detail::decay<T1>::type> first;
- type_caster<typename detail::decay<T2>::type> second;
+ type_caster<typename decay<T1>::type> first;
+ type_caster<typename decay<T2>::type> second;
};
-template <typename ... Tuple> class type_caster<std::tuple<Tuple...>> {
+template <typename... Tuple> class type_caster<std::tuple<Tuple...>> {
typedef std::tuple<Tuple...> type;
public:
enum { size = sizeof...(Tuple) };
@@ -394,7 +299,7 @@
static std::string name(const char **keywords = nullptr, const char **values = nullptr) {
std::array<std::string, size> names {{
- type_caster<typename detail::decay<Tuple>::type>::name()...
+ type_caster<typename decay<Tuple>::type>::name()...
}};
std::string result("(");
int counter = 0;
@@ -419,9 +324,9 @@
return call<ReturnValue>(std::forward<Func>(f), typename make_index_sequence<sizeof...(Tuple)>::type());
}
- template <typename ReturnValue, typename Func> typename std::enable_if<std::is_void<ReturnValue>::value, detail::void_type>::type call(Func &&f) {
+ template <typename ReturnValue, typename Func> typename std::enable_if<std::is_void<ReturnValue>::value, void_type>::type call(Func &&f) {
call<ReturnValue>(std::forward<Func>(f), typename make_index_sequence<sizeof...(Tuple)>::type());
- return detail::void_type();
+ return void_type();
}
operator type() {
@@ -443,8 +348,9 @@
if (PyTuple_Size(src) != size)
return false;
std::array<bool, size> results {{
- std::get<Indices>(value).load(PyTuple_GetItem(src, Indices), convert)...
+ (PyTuple_GET_ITEM(src, Indices) != nullptr ? std::get<Indices>(value).load(PyTuple_GET_ITEM(src, Indices), convert) : false)...
}};
+ (void) convert; /* avoid a warning when the tuple is empty */
for (bool r : results)
if (!r)
return false;
@@ -454,7 +360,7 @@
/* Implementation: Convert a C++ tuple into a Python tuple */
template <size_t ... Indices> static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent, index_sequence<Indices...>) {
std::array<PyObject *, size> results {{
- type_caster<typename detail::decay<Tuple>::type>::cast(std::get<Indices>(src), policy, parent)...
+ type_caster<typename decay<Tuple>::type>::cast(std::get<Indices>(src), policy, parent)...
}};
bool success = true;
for (auto result : results)
@@ -475,7 +381,7 @@
}
protected:
- std::tuple<type_caster<typename detail::decay<Tuple>::type>...> value;
+ std::tuple<type_caster<typename decay<Tuple>::type>...> value;
};
/// Type caster for holder types like std::shared_ptr, etc.
@@ -542,7 +448,7 @@
template <typename T> inline T handle::cast() { return pybind::cast<T>(m_ptr); }
-template <typename ... Args> inline object handle::call(Args&&... args_) {
+template <typename... Args> inline object handle::call(Args&&... args_) {
const size_t size = sizeof...(Args);
std::array<PyObject *, size> args{
{ detail::type_caster<typename detail::decay<Args>::type>::cast(