stl.rst revision 12037
111986Sandreas.sandberg@arm.comSTL containers
211986Sandreas.sandberg@arm.com##############
311986Sandreas.sandberg@arm.com
411986Sandreas.sandberg@arm.comAutomatic conversion
511986Sandreas.sandberg@arm.com====================
611986Sandreas.sandberg@arm.com
711986Sandreas.sandberg@arm.comWhen including the additional header file :file:`pybind11/stl.h`, conversions
812037Sandreas.sandberg@arm.combetween ``std::vector<>``/``std::list<>``/``std::array<>``,
912037Sandreas.sandberg@arm.com``std::set<>``/``std::unordered_set<>``, and
1012037Sandreas.sandberg@arm.com``std::map<>``/``std::unordered_map<>`` and the Python ``list``, ``set`` and
1112037Sandreas.sandberg@arm.com``dict`` data structures are automatically enabled. The types ``std::pair<>``
1212037Sandreas.sandberg@arm.comand ``std::tuple<>`` are already supported out of the box with just the core
1312037Sandreas.sandberg@arm.com:file:`pybind11/pybind11.h` header.
1411986Sandreas.sandberg@arm.com
1511986Sandreas.sandberg@arm.comThe major downside of these implicit conversions is that containers must be
1611986Sandreas.sandberg@arm.comconverted (i.e. copied) on every Python->C++ and C++->Python transition, which
1711986Sandreas.sandberg@arm.comcan have implications on the program semantics and performance. Please read the
1811986Sandreas.sandberg@arm.comnext sections for more details and alternative approaches that avoid this.
1911986Sandreas.sandberg@arm.com
2011986Sandreas.sandberg@arm.com.. note::
2111986Sandreas.sandberg@arm.com
2211986Sandreas.sandberg@arm.com    Arbitrary nesting of any of these types is possible.
2311986Sandreas.sandberg@arm.com
2411986Sandreas.sandberg@arm.com.. seealso::
2511986Sandreas.sandberg@arm.com
2611986Sandreas.sandberg@arm.com    The file :file:`tests/test_python_types.cpp` contains a complete
2711986Sandreas.sandberg@arm.com    example that demonstrates how to pass STL data types in more detail.
2811986Sandreas.sandberg@arm.com
2911986Sandreas.sandberg@arm.com.. _opaque:
3011986Sandreas.sandberg@arm.com
3111986Sandreas.sandberg@arm.comMaking opaque types
3211986Sandreas.sandberg@arm.com===================
3311986Sandreas.sandberg@arm.com
3411986Sandreas.sandberg@arm.compybind11 heavily relies on a template matching mechanism to convert parameters
3511986Sandreas.sandberg@arm.comand return values that are constructed from STL data types such as vectors,
3611986Sandreas.sandberg@arm.comlinked lists, hash tables, etc. This even works in a recursive manner, for
3711986Sandreas.sandberg@arm.cominstance to deal with lists of hash maps of pairs of elementary and custom
3811986Sandreas.sandberg@arm.comtypes, etc.
3911986Sandreas.sandberg@arm.com
4011986Sandreas.sandberg@arm.comHowever, a fundamental limitation of this approach is that internal conversions
4111986Sandreas.sandberg@arm.combetween Python and C++ types involve a copy operation that prevents
4211986Sandreas.sandberg@arm.compass-by-reference semantics. What does this mean?
4311986Sandreas.sandberg@arm.com
4411986Sandreas.sandberg@arm.comSuppose we bind the following function
4511986Sandreas.sandberg@arm.com
4611986Sandreas.sandberg@arm.com.. code-block:: cpp
4711986Sandreas.sandberg@arm.com
4811986Sandreas.sandberg@arm.com    void append_1(std::vector<int> &v) {
4911986Sandreas.sandberg@arm.com       v.push_back(1);
5011986Sandreas.sandberg@arm.com    }
5111986Sandreas.sandberg@arm.com
5211986Sandreas.sandberg@arm.comand call it from Python, the following happens:
5311986Sandreas.sandberg@arm.com
5411986Sandreas.sandberg@arm.com.. code-block:: pycon
5511986Sandreas.sandberg@arm.com
5611986Sandreas.sandberg@arm.com   >>> v = [5, 6]
5711986Sandreas.sandberg@arm.com   >>> append_1(v)
5811986Sandreas.sandberg@arm.com   >>> print(v)
5911986Sandreas.sandberg@arm.com   [5, 6]
6011986Sandreas.sandberg@arm.com
6111986Sandreas.sandberg@arm.comAs you can see, when passing STL data structures by reference, modifications
6211986Sandreas.sandberg@arm.comare not propagated back the Python side. A similar situation arises when
6311986Sandreas.sandberg@arm.comexposing STL data structures using the ``def_readwrite`` or ``def_readonly``
6411986Sandreas.sandberg@arm.comfunctions:
6511986Sandreas.sandberg@arm.com
6611986Sandreas.sandberg@arm.com.. code-block:: cpp
6711986Sandreas.sandberg@arm.com
6811986Sandreas.sandberg@arm.com    /* ... definition ... */
6911986Sandreas.sandberg@arm.com
7011986Sandreas.sandberg@arm.com    class MyClass {
7111986Sandreas.sandberg@arm.com        std::vector<int> contents;
7211986Sandreas.sandberg@arm.com    };
7311986Sandreas.sandberg@arm.com
7411986Sandreas.sandberg@arm.com    /* ... binding code ... */
7511986Sandreas.sandberg@arm.com
7611986Sandreas.sandberg@arm.com    py::class_<MyClass>(m, "MyClass")
7712037Sandreas.sandberg@arm.com        .def(py::init<>())
7811986Sandreas.sandberg@arm.com        .def_readwrite("contents", &MyClass::contents);
7911986Sandreas.sandberg@arm.com
8011986Sandreas.sandberg@arm.comIn this case, properties can be read and written in their entirety. However, an
8111986Sandreas.sandberg@arm.com``append`` operation involving such a list type has no effect:
8211986Sandreas.sandberg@arm.com
8311986Sandreas.sandberg@arm.com.. code-block:: pycon
8411986Sandreas.sandberg@arm.com
8511986Sandreas.sandberg@arm.com   >>> m = MyClass()
8611986Sandreas.sandberg@arm.com   >>> m.contents = [5, 6]
8711986Sandreas.sandberg@arm.com   >>> print(m.contents)
8811986Sandreas.sandberg@arm.com   [5, 6]
8911986Sandreas.sandberg@arm.com   >>> m.contents.append(7)
9011986Sandreas.sandberg@arm.com   >>> print(m.contents)
9111986Sandreas.sandberg@arm.com   [5, 6]
9211986Sandreas.sandberg@arm.com
9311986Sandreas.sandberg@arm.comFinally, the involved copy operations can be costly when dealing with very
9411986Sandreas.sandberg@arm.comlarge lists. To deal with all of the above situations, pybind11 provides a
9511986Sandreas.sandberg@arm.commacro named ``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based
9611986Sandreas.sandberg@arm.comconversion machinery of types, thus rendering them *opaque*. The contents of
9711986Sandreas.sandberg@arm.comopaque objects are never inspected or extracted, hence they *can* be passed by
9811986Sandreas.sandberg@arm.comreference. For instance, to turn ``std::vector<int>`` into an opaque type, add
9911986Sandreas.sandberg@arm.comthe declaration
10011986Sandreas.sandberg@arm.com
10111986Sandreas.sandberg@arm.com.. code-block:: cpp
10211986Sandreas.sandberg@arm.com
10311986Sandreas.sandberg@arm.com    PYBIND11_MAKE_OPAQUE(std::vector<int>);
10411986Sandreas.sandberg@arm.com
10511986Sandreas.sandberg@arm.combefore any binding code (e.g. invocations to ``class_::def()``, etc.). This
10611986Sandreas.sandberg@arm.commacro must be specified at the top level (and outside of any namespaces), since
10711986Sandreas.sandberg@arm.comit instantiates a partial template overload. If your binding code consists of
10811986Sandreas.sandberg@arm.commultiple compilation units, it must be present in every file preceding any
10911986Sandreas.sandberg@arm.comusage of ``std::vector<int>``. Opaque types must also have a corresponding
11011986Sandreas.sandberg@arm.com``class_`` declaration to associate them with a name in Python, and to define a
11111986Sandreas.sandberg@arm.comset of available operations, e.g.:
11211986Sandreas.sandberg@arm.com
11311986Sandreas.sandberg@arm.com.. code-block:: cpp
11411986Sandreas.sandberg@arm.com
11511986Sandreas.sandberg@arm.com    py::class_<std::vector<int>>(m, "IntVector")
11611986Sandreas.sandberg@arm.com        .def(py::init<>())
11711986Sandreas.sandberg@arm.com        .def("clear", &std::vector<int>::clear)
11811986Sandreas.sandberg@arm.com        .def("pop_back", &std::vector<int>::pop_back)
11911986Sandreas.sandberg@arm.com        .def("__len__", [](const std::vector<int> &v) { return v.size(); })
12011986Sandreas.sandberg@arm.com        .def("__iter__", [](std::vector<int> &v) {
12111986Sandreas.sandberg@arm.com           return py::make_iterator(v.begin(), v.end());
12211986Sandreas.sandberg@arm.com        }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */
12311986Sandreas.sandberg@arm.com        // ....
12411986Sandreas.sandberg@arm.com
12511986Sandreas.sandberg@arm.comThe ability to expose STL containers as native Python objects is a fairly
12611986Sandreas.sandberg@arm.comcommon request, hence pybind11 also provides an optional header file named
12711986Sandreas.sandberg@arm.com:file:`pybind11/stl_bind.h` that does exactly this. The mapped containers try
12811986Sandreas.sandberg@arm.comto match the behavior of their native Python counterparts as much as possible.
12911986Sandreas.sandberg@arm.com
13011986Sandreas.sandberg@arm.comThe following example showcases usage of :file:`pybind11/stl_bind.h`:
13111986Sandreas.sandberg@arm.com
13211986Sandreas.sandberg@arm.com.. code-block:: cpp
13311986Sandreas.sandberg@arm.com
13411986Sandreas.sandberg@arm.com    // Don't forget this
13511986Sandreas.sandberg@arm.com    #include <pybind11/stl_bind.h>
13611986Sandreas.sandberg@arm.com
13711986Sandreas.sandberg@arm.com    PYBIND11_MAKE_OPAQUE(std::vector<int>);
13811986Sandreas.sandberg@arm.com    PYBIND11_MAKE_OPAQUE(std::map<std::string, double>);
13911986Sandreas.sandberg@arm.com
14011986Sandreas.sandberg@arm.com    // ...
14111986Sandreas.sandberg@arm.com
14211986Sandreas.sandberg@arm.com    // later in binding code:
14311986Sandreas.sandberg@arm.com    py::bind_vector<std::vector<int>>(m, "VectorInt");
14411986Sandreas.sandberg@arm.com    py::bind_map<std::map<std::string, double>>(m, "MapStringDouble");
14511986Sandreas.sandberg@arm.com
14611986Sandreas.sandberg@arm.comPlease take a look at the :ref:`macro_notes` before using the
14711986Sandreas.sandberg@arm.com``PYBIND11_MAKE_OPAQUE`` macro.
14811986Sandreas.sandberg@arm.com
14911986Sandreas.sandberg@arm.com.. seealso::
15011986Sandreas.sandberg@arm.com
15111986Sandreas.sandberg@arm.com    The file :file:`tests/test_opaque_types.cpp` contains a complete
15211986Sandreas.sandberg@arm.com    example that demonstrates how to create and expose opaque types using
15311986Sandreas.sandberg@arm.com    pybind11 in more detail.
15411986Sandreas.sandberg@arm.com
15511986Sandreas.sandberg@arm.com    The file :file:`tests/test_stl_binders.cpp` shows how to use the
15611986Sandreas.sandberg@arm.com    convenience STL container wrappers.
157