mirror of
https://github.com/RYDE-WORK/pybind11.git
synced 2026-02-04 14:33:21 +08:00
Improved STL support, support for std::set
This commit is contained in:
parent
723bc65b27
commit
333e889ef2
@ -27,6 +27,14 @@ public:
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create and return a Python set */
|
||||||
|
py::set get_set() {
|
||||||
|
py::set set;
|
||||||
|
set.insert(py::str("key1"));
|
||||||
|
set.insert(py::str("key2"));
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create and return a C++ dictionary */
|
/* Create and return a C++ dictionary */
|
||||||
std::map<std::string, std::string> get_dict_2() {
|
std::map<std::string, std::string> get_dict_2() {
|
||||||
std::map<std::string, std::string> result;
|
std::map<std::string, std::string> result;
|
||||||
@ -34,6 +42,14 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create and return a C++ set */
|
||||||
|
std::set<std::string> get_set_2() {
|
||||||
|
std::set<std::string> result;
|
||||||
|
result.insert("key1");
|
||||||
|
result.insert("key2");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create, manipulate, and return a Python list */
|
/* Create, manipulate, and return a Python list */
|
||||||
py::list get_list() {
|
py::list get_list() {
|
||||||
py::list list;
|
py::list list;
|
||||||
@ -62,6 +78,18 @@ public:
|
|||||||
std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
|
std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Easily iterate over a setionary using a C++11 range-based for loop */
|
||||||
|
void print_set(py::set set) {
|
||||||
|
for (auto item : set)
|
||||||
|
std::cout << "key: " << item << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* STL data types are automatically casted from Python */
|
||||||
|
void print_set_2(const std::set<std::string> &set) {
|
||||||
|
for (auto item : set)
|
||||||
|
std::cout << "key: " << item << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
/* Easily iterate over a list using a C++11 range-based for loop */
|
/* Easily iterate over a list using a C++11 range-based for loop */
|
||||||
void print_list(py::list list) {
|
void print_list(py::list list) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -105,8 +133,12 @@ void init_ex2(py::module &m) {
|
|||||||
.def("get_dict_2", &Example2::get_dict_2, "Return a C++ dictionary")
|
.def("get_dict_2", &Example2::get_dict_2, "Return a C++ dictionary")
|
||||||
.def("get_list", &Example2::get_list, "Return a Python list")
|
.def("get_list", &Example2::get_list, "Return a Python list")
|
||||||
.def("get_list_2", &Example2::get_list_2, "Return a C++ list")
|
.def("get_list_2", &Example2::get_list_2, "Return a C++ list")
|
||||||
|
.def("get_set", &Example2::get_set, "Return a Python set")
|
||||||
|
.def("get_set2", &Example2::get_set, "Return a C++ set")
|
||||||
.def("print_dict", &Example2::print_dict, "Print entries of a Python dictionary")
|
.def("print_dict", &Example2::print_dict, "Print entries of a Python dictionary")
|
||||||
.def("print_dict_2", &Example2::print_dict_2, "Print entries of a C++ dictionary")
|
.def("print_dict_2", &Example2::print_dict_2, "Print entries of a C++ dictionary")
|
||||||
|
.def("print_set", &Example2::print_set, "Print entries of a Python set")
|
||||||
|
.def("print_set_2", &Example2::print_set_2, "Print entries of a C++ set")
|
||||||
.def("print_list", &Example2::print_list, "Print entries of a Python list")
|
.def("print_list", &Example2::print_list, "Print entries of a Python list")
|
||||||
.def("print_list_2", &Example2::print_list_2, "Print entries of a C++ list")
|
.def("print_list_2", &Example2::print_list_2, "Print entries of a C++ list")
|
||||||
.def("pair_passthrough", &Example2::pair_passthrough, "Return a pair in reversed order")
|
.def("pair_passthrough", &Example2::pair_passthrough, "Return a pair in reversed order")
|
||||||
|
|||||||
@ -29,6 +29,14 @@ dict_result = instance.get_dict_2()
|
|||||||
dict_result['key2'] = 'value2'
|
dict_result['key2'] = 'value2'
|
||||||
instance.print_dict_2(dict_result)
|
instance.print_dict_2(dict_result)
|
||||||
|
|
||||||
|
set_result = instance.get_set()
|
||||||
|
set_result.add(u'key3')
|
||||||
|
instance.print_set(set_result)
|
||||||
|
|
||||||
|
set_result = instance.get_set2()
|
||||||
|
set_result.add(u'key3')
|
||||||
|
instance.print_set_2(set_result)
|
||||||
|
|
||||||
list_result = instance.get_list()
|
list_result = instance.get_list()
|
||||||
list_result.append('value2')
|
list_result.append('value2')
|
||||||
instance.print_list(list_result)
|
instance.print_list(list_result)
|
||||||
|
|||||||
@ -6,6 +6,12 @@ key: key2, value=value2
|
|||||||
key: key, value=value
|
key: key, value=value
|
||||||
key: key, value=value
|
key: key, value=value
|
||||||
key: key2, value=value2
|
key: key2, value=value2
|
||||||
|
key: key3
|
||||||
|
key: key2
|
||||||
|
key: key1
|
||||||
|
key: key1
|
||||||
|
key: key2
|
||||||
|
key: key3
|
||||||
Entry at positon 0: value
|
Entry at positon 0: value
|
||||||
list item 0: overwritten
|
list item 0: overwritten
|
||||||
list item 1: value2
|
list item 1: value2
|
||||||
@ -44,6 +50,16 @@ class EExxaammppllee22(__builtin__.object)
|
|||||||
|
|
|
|
||||||
| Return a C++ list
|
| Return a C++ list
|
||||||
|
|
|
|
||||||
|
| ggeett__sseett(...)
|
||||||
|
| Signature : (Example2) -> set
|
||||||
|
|
|
||||||
|
| Return a Python set
|
||||||
|
|
|
||||||
|
| ggeett__sseett22(...)
|
||||||
|
| Signature : (Example2) -> set
|
||||||
|
|
|
||||||
|
| Return a C++ set
|
||||||
|
|
|
||||||
| ppaaiirr__ppaasssstthhrroouugghh(...)
|
| ppaaiirr__ppaasssstthhrroouugghh(...)
|
||||||
| Signature : (Example2, (bool, str)) -> (str, bool)
|
| Signature : (Example2, (bool, str)) -> (str, bool)
|
||||||
|
|
|
|
||||||
@ -69,6 +85,16 @@ class EExxaammppllee22(__builtin__.object)
|
|||||||
|
|
|
|
||||||
| Print entries of a C++ list
|
| Print entries of a C++ list
|
||||||
|
|
|
|
||||||
|
| pprriinntt__sseett(...)
|
||||||
|
| Signature : (Example2, set) -> None
|
||||||
|
|
|
||||||
|
| Print entries of a Python set
|
||||||
|
|
|
||||||
|
| pprriinntt__sseett__22(...)
|
||||||
|
| Signature : (Example2, set<str>) -> None
|
||||||
|
|
|
||||||
|
| Print entries of a C++ set
|
||||||
|
|
|
||||||
| tthhrrooww__eexxcceeppttiioonn(...)
|
| tthhrrooww__eexxcceeppttiioonn(...)
|
||||||
| Signature : (Example2) -> None
|
| Signature : (Example2) -> None
|
||||||
|
|
|
|
||||||
@ -85,7 +111,7 @@ class EExxaammppllee22(__builtin__.object)
|
|||||||
| ____nneeww____ = <built-in method __new__ of Example2_meta object>
|
| ____nneeww____ = <built-in method __new__ of Example2_meta object>
|
||||||
| T.__new__(S, ...) -> a new object with type S, a subtype of T
|
| T.__new__(S, ...) -> a new object with type S, a subtype of T
|
||||||
|
|
|
|
||||||
| ____ppyybbiinndd____ = <capsule object NULL>
|
| ____ppyybbiinndd1111____ = <capsule object NULL>
|
||||||
|
|
|
|
||||||
| nneeww__iinnssttaannccee = <built-in method new_instance of PyCapsule object>
|
| nneeww__iinnssttaannccee = <built-in method new_instance of PyCapsule object>
|
||||||
| Signature : () -> Example2
|
| Signature : () -> Example2
|
||||||
|
|||||||
@ -571,6 +571,7 @@ PYBIND11_TYPE_CASTER_PYTYPE(capsule) PYBIND11_TYPE_CASTER_PYTYPE(dict)
|
|||||||
PYBIND11_TYPE_CASTER_PYTYPE(float_) PYBIND11_TYPE_CASTER_PYTYPE(int_)
|
PYBIND11_TYPE_CASTER_PYTYPE(float_) PYBIND11_TYPE_CASTER_PYTYPE(int_)
|
||||||
PYBIND11_TYPE_CASTER_PYTYPE(list) PYBIND11_TYPE_CASTER_PYTYPE(slice)
|
PYBIND11_TYPE_CASTER_PYTYPE(list) PYBIND11_TYPE_CASTER_PYTYPE(slice)
|
||||||
PYBIND11_TYPE_CASTER_PYTYPE(tuple) PYBIND11_TYPE_CASTER_PYTYPE(function)
|
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)
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ class object;
|
|||||||
class str;
|
class str;
|
||||||
class object;
|
class object;
|
||||||
class dict;
|
class dict;
|
||||||
|
class iterator;
|
||||||
namespace detail { class accessor; }
|
namespace detail { class accessor; }
|
||||||
|
|
||||||
/// Holds a reference to a Python object (no reference counting)
|
/// Holds a reference to a Python object (no reference counting)
|
||||||
@ -33,6 +34,8 @@ public:
|
|||||||
void dec_ref() const { Py_XDECREF(m_ptr); }
|
void dec_ref() const { Py_XDECREF(m_ptr); }
|
||||||
int ref_count() const { return (int) Py_REFCNT(m_ptr); }
|
int ref_count() const { return (int) Py_REFCNT(m_ptr); }
|
||||||
handle get_type() { return (PyObject *) Py_TYPE(m_ptr); }
|
handle get_type() { return (PyObject *) Py_TYPE(m_ptr); }
|
||||||
|
inline iterator begin();
|
||||||
|
inline iterator end();
|
||||||
inline detail::accessor operator[](handle key);
|
inline detail::accessor operator[](handle key);
|
||||||
inline detail::accessor operator[](const char *key);
|
inline detail::accessor operator[](const char *key);
|
||||||
inline detail::accessor attr(handle key);
|
inline detail::accessor attr(handle key);
|
||||||
@ -73,6 +76,23 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class iterator : public object {
|
||||||
|
public:
|
||||||
|
iterator(PyObject *obj, bool borrowed = false) : object(obj, borrowed) { ++*this; }
|
||||||
|
iterator& operator++() {
|
||||||
|
if (ptr())
|
||||||
|
value = object(PyIter_Next(ptr()), false);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool operator==(const iterator &it) const { return *it == **this; }
|
||||||
|
bool operator!=(const iterator &it) const { return *it != **this; }
|
||||||
|
object operator*() { return value; }
|
||||||
|
const object &operator*() const { return value; }
|
||||||
|
bool check() const { return PyIter_Check(ptr()); }
|
||||||
|
private:
|
||||||
|
object value;
|
||||||
|
};
|
||||||
|
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
class accessor {
|
class accessor {
|
||||||
public:
|
public:
|
||||||
@ -159,18 +179,6 @@ private:
|
|||||||
size_t index;
|
size_t index;
|
||||||
};
|
};
|
||||||
|
|
||||||
class list_iterator {
|
|
||||||
public:
|
|
||||||
list_iterator(PyObject *list, ssize_t pos) : list(list), pos(pos) { }
|
|
||||||
list_iterator& operator++() { ++pos; return *this; }
|
|
||||||
object operator*() { return object(PyList_GetItem(list, pos), true); }
|
|
||||||
bool operator==(const list_iterator &it) const { return it.pos == pos; }
|
|
||||||
bool operator!=(const list_iterator &it) const { return it.pos != pos; }
|
|
||||||
private:
|
|
||||||
PyObject *list;
|
|
||||||
ssize_t pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dict_iterator {
|
struct dict_iterator {
|
||||||
public:
|
public:
|
||||||
dict_iterator(PyObject *dict = nullptr, ssize_t pos = -1) : dict(dict), pos(pos) { }
|
dict_iterator(PyObject *dict = nullptr, ssize_t pos = -1) : dict(dict), pos(pos) { }
|
||||||
@ -194,6 +202,8 @@ inline detail::accessor handle::operator[](handle key) { return detail::accessor
|
|||||||
inline detail::accessor handle::operator[](const char *key) { return detail::accessor(ptr(), key, false); }
|
inline detail::accessor handle::operator[](const char *key) { return detail::accessor(ptr(), key, false); }
|
||||||
inline detail::accessor handle::attr(handle key) { return detail::accessor(ptr(), key.ptr(), true); }
|
inline detail::accessor handle::attr(handle key) { return detail::accessor(ptr(), key.ptr(), true); }
|
||||||
inline detail::accessor handle::attr(const char *key) { return detail::accessor(ptr(), key, true); }
|
inline detail::accessor handle::attr(const char *key) { return detail::accessor(ptr(), key, true); }
|
||||||
|
inline iterator handle::begin() { return iterator(PyObject_GetIter(ptr())); }
|
||||||
|
inline iterator handle::end() { return iterator(nullptr); }
|
||||||
|
|
||||||
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, CvtStmt) \
|
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, CvtStmt) \
|
||||||
Name(const handle &h, bool borrowed) : Parent(h, borrowed) { CvtStmt; } \
|
Name(const handle &h, bool borrowed) : Parent(h, borrowed) { CvtStmt; } \
|
||||||
@ -310,6 +320,7 @@ public:
|
|||||||
size_t size() const { return (size_t) PyDict_Size(m_ptr); }
|
size_t size() const { return (size_t) PyDict_Size(m_ptr); }
|
||||||
detail::dict_iterator begin() { return (++detail::dict_iterator(ptr(), 0)); }
|
detail::dict_iterator begin() { return (++detail::dict_iterator(ptr(), 0)); }
|
||||||
detail::dict_iterator end() { return detail::dict_iterator(); }
|
detail::dict_iterator end() { return detail::dict_iterator(); }
|
||||||
|
void clear() { PyDict_Clear(ptr()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class list : public object {
|
class list : public object {
|
||||||
@ -317,12 +328,19 @@ public:
|
|||||||
PYBIND11_OBJECT(list, object, PyList_Check)
|
PYBIND11_OBJECT(list, object, PyList_Check)
|
||||||
list(size_t size = 0) : object(PyList_New((ssize_t) size), false) { }
|
list(size_t size = 0) : object(PyList_New((ssize_t) size), false) { }
|
||||||
size_t size() const { return (size_t) PyList_Size(m_ptr); }
|
size_t size() const { return (size_t) PyList_Size(m_ptr); }
|
||||||
detail::list_iterator begin() { return detail::list_iterator(ptr(), 0); }
|
|
||||||
detail::list_iterator end() { return detail::list_iterator(ptr(), (ssize_t) size()); }
|
|
||||||
detail::list_accessor operator[](size_t index) { return detail::list_accessor(ptr(), index); }
|
detail::list_accessor operator[](size_t index) { return detail::list_accessor(ptr(), index); }
|
||||||
void append(const object &object) { PyList_Append(m_ptr, (PyObject *) object.ptr()); }
|
void append(const object &object) { PyList_Append(m_ptr, (PyObject *) object.ptr()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class set : public object {
|
||||||
|
public:
|
||||||
|
PYBIND11_OBJECT(set, object, PySet_Check)
|
||||||
|
set() : object(PySet_New(nullptr), false) { }
|
||||||
|
size_t size() const { return (size_t) PySet_Size(m_ptr); }
|
||||||
|
void insert(const object &object) { PySet_Add(m_ptr, (PyObject *) object.ptr()); }
|
||||||
|
void clear() { PySet_Clear(ptr()); }
|
||||||
|
};
|
||||||
|
|
||||||
class function : public object {
|
class function : public object {
|
||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT_DEFAULT(function, object, PyFunction_Check)
|
PYBIND11_OBJECT_DEFAULT(function, object, PyFunction_Check)
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "pybind11.h"
|
#include "pybind11.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
@ -22,8 +23,8 @@
|
|||||||
NAMESPACE_BEGIN(pybind11)
|
NAMESPACE_BEGIN(pybind11)
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
template <typename Value> struct type_caster<std::vector<Value>> {
|
template <typename Value, typename Alloc> struct type_caster<std::vector<Value, Alloc>> {
|
||||||
typedef std::vector<Value> type;
|
typedef std::vector<Value, Alloc> type;
|
||||||
typedef type_caster<Value> value_conv;
|
typedef type_caster<Value> value_conv;
|
||||||
public:
|
public:
|
||||||
bool load(PyObject *src, bool convert) {
|
bool load(PyObject *src, bool convert) {
|
||||||
@ -32,8 +33,8 @@ public:
|
|||||||
size_t size = (size_t) PyList_GET_SIZE(src);
|
size_t size = (size_t) PyList_GET_SIZE(src);
|
||||||
value.reserve(size);
|
value.reserve(size);
|
||||||
value.clear();
|
value.clear();
|
||||||
|
value_conv conv;
|
||||||
for (size_t i=0; i<size; ++i) {
|
for (size_t i=0; i<size; ++i) {
|
||||||
value_conv conv;
|
|
||||||
if (!conv.load(PyList_GetItem(src, (ssize_t) i), convert))
|
if (!conv.load(PyList_GetItem(src, (ssize_t) i), convert))
|
||||||
return false;
|
return false;
|
||||||
value.push_back((Value) conv);
|
value.push_back((Value) conv);
|
||||||
@ -57,9 +58,46 @@ public:
|
|||||||
PYBIND11_TYPE_CASTER(type, detail::descr("list<") + value_conv::name() + detail::descr(">"));
|
PYBIND11_TYPE_CASTER(type, detail::descr("list<") + value_conv::name() + detail::descr(">"));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Key, typename Value> struct type_caster<std::map<Key, Value>> {
|
template <typename Value, typename Compare, typename Alloc> struct type_caster<std::set<Value, Compare, Alloc>> {
|
||||||
|
typedef std::set<Value, Compare, Alloc> type;
|
||||||
|
typedef type_caster<Value> value_conv;
|
||||||
public:
|
public:
|
||||||
typedef std::map<Key, Value> type;
|
bool load(PyObject *src, bool convert) {
|
||||||
|
pybind11::set s(src, true);
|
||||||
|
if (!s.check())
|
||||||
|
return false;
|
||||||
|
value.clear();
|
||||||
|
value_conv conv;
|
||||||
|
for (const object &o: s) {
|
||||||
|
if (!conv.load((PyObject *) o.ptr(), convert))
|
||||||
|
return false;
|
||||||
|
value.insert((Value) conv);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) {
|
||||||
|
PyObject *set = PySet_New(nullptr);
|
||||||
|
for (auto const &value: src) {
|
||||||
|
PyObject *value_ = value_conv::cast(value, policy, parent);
|
||||||
|
if (!value_) {
|
||||||
|
Py_DECREF(set);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (PySet_Add(set, value) != 0) {
|
||||||
|
Py_DECREF(value);
|
||||||
|
Py_DECREF(set);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
PYBIND11_TYPE_CASTER(type, detail::descr("set<") + value_conv::name() + detail::descr(">"));
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
typedef type_caster<Key> key_conv;
|
typedef type_caster<Key> key_conv;
|
||||||
typedef type_caster<Value> value_conv;
|
typedef type_caster<Value> value_conv;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user