mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15: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
|
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`.
|
as arguments and return values, refer to the section on binding :ref:`classes`.
|
||||||
|
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| Data type | Description | Header file |
|
| Data type | Description | Header file |
|
||||||
+========================+==========================+=======================+
|
+============================+==========================+=======================+
|
||||||
| int8_t, uint8_t | 8-bit integers | pybind11/pybind11.h |
|
| int8_t, uint8_t | 8-bit integers | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| int16_t, uint16_t | 16-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 |
|
| int32_t, uint32_t | 32-bit integers | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| int64_t, uint64_t | 64-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 |
|
| ssize_t, size_t | Platform-dependent size | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| float, double | Floating point types | pybind11/pybind11.h |
|
| float, double | Floating point types | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| bool | Two-state Boolean type | pybind11/pybind11.h |
|
| bool | Two-state Boolean type | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| char | Character literal | pybind11/pybind11.h |
|
| char | Character literal | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| const char * | UTF-8 string literal | pybind11/pybind11.h |
|
| const char * | UTF-8 string literal | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::string | STL dynamic UTF-8 string | 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::pair<T1, T2> | Pair of two custom types | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::tuple<....> | Arbitrary tuple of types | pybind11/pybind11.h |
|
| std::tuple<....> | Arbitrary tuple of types | pybind11/pybind11.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::complex<T> | Complex numbers | pybind11/complex.h |
|
| std::complex<T> | Complex numbers | pybind11/complex.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::array<T, Size> | STL static array | pybind11/stl.h |
|
| std::array<T, Size> | STL static array | pybind11/stl.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::vector<T> | STL dynamic array | pybind11/stl.h |
|
| std::vector<T> | STL dynamic array | pybind11/stl.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::map<T1, T2> | STL ordered map | pybind11/stl.h |
|
| std::map<T1, T2> | STL ordered map | pybind11/stl.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::set<T> | STL ordered set | pybind11/stl.h |
|
| std::unordered_map<T1, T2> | STL unordered map | pybind11/stl.h |
|
||||||
+------------------------+--------------------------+-----------------------+
|
+----------------------------+--------------------------+-----------------------+
|
||||||
| std::function<...> | STL polymorphic function | pybind11/functional.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
|
.. [#f1] In practice, implementation and binding code will generally be located
|
||||||
|
@ -10,8 +10,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "pybind11.h"
|
#include "pybind11.h"
|
||||||
#include <map>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@ -22,77 +24,10 @@
|
|||||||
NAMESPACE_BEGIN(pybind11)
|
NAMESPACE_BEGIN(pybind11)
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
template <typename Type, typename Alloc> struct type_caster<std::vector<Type, Alloc>> {
|
template <typename Type, typename Key> struct set_caster {
|
||||||
typedef std::vector<Type, Alloc> vector_type;
|
typedef Type 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;
|
|
||||||
typedef type_caster<Key> key_conv;
|
typedef type_caster<Key> key_conv;
|
||||||
public:
|
|
||||||
bool load(handle src, bool convert) {
|
bool load(handle src, bool convert) {
|
||||||
pybind11::set s(src, true);
|
pybind11::set s(src, true);
|
||||||
if (!s.check())
|
if (!s.check())
|
||||||
@ -116,12 +51,12 @@ public:
|
|||||||
}
|
}
|
||||||
return s.release();
|
return s.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_TYPE_CASTER(type, _("set<") + key_conv::name() + _(">"));
|
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>> {
|
template <typename Type, typename Key, typename Value> struct map_caster {
|
||||||
public:
|
typedef Type type;
|
||||||
typedef std::map<Key, Value, Compare, Alloc> type;
|
|
||||||
typedef type_caster<Key> key_conv;
|
typedef type_caster<Key> key_conv;
|
||||||
typedef type_caster<Value> value_conv;
|
typedef type_caster<Value> value_conv;
|
||||||
|
|
||||||
@ -156,6 +91,85 @@ public:
|
|||||||
PYBIND11_TYPE_CASTER(type, _("dict<") + key_conv::name() + _(", ") + value_conv::name() + _(">"));
|
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)
|
NAMESPACE_END(detail)
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
|
inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
|
||||||
|
Loading…
Reference in New Issue
Block a user