111986Sandreas.sandberg@arm.comOverview
211986Sandreas.sandberg@arm.com########
311986Sandreas.sandberg@arm.com
411986Sandreas.sandberg@arm.com.. rubric:: 1. Native type in C++, wrapper in Python
511986Sandreas.sandberg@arm.com
611986Sandreas.sandberg@arm.comExposing a custom C++ type using :class:`py::class_` was covered in detail
711986Sandreas.sandberg@arm.comin the :doc:`/classes` section. There, the underlying data structure is
811986Sandreas.sandberg@arm.comalways the original C++ class while the :class:`py::class_` wrapper provides
911986Sandreas.sandberg@arm.coma Python interface. Internally, when an object like this is sent from C++ to
1011986Sandreas.sandberg@arm.comPython, pybind11 will just add the outer wrapper layer over the native C++
1111986Sandreas.sandberg@arm.comobject. Getting it back from Python is just a matter of peeling off the
1211986Sandreas.sandberg@arm.comwrapper.
1311986Sandreas.sandberg@arm.com
1411986Sandreas.sandberg@arm.com.. rubric:: 2. Wrapper in C++, native type in Python
1511986Sandreas.sandberg@arm.com
1611986Sandreas.sandberg@arm.comThis is the exact opposite situation. Now, we have a type which is native to
1711986Sandreas.sandberg@arm.comPython, like a ``tuple`` or a ``list``. One way to get this data into C++ is
1811986Sandreas.sandberg@arm.comwith the :class:`py::object` family of wrappers. These are explained in more
1911986Sandreas.sandberg@arm.comdetail in the :doc:`/advanced/pycpp/object` section. We'll just give a quick
2011986Sandreas.sandberg@arm.comexample here:
2111986Sandreas.sandberg@arm.com
2211986Sandreas.sandberg@arm.com.. code-block:: cpp
2311986Sandreas.sandberg@arm.com
2411986Sandreas.sandberg@arm.com    void print_list(py::list my_list) {
2511986Sandreas.sandberg@arm.com        for (auto item : my_list)
2611986Sandreas.sandberg@arm.com            std::cout << item << " ";
2711986Sandreas.sandberg@arm.com    }
2811986Sandreas.sandberg@arm.com
2911986Sandreas.sandberg@arm.com.. code-block:: pycon
3011986Sandreas.sandberg@arm.com
3111986Sandreas.sandberg@arm.com    >>> print_list([1, 2, 3])
3211986Sandreas.sandberg@arm.com    1 2 3
3311986Sandreas.sandberg@arm.com
3411986Sandreas.sandberg@arm.comThe Python ``list`` is not converted in any way -- it's just wrapped in a C++
3511986Sandreas.sandberg@arm.com:class:`py::list` class. At its core it's still a Python object. Copying a
3611986Sandreas.sandberg@arm.com:class:`py::list` will do the usual reference-counting like in Python.
3711986Sandreas.sandberg@arm.comReturning the object to Python will just remove the thin wrapper.
3811986Sandreas.sandberg@arm.com
3911986Sandreas.sandberg@arm.com.. rubric:: 3. Converting between native C++ and Python types
4011986Sandreas.sandberg@arm.com
4111986Sandreas.sandberg@arm.comIn the previous two cases we had a native type in one language and a wrapper in
4211986Sandreas.sandberg@arm.comthe other. Now, we have native types on both sides and we convert between them.
4311986Sandreas.sandberg@arm.com
4411986Sandreas.sandberg@arm.com.. code-block:: cpp
4511986Sandreas.sandberg@arm.com
4611986Sandreas.sandberg@arm.com    void print_vector(const std::vector<int> &v) {
4711986Sandreas.sandberg@arm.com        for (auto item : v)
4811986Sandreas.sandberg@arm.com            std::cout << item << "\n";
4911986Sandreas.sandberg@arm.com    }
5011986Sandreas.sandberg@arm.com
5111986Sandreas.sandberg@arm.com.. code-block:: pycon
5211986Sandreas.sandberg@arm.com
5311986Sandreas.sandberg@arm.com    >>> print_vector([1, 2, 3])
5411986Sandreas.sandberg@arm.com    1 2 3
5511986Sandreas.sandberg@arm.com
5611986Sandreas.sandberg@arm.comIn this case, pybind11 will construct a new ``std::vector<int>`` and copy each
5711986Sandreas.sandberg@arm.comelement from the Python ``list``. The newly constructed object will be passed
5811986Sandreas.sandberg@arm.comto ``print_vector``. The same thing happens in the other direction: a new
5911986Sandreas.sandberg@arm.com``list`` is made to match the value returned from C++.
6011986Sandreas.sandberg@arm.com
6111986Sandreas.sandberg@arm.comLots of these conversions are supported out of the box, as shown in the table
6211986Sandreas.sandberg@arm.combelow. They are very convenient, but keep in mind that these conversions are
6311986Sandreas.sandberg@arm.comfundamentally based on copying data. This is perfectly fine for small immutable
6411986Sandreas.sandberg@arm.comtypes but it may become quite expensive for large data structures. This can be
6511986Sandreas.sandberg@arm.comavoided by overriding the automatic conversion with a custom wrapper (i.e. the
6611986Sandreas.sandberg@arm.comabove-mentioned approach 1). This requires some manual effort and more details
6711986Sandreas.sandberg@arm.comare available in the :ref:`opaque` section.
6811986Sandreas.sandberg@arm.com
6911986Sandreas.sandberg@arm.com.. _conversion_table:
7011986Sandreas.sandberg@arm.com
7111986Sandreas.sandberg@arm.comList of all builtin conversions
7211986Sandreas.sandberg@arm.com-------------------------------
7311986Sandreas.sandberg@arm.com
7411986Sandreas.sandberg@arm.comThe following basic data types are supported out of the box (some may require
7511986Sandreas.sandberg@arm.coman additional extension header to be included). To pass other data structures
7611986Sandreas.sandberg@arm.comas arguments and return values, refer to the section on binding :ref:`classes`.
7711986Sandreas.sandberg@arm.com
7811986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
7911986Sandreas.sandberg@arm.com|  Data type                         |  Description              | Header file                   |
8011986Sandreas.sandberg@arm.com+====================================+===========================+===============================+
8111986Sandreas.sandberg@arm.com| ``int8_t``, ``uint8_t``            | 8-bit integers            | :file:`pybind11/pybind11.h`   |
8211986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
8311986Sandreas.sandberg@arm.com| ``int16_t``, ``uint16_t``          | 16-bit integers           | :file:`pybind11/pybind11.h`   |
8411986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
8511986Sandreas.sandberg@arm.com| ``int32_t``, ``uint32_t``          | 32-bit integers           | :file:`pybind11/pybind11.h`   |
8611986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
8711986Sandreas.sandberg@arm.com| ``int64_t``, ``uint64_t``          | 64-bit integers           | :file:`pybind11/pybind11.h`   |
8811986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
8911986Sandreas.sandberg@arm.com| ``ssize_t``, ``size_t``            | Platform-dependent size   | :file:`pybind11/pybind11.h`   |
9011986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
9111986Sandreas.sandberg@arm.com| ``float``, ``double``              | Floating point types      | :file:`pybind11/pybind11.h`   |
9211986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
9311986Sandreas.sandberg@arm.com| ``bool``                           | Two-state Boolean type    | :file:`pybind11/pybind11.h`   |
9411986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
9511986Sandreas.sandberg@arm.com| ``char``                           | Character literal         | :file:`pybind11/pybind11.h`   |
9611986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
9712037Sandreas.sandberg@arm.com| ``char16_t``                       | UTF-16 character literal  | :file:`pybind11/pybind11.h`   |
9812037Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
9912037Sandreas.sandberg@arm.com| ``char32_t``                       | UTF-32 character literal  | :file:`pybind11/pybind11.h`   |
10012037Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
10111986Sandreas.sandberg@arm.com| ``wchar_t``                        | Wide character literal    | :file:`pybind11/pybind11.h`   |
10211986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
10311986Sandreas.sandberg@arm.com| ``const char *``                   | UTF-8 string literal      | :file:`pybind11/pybind11.h`   |
10411986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
10512037Sandreas.sandberg@arm.com| ``const char16_t *``               | UTF-16 string literal     | :file:`pybind11/pybind11.h`   |
10612037Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
10712037Sandreas.sandberg@arm.com| ``const char32_t *``               | UTF-32 string literal     | :file:`pybind11/pybind11.h`   |
10812037Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
10911986Sandreas.sandberg@arm.com| ``const wchar_t *``                | Wide string literal       | :file:`pybind11/pybind11.h`   |
11011986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
11111986Sandreas.sandberg@arm.com| ``std::string``                    | STL dynamic UTF-8 string  | :file:`pybind11/pybind11.h`   |
11211986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
11312037Sandreas.sandberg@arm.com| ``std::u16string``                 | STL dynamic UTF-16 string | :file:`pybind11/pybind11.h`   |
11412037Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
11512037Sandreas.sandberg@arm.com| ``std::u32string``                 | STL dynamic UTF-32 string | :file:`pybind11/pybind11.h`   |
11612037Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
11711986Sandreas.sandberg@arm.com| ``std::wstring``                   | STL dynamic wide string   | :file:`pybind11/pybind11.h`   |
11811986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
11912391Sjason@lowepower.com| ``std::string_view``,              | STL C++17 string views    | :file:`pybind11/pybind11.h`   |
12012391Sjason@lowepower.com| ``std::u16string_view``, etc.      |                           |                               |
12112391Sjason@lowepower.com+------------------------------------+---------------------------+-------------------------------+
12211986Sandreas.sandberg@arm.com| ``std::pair<T1, T2>``              | Pair of two custom types  | :file:`pybind11/pybind11.h`   |
12311986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
12411986Sandreas.sandberg@arm.com| ``std::tuple<...>``                | Arbitrary tuple of types  | :file:`pybind11/pybind11.h`   |
12511986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
12611986Sandreas.sandberg@arm.com| ``std::reference_wrapper<...>``    | Reference type wrapper    | :file:`pybind11/pybind11.h`   |
12711986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
12811986Sandreas.sandberg@arm.com| ``std::complex<T>``                | Complex numbers           | :file:`pybind11/complex.h`    |
12911986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
13011986Sandreas.sandberg@arm.com| ``std::array<T, Size>``            | STL static array          | :file:`pybind11/stl.h`        |
13111986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
13211986Sandreas.sandberg@arm.com| ``std::vector<T>``                 | STL dynamic array         | :file:`pybind11/stl.h`        |
13311986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
13414299Sbbruce@ucdavis.edu| ``std::deque<T>``                  | STL double-ended queue    | :file:`pybind11/stl.h`        |
13514299Sbbruce@ucdavis.edu+------------------------------------+---------------------------+-------------------------------+
13611986Sandreas.sandberg@arm.com| ``std::valarray<T>``               | STL value array           | :file:`pybind11/stl.h`        |
13711986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
13811986Sandreas.sandberg@arm.com| ``std::list<T>``                   | STL linked list           | :file:`pybind11/stl.h`        |
13911986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
14011986Sandreas.sandberg@arm.com| ``std::map<T1, T2>``               | STL ordered map           | :file:`pybind11/stl.h`        |
14111986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
14211986Sandreas.sandberg@arm.com| ``std::unordered_map<T1, T2>``     | STL unordered map         | :file:`pybind11/stl.h`        |
14311986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
14411986Sandreas.sandberg@arm.com| ``std::set<T>``                    | STL ordered set           | :file:`pybind11/stl.h`        |
14511986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
14611986Sandreas.sandberg@arm.com| ``std::unordered_set<T>``          | STL unordered set         | :file:`pybind11/stl.h`        |
14711986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
14811986Sandreas.sandberg@arm.com| ``std::optional<T>``               | STL optional type (C++17) | :file:`pybind11/stl.h`        |
14911986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
15011986Sandreas.sandberg@arm.com| ``std::experimental::optional<T>`` | STL optional type (exp.)  | :file:`pybind11/stl.h`        |
15111986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
15212391Sjason@lowepower.com| ``std::variant<...>``              | Type-safe union (C++17)   | :file:`pybind11/stl.h`        |
15312391Sjason@lowepower.com+------------------------------------+---------------------------+-------------------------------+
15411986Sandreas.sandberg@arm.com| ``std::function<...>``             | STL polymorphic function  | :file:`pybind11/functional.h` |
15511986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
15611986Sandreas.sandberg@arm.com| ``std::chrono::duration<...>``     | STL time duration         | :file:`pybind11/chrono.h`     |
15711986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
15811986Sandreas.sandberg@arm.com| ``std::chrono::time_point<...>``   | STL date/time             | :file:`pybind11/chrono.h`     |
15911986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
16011986Sandreas.sandberg@arm.com| ``Eigen::Matrix<...>``             | Eigen: dense matrix       | :file:`pybind11/eigen.h`      |
16111986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
16211986Sandreas.sandberg@arm.com| ``Eigen::Map<...>``                | Eigen: mapped memory      | :file:`pybind11/eigen.h`      |
16311986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
16411986Sandreas.sandberg@arm.com| ``Eigen::SparseMatrix<...>``       | Eigen: sparse matrix      | :file:`pybind11/eigen.h`      |
16511986Sandreas.sandberg@arm.com+------------------------------------+---------------------------+-------------------------------+
166