mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +00:00
support unordered set/map data structures (fixes #100)
This commit is contained in:
parent
4fee179900
commit
0880294924
@ -222,45 +222,49 @@ The following basic data types are supported out of the box (some may require
|
||||
an additional extension header to be included). To pass other data structures
|
||||
as arguments and return values, refer to the section on binding :ref:`classes`.
|
||||
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| Data type | Description | Header file |
|
||||
+========================+==========================+=======================+
|
||||
+============================+==========================+=======================+
|
||||
| int8_t, uint8_t | 8-bit integers | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| int16_t, uint16_t | 16-bit integers | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| int32_t, uint32_t | 32-bit integers | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| int64_t, uint64_t | 64-bit integers | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| ssize_t, size_t | Platform-dependent size | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| float, double | Floating point types | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| bool | Two-state Boolean type | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| char | Character literal | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| const char * | UTF-8 string literal | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::string | STL dynamic UTF-8 string | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::pair<T1, T2> | Pair of two custom types | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::tuple<....> | Arbitrary tuple of types | pybind11/pybind11.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::complex<T> | Complex numbers | pybind11/complex.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::array<T, Size> | STL static array | pybind11/stl.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::vector<T> | STL dynamic array | pybind11/stl.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::map<T1, T2> | STL ordered map | pybind11/stl.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::unordered_map<T1, T2> | STL unordered map | pybind11/stl.h |
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::set<T> | STL ordered set | pybind11/stl.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::unordered_set<T> | STL unordered set | pybind11/stl.h |
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
| std::function<...> | STL polymorphic function | pybind11/functional.h |
|
||||
+------------------------+--------------------------+-----------------------+
|
||||
+----------------------------+--------------------------+-----------------------+
|
||||
|
||||
|
||||
.. [#f1] In practice, implementation and binding code will generally be located
|
||||
|
@ -10,8 +10,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <iostream>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
@ -22,77 +24,10 @@
|
||||
NAMESPACE_BEGIN(pybind11)
|
||||
NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename Type, typename Alloc> struct type_caster<std::vector<Type, Alloc>> {
|
||||
typedef std::vector<Type, Alloc> vector_type;
|
||||
typedef type_caster<Type> value_conv;
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
list l(src, true);
|
||||
if (!l.check())
|
||||
return false;
|
||||
value.reserve(l.size());
|
||||
value.clear();
|
||||
value_conv conv;
|
||||
for (auto it : l) {
|
||||
if (!conv.load(it, convert))
|
||||
return false;
|
||||
value.push_back((Type) conv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const vector_type &src, return_value_policy policy, handle parent) {
|
||||
list l(src.size());
|
||||
size_t index = 0;
|
||||
for (auto const &value: src) {
|
||||
object value_ = object(value_conv::cast(value, policy, parent), false);
|
||||
if (!value_)
|
||||
return handle();
|
||||
PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
|
||||
}
|
||||
return l.release();
|
||||
}
|
||||
PYBIND11_TYPE_CASTER(vector_type, _("list<") + value_conv::name() + _(">"));
|
||||
};
|
||||
|
||||
template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>> {
|
||||
typedef std::array<Type, Size> array_type;
|
||||
typedef type_caster<Type> value_conv;
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
list l(src, true);
|
||||
if (!l.check())
|
||||
return false;
|
||||
if (l.size() != Size)
|
||||
return false;
|
||||
value_conv conv;
|
||||
size_t ctr = 0;
|
||||
for (auto it : l) {
|
||||
if (!conv.load(it, convert))
|
||||
return false;
|
||||
value[ctr++] = (Type) conv;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const array_type &src, return_value_policy policy, handle parent) {
|
||||
list l(Size);
|
||||
size_t index = 0;
|
||||
for (auto const &value: src) {
|
||||
object value_ = object(value_conv::cast(value, policy, parent), false);
|
||||
if (!value_)
|
||||
return handle();
|
||||
PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
|
||||
}
|
||||
return l.release();
|
||||
}
|
||||
PYBIND11_TYPE_CASTER(array_type, _("list<") + value_conv::name() + _(">") + _("[") + _<Size>() + _("]"));
|
||||
};
|
||||
|
||||
template <typename Key, typename Compare, typename Alloc> struct type_caster<std::set<Key, Compare, Alloc>> {
|
||||
typedef std::set<Key, Compare, Alloc> type;
|
||||
template <typename Type, typename Key> struct set_caster {
|
||||
typedef Type type;
|
||||
typedef type_caster<Key> key_conv;
|
||||
public:
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
pybind11::set s(src, true);
|
||||
if (!s.check())
|
||||
@ -116,12 +51,12 @@ public:
|
||||
}
|
||||
return s.release();
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(type, _("set<") + key_conv::name() + _(">"));
|
||||
};
|
||||
|
||||
template <typename Key, typename Value, typename Compare, typename Alloc> struct type_caster<std::map<Key, Value, Compare, Alloc>> {
|
||||
public:
|
||||
typedef std::map<Key, Value, Compare, Alloc> type;
|
||||
template <typename Type, typename Key, typename Value> struct map_caster {
|
||||
typedef Type type;
|
||||
typedef type_caster<Key> key_conv;
|
||||
typedef type_caster<Value> value_conv;
|
||||
|
||||
@ -156,6 +91,85 @@ public:
|
||||
PYBIND11_TYPE_CASTER(type, _("dict<") + key_conv::name() + _(", ") + value_conv::name() + _(">"));
|
||||
};
|
||||
|
||||
template <typename Type, typename Alloc> struct type_caster<std::vector<Type, Alloc>> {
|
||||
typedef std::vector<Type, Alloc> vector_type;
|
||||
typedef type_caster<Type> value_conv;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
list l(src, true);
|
||||
if (!l.check())
|
||||
return false;
|
||||
value.reserve(l.size());
|
||||
value.clear();
|
||||
value_conv conv;
|
||||
for (auto it : l) {
|
||||
if (!conv.load(it, convert))
|
||||
return false;
|
||||
value.push_back((Type) conv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const vector_type &src, return_value_policy policy, handle parent) {
|
||||
list l(src.size());
|
||||
size_t index = 0;
|
||||
for (auto const &value: src) {
|
||||
object value_ = object(value_conv::cast(value, policy, parent), false);
|
||||
if (!value_)
|
||||
return handle();
|
||||
PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
|
||||
}
|
||||
return l.release();
|
||||
}
|
||||
PYBIND11_TYPE_CASTER(vector_type, _("list<") + value_conv::name() + _(">"));
|
||||
};
|
||||
|
||||
template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>> {
|
||||
typedef std::array<Type, Size> array_type;
|
||||
typedef type_caster<Type> value_conv;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
list l(src, true);
|
||||
if (!l.check())
|
||||
return false;
|
||||
if (l.size() != Size)
|
||||
return false;
|
||||
value_conv conv;
|
||||
size_t ctr = 0;
|
||||
for (auto it : l) {
|
||||
if (!conv.load(it, convert))
|
||||
return false;
|
||||
value[ctr++] = (Type) conv;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const array_type &src, return_value_policy policy, handle parent) {
|
||||
list l(Size);
|
||||
size_t index = 0;
|
||||
for (auto const &value: src) {
|
||||
object value_ = object(value_conv::cast(value, policy, parent), false);
|
||||
if (!value_)
|
||||
return handle();
|
||||
PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
|
||||
}
|
||||
return l.release();
|
||||
}
|
||||
PYBIND11_TYPE_CASTER(array_type, _("list<") + value_conv::name() + _(">") + _("[") + _<Size>() + _("]"));
|
||||
};
|
||||
|
||||
template <typename Key, typename Compare, typename Alloc> struct type_caster<std::set<Key, Compare, Alloc>>
|
||||
: set_caster<std::set<Key, Compare, Alloc>, Key> { };
|
||||
|
||||
template <typename Key, typename Hash, typename Equal, typename Alloc> struct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>
|
||||
: set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> { };
|
||||
|
||||
template <typename Key, typename Value, typename Compare, typename Alloc> struct type_caster<std::map<Key, Value, Compare, Alloc>>
|
||||
: map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> { };
|
||||
|
||||
template <typename Key, typename Value, typename Hash, typename Equal, typename Alloc> struct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>
|
||||
: map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> { };
|
||||
|
||||
NAMESPACE_END(detail)
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
|
||||
|
Loading…
Reference in New Issue
Block a user