@@ -1496,9 +1496,46 @@ struct copyable_holder_caster : public type_caster_base<type> {
1496
1496
holder_type holder;
1497
1497
};
1498
1498
1499
- // / Specialize for the common std::shared_ptr, so users don't need to
1499
+ // / Specialize type_caster for std::shared_ptr<T>.
1500
+ // / This is the same as copyable_holder_caster, except that when casting to C++
1501
+ // / we keep the Python object alive through the shared_ptr as e.g. virtual
1502
+ // / functions and derived state might be defined there.
1500
1503
template <typename T>
1501
- class type_caster <std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> { };
1504
+ class type_caster <std::shared_ptr<T>>
1505
+ {
1506
+ PYBIND11_TYPE_CASTER (std::shared_ptr<T>, _(PYBIND11_STRING_NAME));
1507
+
1508
+ // Re-use copyable_holder_caster
1509
+ using BaseCaster = copyable_holder_caster<T, std::shared_ptr<T>>;
1510
+
1511
+ bool load (pybind11::handle src, bool b)
1512
+ {
1513
+ BaseCaster bc;
1514
+ bool success = bc.load (src, b);
1515
+ if (!success)
1516
+ {
1517
+ return false ;
1518
+ }
1519
+
1520
+ // * Get src as a py::object
1521
+ // * Construct a shared_ptr to the py::object
1522
+ auto py_obj = reinterpret_borrow<object> (src);
1523
+ auto py_obj_ptr = std::make_shared<object> (py_obj);
1524
+
1525
+ // * Use BaseCaster to get it as the shared_ptr<T>
1526
+ // * Use this to make an aliased shared_ptr<T> that keeps the py::object alive
1527
+ auto base_ptr = static_cast <std::shared_ptr<T>> (bc);
1528
+ value = std::shared_ptr<T> (py_obj_ptr, base_ptr.get ());
1529
+ return true ;
1530
+ }
1531
+
1532
+ static handle cast (std::shared_ptr<T> sp,
1533
+ return_value_policy rvp,
1534
+ handle h)
1535
+ {
1536
+ return BaseCaster::cast (sp, rvp, h);
1537
+ }
1538
+ };
1502
1539
1503
1540
template <typename type, typename holder_type>
1504
1541
struct move_only_holder_caster {
@@ -1540,6 +1577,9 @@ template <typename base, typename holder> struct is_holder_type :
1540
1577
template <typename base, typename deleter> struct is_holder_type <base, std::unique_ptr<base, deleter>> :
1541
1578
std::true_type {};
1542
1579
1580
+ template <typename T>
1581
+ struct is_holder_type <T, std::shared_ptr<T>> : std::true_type {};
1582
+
1543
1583
template <typename T> struct handle_type_name { static constexpr auto name = _<T>(); };
1544
1584
template <> struct handle_type_name <bytes> { static constexpr auto name = _(PYBIND11_BYTES_NAME); };
1545
1585
template <> struct handle_type_name <args> { static constexpr auto name = _(" *args" ); };
0 commit comments