1
1
#include " pybind11_tests.h"
2
2
3
+ #include < iostream>
3
4
#include < memory>
4
5
5
6
namespace pybind11_tests {
6
7
namespace unique_ptr_member {
7
8
9
+ inline void to_cout (std::string text) { std::cout << text << std::endl; }
10
+
8
11
class pointee { // NOT copyable.
9
12
public:
10
13
pointee () = default ;
11
14
12
- int get_int () const { return 213 ; }
15
+ int get_int () const {
16
+ to_cout (" pointee::get_int()" );
17
+ return 213 ;
18
+ }
19
+
20
+ ~pointee () { to_cout (" ~pointee()" ); }
13
21
14
22
private:
15
23
pointee (const pointee &) = delete ;
@@ -18,35 +26,64 @@ class pointee { // NOT copyable.
18
26
pointee &operator =(pointee &&) = delete ;
19
27
};
20
28
29
+ inline std::unique_ptr<pointee> make_unique_pointee () {
30
+ return std::unique_ptr<pointee>(new pointee);
31
+ }
32
+
21
33
class ptr_owner {
22
34
public:
23
35
explicit ptr_owner (std::unique_ptr<pointee> ptr) : ptr_(std::move(ptr)) {}
24
36
37
+ bool is_owner () const { return bool (ptr_); }
38
+
39
+ std::unique_ptr<pointee> give_up_ownership_via_unique_ptr () {
40
+ return std::move (ptr_);
41
+ }
42
+ std::shared_ptr<pointee> give_up_ownership_via_shared_ptr () {
43
+ return std::move (ptr_);
44
+ }
45
+
25
46
private:
26
47
std::unique_ptr<pointee> ptr_;
27
48
};
28
49
29
50
// Just to have a minimal example of a typical C++ pattern.
30
51
inline int cpp_pattern () {
31
- auto obj = std::unique_ptr<pointee>(new pointee);
32
- int result = (obj ? 10 : 0 );
52
+ auto obj = make_unique_pointee ();
53
+ int result = (obj ? 1 : 8 );
54
+ obj->get_int ();
33
55
ptr_owner owner (std::move (obj));
34
- result += (obj ? 1 : 0 );
56
+ result = result * 10 + (obj ? 8 : 1 );
57
+ result = result * 10 + (owner.is_owner () ? 1 : 8 );
58
+ to_cout (" before give up" );
59
+ auto reclaimed = owner.give_up_ownership_via_shared_ptr ();
60
+ to_cout (" after give up" );
61
+ result = result * 10 + (owner.is_owner () ? 8 : 1 );
62
+ result = result * 10 + (reclaimed ? 1 : 8 );
63
+ reclaimed.reset ();
64
+ to_cout (" after del" );
65
+ result = result * 10 + (reclaimed ? 8 : 1 );
35
66
return result;
36
67
}
37
68
38
69
TEST_SUBMODULE (unique_ptr_member, m) {
39
- m.def (" cpp_pattern " , cpp_pattern );
70
+ m.def (" to_cout " , to_cout );
40
71
41
- py::class_<pointee>(m, " pointee" )
72
+ py::class_<pointee, std::shared_ptr<pointee> >(m, " pointee" )
42
73
.def (py::init<>())
43
74
.def (" get_int" , &pointee::get_int);
44
75
76
+ m.def (" make_unique_pointee" , make_unique_pointee);
77
+
45
78
py::class_<ptr_owner>(m, " ptr_owner" )
46
- #ifdef FEAT_UNIQUE_PTR_ARG
47
- .def (py::init<std::unique_ptr<pointee>>(), py::arg (" ptr" ))
48
- #endif
49
- ;
79
+ // .def(py::init<std::unique_ptr<pointee>>(), py::arg("ptr"))
80
+ .def (" is_owner" , &ptr_owner::is_owner)
81
+ .def (" give_up_ownership_via_unique_ptr" ,
82
+ &ptr_owner::give_up_ownership_via_unique_ptr)
83
+ .def (" give_up_ownership_via_shared_ptr" ,
84
+ &ptr_owner::give_up_ownership_via_shared_ptr);
85
+
86
+ m.def (" cpp_pattern" , cpp_pattern);
50
87
}
51
88
52
89
} // namespace unique_ptr_member
0 commit comments