issues.cpp 3.71 KB
Newer Older
1
2
3
/*
    example/issues.cpp -- collection of testcases for miscellaneous issues

4
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5
6
7
8
9
10

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#include "example.h"
11
#include <pybind11/stl.h>
12

Wenzel Jakob's avatar
Wenzel Jakob committed
13
14
PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>);

15
16
17
void init_issues(py::module &m) {
    py::module m2 = m.def_submodule("issues");

Wenzel Jakob's avatar
Wenzel Jakob committed
18
19
20
21
22
23
24
25
26
27
#if !defined(_MSC_VER)
    // Visual Studio 2015 currently cannot compile this test
    // (see the comment in type_caster_base::make_copy_constructor)
    // #70 compilation issue if operator new is not public
    class NonConstructible { private: void *operator new(size_t bytes) throw(); };
    py::class_<NonConstructible>(m, "Foo");
    m.def("getstmt", []() -> NonConstructible * { return nullptr; },
        py::return_value_policy::reference);
#endif

28
29
    // #137: const char* isn't handled properly
    m2.def("print_cchar", [](const char *string) { std::cout << string << std::endl; });
30
31
32

    // #150: char bindings broken
    m2.def("print_char", [](char c) { std::cout << c << std::endl; });
33
34

    // #159: virtual function dispatch has problems with similar-named functions
Wenzel Jakob's avatar
Wenzel Jakob committed
35
36
37
    struct Base { virtual void dispatch(void) const {
        /* for some reason MSVC2015 can't compile this if the function is pure virtual */
    }; };
Wenzel Jakob's avatar
Wenzel Jakob committed
38
39
40
41
42
43
44

    struct DispatchIssue : Base {
        virtual void dispatch(void) const {
            PYBIND11_OVERLOAD_PURE(void, Base, dispatch, /* no arguments */);
        }
    };

45
    py::class_<DispatchIssue> base(m2, "DispatchIssue");
46
    base.alias<Base>()
47
        .def(py::init<>())
48
49
        .def("dispatch", &Base::dispatch);

Wenzel Jakob's avatar
Wenzel Jakob committed
50
51
52
    m2.def("dispatch_issue_go", [](const Base * b) { b->dispatch(); });

    struct Placeholder { int i; Placeholder(int i) : i(i) { } };
53
54

    py::class_<Placeholder>(m2, "Placeholder")
55
        .def(py::init<int>())
56
57
58
        .def("__repr__", [](const Placeholder &p) { return "Placeholder[" + std::to_string(p.i) + "]"; });

    // #171: Can't return reference wrappers (or STL datastructures containing them)
59
    m2.def("return_vec_of_reference_wrapper", [](std::reference_wrapper<Placeholder> p4){
60
61
        Placeholder *p1 = new Placeholder{1};
        Placeholder *p2 = new Placeholder{2};
62
        Placeholder *p3 = new Placeholder{3};
63
64
65
66
        std::vector<std::reference_wrapper<Placeholder>> v;
        v.push_back(std::ref(*p1));
        v.push_back(std::ref(*p2));
        v.push_back(std::ref(*p3));
67
        v.push_back(p4);
68
69
        return v;
    });
70
71
72
73
74

    // #181: iterator passthrough did not compile
    m2.def("iterator_passthrough", [](py::iterator s) -> py::iterator {
        return py::make_iterator(std::begin(s), std::end(s));
    });
Wenzel Jakob's avatar
Wenzel Jakob committed
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

    // #187: issue involving std::shared_ptr<> return value policy & garbage collection
    struct ElementBase { virtual void foo() { } /* Force creation of virtual table */ };
    struct ElementA : ElementBase {
        ElementA(int v) : v(v) { }
        int value() { return v; }
        int v;
    };

    struct ElementList {
        void add(std::shared_ptr<ElementBase> e) { l.push_back(e); }
        std::vector<std::shared_ptr<ElementBase>> l;
    };

    py::class_<ElementBase, std::shared_ptr<ElementBase>> (m2, "ElementBase");

    py::class_<ElementA, std::shared_ptr<ElementA>>(m2, "ElementA", py::base<ElementBase>())
        .def(py::init<int>())
        .def("value", &ElementA::value);

    py::class_<ElementList, std::shared_ptr<ElementList>>(m2, "ElementList")
        .def(py::init<>())
        .def("add", &ElementList::add)
        .def("get", [](ElementList &el){
            py::list list;
            for (auto &e : el.l)
                list.append(py::cast(e));
            return list;
        });
};