mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-30 00:47:12 +00:00
11a337f16f
* Propagate unicode conversion failure If returning a std::string with invalid utf-8 data, we currently fail with an uninformative TypeError instead of propagating the UnicodeDecodeError that Python sets on failure. * Add support for u16/u32strings and literals This adds support for wchar{16,32}_t character literals and the associated std::u{16,32}string types. It also folds the character/string conversion into a single type_caster template, since the type casters for string and wstring were mostly the same anyway. * Added too-long and too-big character conversion errors With this commit, when casting to a single character, as opposed to a C-style string, we make sure the input wasn't a multi-character string or a single character with codepoint too large for the character type. This also changes the character cast op to CharT instead of CharT& (we need to be able to return a temporary decoded char value, but also because there's little gained by bothering with an lvalue return here). Finally it changes the char caster to 'has-a-string-caster' instead of 'is-a-string-caster' because, with the cast_op change above, there's nothing at all gained from inheritance. This also lets us remove the `success` from the string caster (which was only there for the char caster) into the char caster itself. (I also renamed it to 'none' and inverted its value to better reflect its purpose). The None -> nullptr loading also now takes place only under a `convert = true` load pass. Although it's unlikely that a function taking a char also has overloads that can take a None, it seems marginally more correct to treat it as a conversion. This commit simplifies the size assumptions about character sizes with static_asserts to back them up.
159 lines
11 KiB
ReStructuredText
159 lines
11 KiB
ReStructuredText
Overview
|
|
########
|
|
|
|
.. rubric:: 1. Native type in C++, wrapper in Python
|
|
|
|
Exposing a custom C++ type using :class:`py::class_` was covered in detail
|
|
in the :doc:`/classes` section. There, the underlying data structure is
|
|
always the original C++ class while the :class:`py::class_` wrapper provides
|
|
a Python interface. Internally, when an object like this is sent from C++ to
|
|
Python, pybind11 will just add the outer wrapper layer over the native C++
|
|
object. Getting it back from Python is just a matter of peeling off the
|
|
wrapper.
|
|
|
|
.. rubric:: 2. Wrapper in C++, native type in Python
|
|
|
|
This is the exact opposite situation. Now, we have a type which is native to
|
|
Python, like a ``tuple`` or a ``list``. One way to get this data into C++ is
|
|
with the :class:`py::object` family of wrappers. These are explained in more
|
|
detail in the :doc:`/advanced/pycpp/object` section. We'll just give a quick
|
|
example here:
|
|
|
|
.. code-block:: cpp
|
|
|
|
void print_list(py::list my_list) {
|
|
for (auto item : my_list)
|
|
std::cout << item << " ";
|
|
}
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> print_list([1, 2, 3])
|
|
1 2 3
|
|
|
|
The Python ``list`` is not converted in any way -- it's just wrapped in a C++
|
|
:class:`py::list` class. At its core it's still a Python object. Copying a
|
|
:class:`py::list` will do the usual reference-counting like in Python.
|
|
Returning the object to Python will just remove the thin wrapper.
|
|
|
|
.. rubric:: 3. Converting between native C++ and Python types
|
|
|
|
In the previous two cases we had a native type in one language and a wrapper in
|
|
the other. Now, we have native types on both sides and we convert between them.
|
|
|
|
.. code-block:: cpp
|
|
|
|
void print_vector(const std::vector<int> &v) {
|
|
for (auto item : v)
|
|
std::cout << item << "\n";
|
|
}
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> print_vector([1, 2, 3])
|
|
1 2 3
|
|
|
|
In this case, pybind11 will construct a new ``std::vector<int>`` and copy each
|
|
element from the Python ``list``. The newly constructed object will be passed
|
|
to ``print_vector``. The same thing happens in the other direction: a new
|
|
``list`` is made to match the value returned from C++.
|
|
|
|
Lots of these conversions are supported out of the box, as shown in the table
|
|
below. They are very convenient, but keep in mind that these conversions are
|
|
fundamentally based on copying data. This is perfectly fine for small immutable
|
|
types but it may become quite expensive for large data structures. This can be
|
|
avoided by overriding the automatic conversion with a custom wrapper (i.e. the
|
|
above-mentioned approach 1). This requires some manual effort and more details
|
|
are available in the :ref:`opaque` section.
|
|
|
|
.. _conversion_table:
|
|
|
|
List of all builtin conversions
|
|
-------------------------------
|
|
|
|
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 | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``int16_t``, ``uint16_t`` | 16-bit integers | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``int32_t``, ``uint32_t`` | 32-bit integers | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``int64_t``, ``uint64_t`` | 64-bit integers | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``ssize_t``, ``size_t`` | Platform-dependent size | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``float``, ``double`` | Floating point types | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``bool`` | Two-state Boolean type | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``char`` | Character literal | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``char16_t`` | UTF-16 character literal | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``char32_t`` | UTF-32 character literal | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``wchar_t`` | Wide character literal | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``const char *`` | UTF-8 string literal | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``const char16_t *`` | UTF-16 string literal | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``const char32_t *`` | UTF-32 string literal | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``const wchar_t *`` | Wide string literal | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::string`` | STL dynamic UTF-8 string | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::u16string`` | STL dynamic UTF-16 string | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::u32string`` | STL dynamic UTF-32 string | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::wstring`` | STL dynamic wide string | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::pair<T1, T2>`` | Pair of two custom types | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::tuple<...>`` | Arbitrary tuple of types | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::reference_wrapper<...>`` | Reference type wrapper | :file:`pybind11/pybind11.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::complex<T>`` | Complex numbers | :file:`pybind11/complex.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::array<T, Size>`` | STL static array | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::vector<T>`` | STL dynamic array | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::valarray<T>`` | STL value array | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::list<T>`` | STL linked list | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::map<T1, T2>`` | STL ordered map | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::unordered_map<T1, T2>`` | STL unordered map | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::set<T>`` | STL ordered set | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::unordered_set<T>`` | STL unordered set | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::optional<T>`` | STL optional type (C++17) | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::experimental::optional<T>`` | STL optional type (exp.) | :file:`pybind11/stl.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::function<...>`` | STL polymorphic function | :file:`pybind11/functional.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::chrono::duration<...>`` | STL time duration | :file:`pybind11/chrono.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``std::chrono::time_point<...>`` | STL date/time | :file:`pybind11/chrono.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``Eigen::Matrix<...>`` | Eigen: dense matrix | :file:`pybind11/eigen.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``Eigen::Map<...>`` | Eigen: mapped memory | :file:`pybind11/eigen.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|
|
| ``Eigen::SparseMatrix<...>`` | Eigen: sparse matrix | :file:`pybind11/eigen.h` |
|
|
+------------------------------------+---------------------------+-------------------------------+
|