@@ -552,15 +552,150 @@ and the Python ``list``, ``set`` and ``dict`` data structures are automatically
552552enabled. The types ``std::pair<> `` and ``std::tuple<> `` are already supported
553553out of the box with just the core :file: `pybind11/pybind11.h ` header.
554554
555+ The major downside of these implicit conversions is that containers must be
556+ converted (i.e. copied) on every Python->C++ and C++->Python transition, which
557+ can have implications on the program semantics and performance. Please read the
558+ next sections for more details and alternative approaches that avoid this.
559+
555560.. note ::
556561
557- Arbitrary nesting of any of these types is supported .
562+ Arbitrary nesting of any of these types is possible .
558563
559564.. seealso ::
560565
561566 The file :file: `tests/test_python_types.cpp ` contains a complete
562567 example that demonstrates how to pass STL data types in more detail.
563568
569+ .. _opaque :
570+
571+ Treating STL data structures as opaque objects
572+ ==============================================
573+
574+ pybind11 heavily relies on a template matching mechanism to convert parameters
575+ and return values that are constructed from STL data types such as vectors,
576+ linked lists, hash tables, etc. This even works in a recursive manner, for
577+ instance to deal with lists of hash maps of pairs of elementary and custom
578+ types, etc.
579+
580+ However, a fundamental limitation of this approach is that internal conversions
581+ between Python and C++ types involve a copy operation that prevents
582+ pass-by-reference semantics. What does this mean?
583+
584+ Suppose we bind the following function
585+
586+ .. code-block :: cpp
587+
588+ void append_1(std::vector<int> &v) {
589+ v.push_back(1);
590+ }
591+
592+ and call it from Python, the following happens:
593+
594+ .. code-block :: pycon
595+
596+ >>> v = [5, 6]
597+ >>> append_1(v)
598+ >>> print(v)
599+ [5, 6]
600+
601+ As you can see, when passing STL data structures by reference, modifications
602+ are not propagated back the Python side. A similar situation arises when
603+ exposing STL data structures using the ``def_readwrite `` or ``def_readonly ``
604+ functions:
605+
606+ .. code-block :: cpp
607+
608+ /* ... definition ... */
609+
610+ class MyClass {
611+ std::vector<int> contents;
612+ };
613+
614+ /* ... binding code ... */
615+
616+ py::class_<MyClass>(m, "MyClass")
617+ .def(py::init<>)
618+ .def_readwrite("contents", &MyClass::contents);
619+
620+ In this case, properties can be read and written in their entirety. However, an
621+ ``append `` operaton involving such a list type has no effect:
622+
623+ .. code-block :: pycon
624+
625+ >>> m = MyClass()
626+ >>> m.contents = [5, 6]
627+ >>> print(m.contents)
628+ [5, 6]
629+ >>> m.contents.append(7)
630+ >>> print(m.contents)
631+ [5, 6]
632+
633+ Finally, the involved copy operations can be costly when dealing with very
634+ large lists. To deal with all of the above situations, pybind11 provides a
635+ macro named ``PYBIND11_MAKE_OPAQUE(T) `` that disables the template-based
636+ conversion machinery of types, thus rendering them *opaque *. The contents of
637+ opaque objects are never inspected or extracted, hence they *can * be passed by
638+ reference. For instance, to turn ``std::vector<int> `` into an opaque type, add
639+ the declaration
640+
641+ .. code-block :: cpp
642+
643+ PYBIND11_MAKE_OPAQUE(std::vector<int>);
644+
645+ before any binding code (e.g. invocations to ``class_::def() ``, etc.). This
646+ macro must be specified at the top level (and outside of any namespaces), since
647+ it instantiates a partial template overload. If your binding code consists of
648+ multiple compilation units, it must be present in every file preceding any
649+ usage of ``std::vector<int> ``. Opaque types must also have a corresponding
650+ ``class_ `` declaration to associate them with a name in Python, and to define a
651+ set of available operations, e.g.:
652+
653+ .. code-block :: cpp
654+
655+ py::class_<std::vector<int>>(m, "IntVector")
656+ .def(py::init<>())
657+ .def("clear", &std::vector<int>::clear)
658+ .def("pop_back", &std::vector<int>::pop_back)
659+ .def("__len__", [](const std::vector<int> &v) { return v.size(); })
660+ .def("__iter__", [](std::vector<int> &v) {
661+ return py::make_iterator(v.begin(), v.end());
662+ }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */
663+ // ....
664+
665+ The ability to expose STL containers as native Python objects is a fairly
666+ common request, hence pybind11 also provides an optional header file named
667+ :file: `pybind11/stl_bind.h ` that does exactly this. The mapped containers try
668+ to match the behavior of their native Python counterparts as much as possible.
669+
670+ The following example showcases usage of :file: `pybind11/stl_bind.h `:
671+
672+ .. code-block :: cpp
673+
674+ // Don't forget this
675+ #include <pybind11/stl_bind.h>
676+
677+ PYBIND11_MAKE_OPAQUE(std::vector<int>);
678+ PYBIND11_MAKE_OPAQUE(std::map<std::string, double>);
679+
680+ // ...
681+
682+ // later in binding code:
683+ py::bind_vector<std::vector<int>>(m, "VectorInt");
684+ py::bind_map<std::map<std::string, double>>(m, "MapStringDouble");
685+
686+ Please take a look at the :ref: `macro_notes ` before using the
687+ ``PYBIND11_MAKE_OPAQUE `` macro.
688+
689+ .. seealso ::
690+
691+ The file :file: `tests/test_opaque_types.cpp ` contains a complete
692+ example that demonstrates how to create and expose opaque types using
693+ pybind11 in more detail.
694+
695+ The file :file: `tests/test_stl_binders.cpp ` shows how to use the
696+ convenience STL container wrappers.
697+
698+
564699Binding sequence data types, iterators, the slicing protocol, etc.
565700==================================================================
566701
@@ -1094,108 +1229,6 @@ section.
10941229 The ``py::exception `` wrapper for creating custom exceptions cannot (yet)
10951230 be used as a base type.
10961231
1097- .. _opaque :
1098-
1099- Treating STL data structures as opaque objects
1100- ==============================================
1101-
1102- pybind11 heavily relies on a template matching mechanism to convert parameters
1103- and return values that are constructed from STL data types such as vectors,
1104- linked lists, hash tables, etc. This even works in a recursive manner, for
1105- instance to deal with lists of hash maps of pairs of elementary and custom
1106- types, etc.
1107-
1108- However, a fundamental limitation of this approach is that internal conversions
1109- between Python and C++ types involve a copy operation that prevents
1110- pass-by-reference semantics. What does this mean?
1111-
1112- Suppose we bind the following function
1113-
1114- .. code-block :: cpp
1115-
1116- void append_1(std::vector<int> &v) {
1117- v.push_back(1);
1118- }
1119-
1120- and call it from Python, the following happens:
1121-
1122- .. code-block :: pycon
1123-
1124- >>> v = [5, 6]
1125- >>> append_1(v)
1126- >>> print(v)
1127- [5, 6]
1128-
1129- As you can see, when passing STL data structures by reference, modifications
1130- are not propagated back the Python side. A similar situation arises when
1131- exposing STL data structures using the ``def_readwrite `` or ``def_readonly ``
1132- functions:
1133-
1134- .. code-block :: cpp
1135-
1136- /* ... definition ... */
1137-
1138- class MyClass {
1139- std::vector<int> contents;
1140- };
1141-
1142- /* ... binding code ... */
1143-
1144- py::class_<MyClass>(m, "MyClass")
1145- .def(py::init<>)
1146- .def_readwrite("contents", &MyClass::contents);
1147-
1148- In this case, properties can be read and written in their entirety. However, an
1149- ``append `` operaton involving such a list type has no effect:
1150-
1151- .. code-block :: pycon
1152-
1153- >>> m = MyClass()
1154- >>> m.contents = [5, 6]
1155- >>> print(m.contents)
1156- [5, 6]
1157- >>> m.contents.append(7)
1158- >>> print(m.contents)
1159- [5, 6]
1160-
1161- To deal with both of the above situations, pybind11 provides a macro named
1162- ``PYBIND11_MAKE_OPAQUE(T) `` that disables the template-based conversion
1163- machinery of types, thus rendering them *opaque *. The contents of opaque
1164- objects are never inspected or extracted, hence they can be passed by
1165- reference. For instance, to turn ``std::vector<int> `` into an opaque type, add
1166- the declaration
1167-
1168- .. code-block :: cpp
1169-
1170- PYBIND11_MAKE_OPAQUE(std::vector<int>);
1171-
1172- before any binding code (e.g. invocations to ``class_::def() ``, etc.). This
1173- macro must be specified at the top level, since instantiates a partial template
1174- overload. If your binding code consists of multiple compilation units, it must
1175- be present in every file preceding any usage of ``std::vector<int> ``. Opaque
1176- types must also have a corresponding ``class_ `` declaration to associate them
1177- with a name in Python, and to define a set of available operations:
1178-
1179- .. code-block :: cpp
1180-
1181- py::class_<std::vector<int>>(m, "IntVector")
1182- .def(py::init<>())
1183- .def("clear", &std::vector<int>::clear)
1184- .def("pop_back", &std::vector<int>::pop_back)
1185- .def("__len__", [](const std::vector<int> &v) { return v.size(); })
1186- .def("__iter__", [](std::vector<int> &v) {
1187- return py::make_iterator(v.begin(), v.end());
1188- }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */
1189- // ....
1190-
1191- Please take a look at the :ref: `macro_notes ` before using this feature.
1192-
1193- .. seealso ::
1194-
1195- The file :file: `tests/test_opaque_types.cpp ` contains a complete
1196- example that demonstrates how to create and expose opaque types using
1197- pybind11 in more detail.
1198-
11991232.. _eigen :
12001233
12011234Transparent conversion of dense and sparse Eigen data types
0 commit comments