@@ -290,6 +290,72 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>)
290290PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>)
291291PYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>)
292292
293+ namespace holder_caster_traits_test {
294+ struct example_base {};
295+ } // namespace holder_caster_traits_test
296+
297+ PYBIND11_NAMESPACE_BEGIN (PYBIND11_NAMESPACE)
298+ PYBIND11_NAMESPACE_BEGIN(detail)
299+
300+ // Negate this condition to demonstrate "ambiguous template instantiation" compilation error:
301+ #if defined(PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT)
302+ template <typename ExampleType>
303+ struct copyable_holder_caster_shared_ptr_with_smart_holder_support_enabled <
304+ ExampleType,
305+ enable_if_t <std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>>
306+ : std::false_type {};
307+ #endif
308+
309+ template <typename ExampleType, typename HolderType>
310+ struct copyable_holder_caster <
311+ ExampleType,
312+ HolderType,
313+ enable_if_t <std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>> {
314+ static constexpr auto name = const_name<ExampleType>();
315+
316+ static handle cast (const HolderType &, return_value_policy, handle) {
317+ return str (" copyable_holder_caster_traits_test" ).release ();
318+ }
319+ };
320+
321+ // Negate this condition to demonstrate "ambiguous template instantiation" compilation error:
322+ #if defined(PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT)
323+ template <typename ExampleType>
324+ struct move_only_holder_caster_unique_ptr_with_smart_holder_support_enabled <
325+ ExampleType,
326+ enable_if_t <std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>>
327+ : std::false_type {};
328+ #endif
329+
330+ template <typename ExampleType, typename HolderType>
331+ struct move_only_holder_caster <
332+ ExampleType,
333+ HolderType,
334+ enable_if_t <std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>> {
335+ static constexpr auto name = const_name<ExampleType>();
336+
337+ static handle cast (const HolderType &, return_value_policy, handle) {
338+ return str (" move_only_holder_caster_traits_test" ).release ();
339+ }
340+ };
341+
342+ PYBIND11_NAMESPACE_END (detail)
343+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
344+
345+ namespace holder_caster_traits_test {
346+
347+ struct example_drvd : example_base {};
348+
349+ void wrap (py::module_ &m) {
350+ m.def (" return_std_shared_ptr_example_drvd" ,
351+ // NOLINTNEXTLINE(modernize-make-shared)
352+ []() { return std::shared_ptr<example_drvd>(new example_drvd ()); });
353+ m.def (" return_std_unique_ptr_example_drvd" ,
354+ []() { return std::unique_ptr<example_drvd>(new example_drvd ()); });
355+ }
356+
357+ } // namespace holder_caster_traits_test
358+
293359TEST_SUBMODULE (smart_ptr, m) {
294360 // Please do not interleave `struct` and `class` definitions with bindings code,
295361 // but implement `struct`s and `class`es in the anonymous namespace above.
@@ -482,4 +548,6 @@ TEST_SUBMODULE(smart_ptr, m) {
482548 .def (py::init<>())
483549 .def_readwrite (" ptr" ,
484550 &ContainerUsingPrivateESFT::ptr); // <- access ESFT through shared_ptr
551+
552+ holder_caster_traits_test::wrap (m);
485553}
0 commit comments