Skip to content

Commit 114c0f2

Browse files
authored
[smart_holder] Implement try_as_void_ptr_capsule as a free function (#4539)
* Move try_as_void_ptr_capsule out from modified_type_caster_generic_load_impl. * Try fixing clangtidy
1 parent 480eb36 commit 114c0f2

File tree

1 file changed

+34
-22
lines changed

1 file changed

+34
-22
lines changed

include/pybind11/detail/smart_holder_type_casters.h

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,37 @@ struct is_smart_holder_type<smart_holder> : std::true_type {};
3737
inline void register_instance(instance *self, void *valptr, const type_info *tinfo);
3838
inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo);
3939

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;
4644
}
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;
4771
}
4872

4973
// 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 {
120144
}
121145

122146
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;
139151
}
140152
return false;
141153
}

0 commit comments

Comments
 (0)