1
1
#pragma once
2
2
3
3
#include < memory>
4
+ #include < stdexcept>
5
+ #include < string>
4
6
#include < typeinfo>
5
7
6
8
namespace pybindit {
@@ -44,8 +46,10 @@ struct smart_holder {
44
46
rtti_uqp_del{nullptr },
45
47
vptr_deleter_guard_flag{false } {}
46
48
49
+ bool has_pointee () const { return vptr.get () != nullptr ; }
50
+
47
51
template <typename T>
48
- void ensure_compatible_rtti_held (const char * context) {
52
+ void ensure_compatible_rtti_held (const char * context) const {
49
53
const std::type_info* rtti_requested = &typeid (T);
50
54
if (!(*rtti_requested == *rtti_held)) {
51
55
throw std::runtime_error (std::string (" Incompatible RTTI (" ) + context +
@@ -54,30 +58,45 @@ struct smart_holder {
54
58
}
55
59
56
60
template <typename D>
57
- void ensure_compatible_rtti_uqp_del (const char * context) {
61
+ void ensure_compatible_rtti_uqp_del (const char * context) const {
58
62
const std::type_info* rtti_requested = &typeid (D);
59
63
if (!(*rtti_requested == *rtti_uqp_del)) {
60
64
throw std::runtime_error (
61
65
std::string (" Incompatible unique_ptr deleter (" ) + context + " )." );
62
66
}
63
67
}
64
68
65
- void ensure_vptr_deleter_guard_flag_true (const char * context) {
69
+ void ensure_has_pointee (const char * context) const {
70
+ if (!has_pointee ()) {
71
+ throw std::runtime_error (std::string (" Disowned holder (" ) + context +
72
+ " )." );
73
+ }
74
+ }
75
+
76
+ void ensure_vptr_deleter_guard_flag_true (const char * context) const {
66
77
if (rtti_uqp_del != nullptr ) {
67
78
throw std::runtime_error (std::string (" Cannot disown this shared_ptr (" ) +
68
79
context + " )." );
69
80
}
70
81
}
71
82
72
- void ensure_use_count_1 (const char * context) {
83
+ void ensure_use_count_1 (const char * context) const {
73
84
if (vptr.use_count () != 1 ) {
74
85
throw std::runtime_error (std::string (" Cannot disown use_count != 1 (" ) +
75
86
context + " )." );
76
87
}
77
88
}
78
89
79
90
template <typename T>
80
- void from_raw_ptr_owned (T* raw_ptr) {
91
+ const T& const_value_ref () const {
92
+ static const char * context = " const_value_ref" ;
93
+ ensure_compatible_rtti_held<T>(context);
94
+ ensure_has_pointee (context);
95
+ return *static_cast <T*>(vptr.get ());
96
+ }
97
+
98
+ template <typename T>
99
+ void from_raw_ptr_take_ownership (T* raw_ptr) {
81
100
clear ();
82
101
rtti_held = &typeid (T);
83
102
vptr_deleter_guard_flag = true ;
@@ -93,7 +112,8 @@ struct smart_holder {
93
112
}
94
113
95
114
template <typename T>
96
- T* as_raw_ptr_owned (const char * context = " as_raw_ptr_owned" ) {
115
+ T* as_raw_ptr_release_ownership (
116
+ const char * context = " as_raw_ptr_release_ownership" ) {
97
117
ensure_compatible_rtti_held<T>(context);
98
118
ensure_vptr_deleter_guard_flag_true (context);
99
119
ensure_use_count_1 (context);
@@ -104,7 +124,7 @@ struct smart_holder {
104
124
}
105
125
106
126
template <typename T>
107
- T* as_raw_ptr_unowned () {
127
+ T* as_raw_ptr_unowned () const {
108
128
static const char * context = " as_raw_ptr_unowned" ;
109
129
ensure_compatible_rtti_held<T>(context);
110
130
return static_cast <T*>(vptr.get ());
@@ -122,7 +142,7 @@ struct smart_holder {
122
142
123
143
template <typename T>
124
144
std::unique_ptr<T> as_unique_ptr () {
125
- return std::unique_ptr<T>(as_raw_ptr_owned <T>(" as_unique_ptr" ));
145
+ return std::unique_ptr<T>(as_raw_ptr_release_ownership <T>(" as_unique_ptr" ));
126
146
}
127
147
128
148
template <typename T, typename D>
@@ -156,7 +176,7 @@ struct smart_holder {
156
176
}
157
177
158
178
template <typename T>
159
- std::shared_ptr<T> as_shared_ptr () {
179
+ std::shared_ptr<T> as_shared_ptr () const {
160
180
static const char * context = " as_shared_ptr" ;
161
181
ensure_compatible_rtti_held<T>(context);
162
182
return std::static_pointer_cast<T>(vptr);
0 commit comments