@@ -37,13 +37,37 @@ struct is_smart_holder_type<smart_holder> : std::true_type {};
37
37
inline void register_instance (instance *self, void *valptr, const type_info *tinfo);
38
38
inline bool deregister_instance (instance *self, void *valptr, const type_info *tinfo);
39
39
40
- // Replace all occurrences of a character in string.
41
- inline void replace_all (std::string &str, const std::string &from, char to) {
42
- size_t pos = str.find (from);
43
- while (pos != std::string::npos) {
44
- str.replace (pos, from.length (), 1 , to);
45
- pos = str.find (from, pos);
40
+ // Replace all occurrences of substrings in a string.
41
+ inline void replace_all (std::string &str, const std::string &from, const std::string &to) {
42
+ if (str.empty ()) {
43
+ return ;
46
44
}
45
+ size_t pos = 0 ;
46
+ while ((pos = str.find (from, pos)) != std::string::npos) {
47
+ str.replace (pos, from.length (), to);
48
+ pos += to.length ();
49
+ }
50
+ }
51
+
52
+ inline void *try_as_void_ptr_capsule_get_pointer (handle src, const char *typeid_name) {
53
+ std::string type_name = typeid_name;
54
+ detail::clean_type_id (type_name);
55
+
56
+ // Convert `a::b::c` to `a_b_c`.
57
+ replace_all (type_name, " ::" , " _" );
58
+ // Remove all `*` in the type name.
59
+ replace_all (type_name, " *" , " " );
60
+
61
+ std::string as_void_ptr_function_name (" as_" );
62
+ as_void_ptr_function_name += type_name;
63
+ if (hasattr (src, as_void_ptr_function_name.c_str ())) {
64
+ auto as_void_ptr_function = function (src.attr (as_void_ptr_function_name.c_str ()));
65
+ auto void_ptr_capsule = as_void_ptr_function ();
66
+ if (isinstance<capsule>(void_ptr_capsule)) {
67
+ return reinterpret_borrow<capsule>(void_ptr_capsule).get_pointer ();
68
+ }
69
+ }
70
+ return nullptr ;
47
71
}
48
72
49
73
// The modified_type_caster_generic_load_impl could replace type_caster_generic::load_impl but not
@@ -120,22 +144,10 @@ class modified_type_caster_generic_load_impl {
120
144
}
121
145
122
146
bool try_as_void_ptr_capsule (handle src) {
123
- std::string type_name = cpptype->name ();
124
- detail::clean_type_id (type_name);
125
-
126
- // Convert `a::b::c` to `a_b_c`
127
- replace_all (type_name, " ::" , ' _' );
128
-
129
- std::string as_void_ptr_function_name (" as_" );
130
- as_void_ptr_function_name += type_name;
131
- if (hasattr (src, as_void_ptr_function_name.c_str ())) {
132
- auto as_void_ptr_function = function (src.attr (as_void_ptr_function_name.c_str ()));
133
- auto void_ptr_capsule = as_void_ptr_function ();
134
- if (isinstance<capsule>(void_ptr_capsule)) {
135
- unowned_void_ptr_from_void_ptr_capsule
136
- = reinterpret_borrow<capsule>(void_ptr_capsule).get_pointer ();
137
- return true ;
138
- }
147
+ unowned_void_ptr_from_void_ptr_capsule
148
+ = try_as_void_ptr_capsule_get_pointer (src, cpptype->name ());
149
+ if (unowned_void_ptr_from_void_ptr_capsule != nullptr ) {
150
+ return true ;
139
151
}
140
152
return false ;
141
153
}
0 commit comments