@@ -1515,15 +1515,86 @@ template <typename T>
1515
1515
class type_caster <std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> { };
1516
1516
1517
1517
template <typename type, typename holder_type>
1518
- struct move_only_holder_caster {
1519
- static_assert (std::is_base_of<type_caster_base<type>, type_caster<type>>::value,
1518
+ struct move_only_holder_caster : public type_caster_base <type> {
1519
+ public:
1520
+ using base = type_caster_base<type>;
1521
+ static_assert (std::is_base_of<base, type_caster<type>>::value,
1520
1522
" Holder classes are only supported for custom types" );
1523
+ using base::base;
1524
+ using base::cast;
1525
+ using base::typeinfo;
1526
+ using base::value;
1527
+
1528
+ bool load (handle& src, bool convert) {
1529
+ bool success = base::template load_impl<move_only_holder_caster<type, holder_type>>(src, convert);
1530
+ if (success) // if loading was successful, the instance needs to be withdrawn from src
1531
+ // However, setting the src pointer to None is not sufficient.
1532
+ src.ptr () = none ().release ().ptr ();
1533
+ return success;
1534
+ }
1535
+
1536
+ template <typename T> using cast_op_type = detail::movable_cast_op_type<T>;
1537
+
1538
+ explicit operator type*() { return this ->value ; }
1539
+ explicit operator type&() { return *(this ->value ); }
1540
+ explicit operator holder_type*() { return std::addressof (holder); }
1541
+
1542
+ // Workaround for Intel compiler bug
1543
+ // see pybind11 issue 94
1544
+ #if defined(__ICC) || defined(__INTEL_COMPILER)
1545
+ operator holder_type&() { return holder; }
1546
+ #else
1547
+ explicit operator holder_type&() { return holder; }
1548
+ #endif
1549
+ explicit operator holder_type&&() { value = nullptr ; return std::move (holder); }
1550
+
1551
+ static handle cast (const holder_type &src, return_value_policy, handle) {
1552
+ const auto *ptr = holder_helper<holder_type>::get (src);
1553
+ return type_caster_base<type>::cast_holder (ptr, &src);
1554
+ }
1555
+
1556
+ protected:
1557
+ friend class type_caster_generic ;
1558
+ void check_holder_compat () {
1559
+ // if (typeinfo->default_holder)
1560
+ // throw cast_error("Unable to load a custom holder type from a default-holder instance");
1561
+ }
1521
1562
1522
- static handle cast (holder_type &&src, return_value_policy, handle) {
1523
- auto *ptr = holder_helper<holder_type>::get (src);
1524
- return type_caster_base<type>::cast_holder (ptr, std::addressof (src));
1563
+ bool load_value (value_and_holder &&v_h) {
1564
+ if (v_h.holder_constructed ()) {
1565
+ value = v_h.value_ptr ();
1566
+ holder = std::move (v_h.template holder <holder_type>());
1567
+ return true ;
1568
+ } else {
1569
+ throw cast_error (" Unable to cast from non-held to held instance (T& to Holder<T>) "
1570
+ #if defined(NDEBUG)
1571
+ " (compile in debug mode for type information)" );
1572
+ #else
1573
+ " of type '" + type_id<holder_type>() + " ''" );
1574
+ #endif
1575
+ }
1576
+ }
1577
+
1578
+ template <typename T = holder_type, detail::enable_if_t <!std::is_constructible<T, const T &, type*>::value, int > = 0 >
1579
+ bool try_implicit_casts (handle, bool ) { return false ; }
1580
+
1581
+ template <typename T = holder_type, detail::enable_if_t <std::is_constructible<T, const T &, type*>::value, int > = 0 >
1582
+ bool try_implicit_casts (handle src, bool convert) {
1583
+ for (auto &cast : typeinfo->implicit_casts ) {
1584
+ move_only_holder_caster sub_caster (*cast.first );
1585
+ if (sub_caster.load (src, convert)) {
1586
+ value = cast.second (sub_caster.value );
1587
+ holder = holder_type (sub_caster.holder , (type *) value);
1588
+ return true ;
1589
+ }
1590
+ }
1591
+ return false ;
1525
1592
}
1526
- static constexpr auto name = type_caster_base<type>::name;
1593
+
1594
+ static bool try_direct_conversions (handle) { return false ; }
1595
+
1596
+
1597
+ holder_type holder;
1527
1598
};
1528
1599
1529
1600
template <typename type, typename deleter>
0 commit comments