diff --git a/docs/basics.rst b/docs/basics.rst index 7c2b4ee44..53a325e88 100644 --- a/docs/basics.rst +++ b/docs/basics.rst @@ -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 | Pair of two custom types | pybind11/pybind11.h | -+------------------------+--------------------------+-----------------------+ -| std::tuple<....> | Arbitrary tuple of types | pybind11/pybind11.h | -+------------------------+--------------------------+-----------------------+ -| std::complex | Complex numbers | pybind11/complex.h | -+------------------------+--------------------------+-----------------------+ -| std::array | STL static array | pybind11/stl.h | -+------------------------+--------------------------+-----------------------+ -| std::vector | STL dynamic array | pybind11/stl.h | -+------------------------+--------------------------+-----------------------+ -| std::map | STL ordered map | pybind11/stl.h | -+------------------------+--------------------------+-----------------------+ -| std::set | STL ordered set | pybind11/stl.h | -+------------------------+--------------------------+-----------------------+ -| std::function<...> | STL polymorphic function | pybind11/functional.h | -+------------------------+--------------------------+-----------------------+ ++----------------------------+--------------------------+-----------------------+ +| 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 | Pair of two custom types | pybind11/pybind11.h | ++----------------------------+--------------------------+-----------------------+ +| std::tuple<....> | Arbitrary tuple of types | pybind11/pybind11.h | ++----------------------------+--------------------------+-----------------------+ +| std::complex | Complex numbers | pybind11/complex.h | ++----------------------------+--------------------------+-----------------------+ +| std::array | STL static array | pybind11/stl.h | ++----------------------------+--------------------------+-----------------------+ +| std::vector | STL dynamic array | pybind11/stl.h | ++----------------------------+--------------------------+-----------------------+ +| std::map | STL ordered map | pybind11/stl.h | ++----------------------------+--------------------------+-----------------------+ +| std::unordered_map | STL unordered map | pybind11/stl.h | ++----------------------------+--------------------------+-----------------------+ +| std::set | STL ordered set | pybind11/stl.h | ++----------------------------+--------------------------+-----------------------+ +| std::unordered_set | 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 diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index dcb96e046..1ee2cc4b3 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -10,8 +10,10 @@ #pragma once #include "pybind11.h" -#include #include +#include +#include +#include #include #if defined(_MSC_VER) @@ -22,77 +24,10 @@ NAMESPACE_BEGIN(pybind11) NAMESPACE_BEGIN(detail) -template struct type_caster> { - typedef std::vector vector_type; - typedef type_caster 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 struct type_caster> { - typedef std::array array_type; - typedef type_caster 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() + _(">") + _("[") + _() + _("]")); -}; - -template struct type_caster> { - typedef std::set type; +template struct set_caster { + typedef Type type; typedef type_caster 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 struct type_caster> { -public: - typedef std::map type; +template struct map_caster { + typedef Type type; typedef type_caster key_conv; typedef type_caster value_conv; @@ -156,6 +91,85 @@ public: PYBIND11_TYPE_CASTER(type, _("dict<") + key_conv::name() + _(", ") + value_conv::name() + _(">")); }; +template struct type_caster> { + typedef std::vector vector_type; + typedef type_caster 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 struct type_caster> { + typedef std::array array_type; + typedef type_caster 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() + _(">") + _("[") + _() + _("]")); +}; + +template struct type_caster> + : set_caster, Key> { }; + +template struct type_caster> + : set_caster, Key> { }; + +template struct type_caster> + : map_caster, Key, Value> { }; + +template struct type_caster> + : map_caster, Key, Value> { }; + NAMESPACE_END(detail) inline std::ostream &operator<<(std::ostream &os, const handle &obj) {