Skip to content

Commit d7dd901

Browse files
authored
Support casts of const-qualified unique_ptrs (#988)
This uses the same technique that the `shared_ptr` type caster does. The updated test previously failed because of an invalid conversion from `const void*` to `void*`
1 parent 9b3afa9 commit d7dd901

File tree

2 files changed

+8
-7
lines changed

2 files changed

+8
-7
lines changed

include/nanobind/stl/unique_ptr.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct type_caster<std::unique_ptr<T, Deleter>> {
4848
static constexpr bool IsClass = true;
4949
using Value = std::unique_ptr<T, Deleter>;
5050
using Caster = make_caster<T>;
51+
using Td = std::decay_t<T>;
5152

5253
static constexpr bool IsDefaultDeleter =
5354
std::is_same_v<Deleter, std::default_delete<T>>;
@@ -116,18 +117,18 @@ struct type_caster<std::unique_ptr<T, Deleter>> {
116117
if constexpr (IsNanobindDeleter)
117118
cpp_delete = value.get_deleter().owned_by_cpp();
118119

119-
T *ptr = value.get();
120-
const std::type_info *type = &typeid(T);
120+
Td *ptr = (Td *) value.get();
121+
const std::type_info *type = &typeid(Td);
121122
if (!ptr)
122123
return none().release();
123124

124125
constexpr bool has_type_hook =
125-
!std::is_base_of_v<std::false_type, type_hook<T>>;
126+
!std::is_base_of_v<std::false_type, type_hook<Td>>;
126127
if constexpr (has_type_hook)
127-
type = type_hook<T>::get(ptr);
128+
type = type_hook<Td>::get(ptr);
128129

129130
handle result;
130-
if constexpr (!std::is_polymorphic_v<T>) {
131+
if constexpr (!std::is_polymorphic_v<Td>) {
131132
result = nb_type_put_unique(type, ptr, cleanup, cpp_delete);
132133
} else {
133134
const std::type_info *type_p =
@@ -161,7 +162,7 @@ struct type_caster<std::unique_ptr<T, Deleter>> {
161162
!nb_type_relinquish_ownership(src.ptr(), IsDefaultDeleter))
162163
throw next_overload();
163164

164-
T *p = caster.operator T *();
165+
Td *p = caster.operator Td *();
165166

166167
Value value;
167168
if constexpr (IsNanobindDeleter)

tests/test_holders.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ NB_MODULE(test_holders_ext, m) {
154154
// ------- unique_ptr -------
155155

156156
m.def("unique_from_cpp",
157-
[](int val) { return std::make_unique<Example>(val); },
157+
[](int val) { return std::make_unique<const Example>(val); },
158158
nb::arg() = 1);
159159
m.def("unique_from_cpp_2", []() {
160160
return std::unique_ptr<Example, nb::deleter<Example>>(new Example(2));

0 commit comments

Comments
 (0)