1 /*
2     tests/test_opaque_types.cpp -- opaque types, passing void pointers
3 
4     Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
6     All rights reserved. Use of this source code is governed by a
7     BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #include "pybind11_tests.h"
11 #include <pybind11/stl.h>
12 #include <vector>
13 
14 // IMPORTANT: Disable internal pybind11 translation mechanisms for STL data structures
15 //
16 // This also deliberately doesn't use the below StringList type alias to test
17 // that MAKE_OPAQUE can handle a type containing a `,`.  (The `std::allocator`
18 // bit is just the default `std::vector` allocator).
19 PYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>);
20 
21 using StringList = std::vector<std::string, std::allocator<std::string>>;
22 
TEST_SUBMODULE(opaque_types,m)23 TEST_SUBMODULE(opaque_types, m) {
24     // test_string_list
25     py::class_<StringList>(m, "StringList")
26         .def(py::init<>())
27         .def("pop_back", &StringList::pop_back)
28         /* There are multiple versions of push_back(), etc. Select the right ones. */
29         .def("push_back", (void (StringList::*)(const std::string &)) &StringList::push_back)
30         .def("back", (std::string &(StringList::*)()) &StringList::back)
31         .def("__len__", [](const StringList &v) { return v.size(); })
32         .def("__iter__", [](StringList &v) {
33            return py::make_iterator(v.begin(), v.end());
34         }, py::keep_alive<0, 1>());
35 
36     class ClassWithSTLVecProperty {
37     public:
38         StringList stringList;
39     };
40     py::class_<ClassWithSTLVecProperty>(m, "ClassWithSTLVecProperty")
41         .def(py::init<>())
42         .def_readwrite("stringList", &ClassWithSTLVecProperty::stringList);
43 
44     m.def("print_opaque_list", [](const StringList &l) {
45         std::string ret = "Opaque list: [";
46         bool first = true;
47         for (auto entry : l) {
48             if (!first)
49                 ret += ", ";
50             ret += entry;
51             first = false;
52         }
53         return ret + "]";
54     });
55 
56     // test_pointers
57     m.def("return_void_ptr", []() { return (void *) 0x1234; });
58     m.def("get_void_ptr_value", [](void *ptr) { return reinterpret_cast<std::intptr_t>(ptr); });
59     m.def("return_null_str", []() { return (char *) nullptr; });
60     m.def("get_null_str_value", [](char *ptr) { return reinterpret_cast<std::intptr_t>(ptr); });
61 
62     m.def("return_unique_ptr", []() -> std::unique_ptr<StringList> {
63         StringList *result = new StringList();
64         result->push_back("some value");
65         return std::unique_ptr<StringList>(result);
66     });
67 }
68