1010
1111#pragma once
1212
13+ #include " detail/argument_vector.h"
1314#include " detail/common.h"
1415#include " detail/descr.h"
16+ #include " detail/holder_caster_foreign_helpers.h"
1517#include " detail/native_enum_data.h"
1618#include " detail/type_caster_base.h"
1719#include " detail/typeid.h"
@@ -859,71 +861,6 @@ struct holder_helper {
859861 static auto get (const T &p) -> decltype(p.get()) { return p.get (); }
860862};
861863
862- struct holder_caster_foreign_helpers {
863- struct py_deleter {
864- void operator ()(const void *) const noexcept {
865- // Don't run the deleter if the interpreter has been shut down
866- if (Py_IsInitialized () == 0 ) {
867- return ;
868- }
869- gil_scoped_acquire guard;
870- Py_DECREF (o);
871- }
872-
873- PyObject *o;
874- };
875-
876- template <typename type>
877- static auto try_shared_from_this (type *value, std::shared_ptr<type> *holder_out)
878- -> decltype(value->shared_from_this (), bool()) {
879- // object derives from enable_shared_from_this;
880- // try to reuse an existing shared_ptr if one is known
881- if (auto existing = try_get_shared_from_this (value)) {
882- *holder_out = std::static_pointer_cast<type>(existing);
883- return true ;
884- }
885- return false ;
886- }
887-
888- template <typename type>
889- static bool try_shared_from_this (void *, std::shared_ptr<type> *) {
890- return false ;
891- }
892-
893- template <typename type>
894- static bool set_foreign_holder (handle src, type *value, std::shared_ptr<type> *holder_out) {
895- // We only support using std::shared_ptr<T> for foreign T, and
896- // it's done by creating a new shared_ptr control block that
897- // owns a reference to the original Python object.
898- if (value == nullptr ) {
899- *holder_out = {};
900- return true ;
901- }
902- if (try_shared_from_this (value, holder_out)) {
903- return true ;
904- }
905- *holder_out = std::shared_ptr<type>(value, py_deleter{src.inc_ref ().ptr ()});
906- return true ;
907- }
908-
909- template <typename type>
910- static bool
911- set_foreign_holder (handle src, const type *value, std::shared_ptr<const type> *holder_out) {
912- std::shared_ptr<type> holder_mut;
913- if (set_foreign_holder (src, const_cast <type *>(value), &holder_mut)) {
914- *holder_out = holder_mut;
915- return true ;
916- }
917- return false ;
918- }
919-
920- template <typename type>
921- static bool set_foreign_holder (handle, type *, ...) {
922- throw cast_error (" Unable to cast foreign type to held instance -- "
923- " only std::shared_ptr<T> is supported in this case" );
924- }
925- };
926-
927864// SMART_HOLDER_BAKEIN_FOLLOW_ON: Rewrite comment, with reference to shared_ptr specialization.
928865// / Type caster for holder types like std::shared_ptr, etc.
929866// / The SFINAE hook is provided to help work around the current lack of support
@@ -1284,8 +1221,8 @@ struct move_only_holder_caster<
12841221 }
12851222
12861223 bool set_foreign_holder (handle) {
1287- throw cast_error (" Foreign types cannot be converted to std::unique_ptr "
1288- " because we don't know how to make them relinquish "
1224+ throw cast_error (" Foreign instance cannot be converted to std::unique_ptr "
1225+ " because we don't know how to make it relinquish "
12891226 " ownership" );
12901227 }
12911228
@@ -1467,7 +1404,7 @@ struct handle_type_name<buffer> {
14671404};
14681405template <>
14691406struct handle_type_name <int_> {
1470- static constexpr auto name = io_name( " typing.SupportsInt " , " int" );
1407+ static constexpr auto name = const_name( " int" );
14711408};
14721409template <>
14731410struct handle_type_name <iterable> {
@@ -1479,7 +1416,7 @@ struct handle_type_name<iterator> {
14791416};
14801417template <>
14811418struct handle_type_name <float_> {
1482- static constexpr auto name = io_name( " typing.SupportsFloat " , " float" );
1419+ static constexpr auto name = const_name( " float" );
14831420};
14841421template <>
14851422struct handle_type_name <function> {
@@ -1600,6 +1537,21 @@ struct pyobject_caster {
16001537template <typename T>
16011538class type_caster <T, enable_if_t <is_pyobject<T>::value>> : public pyobject_caster<T> {};
16021539
1540+ template <>
1541+ class type_caster <float_> : public pyobject_caster<float_> {
1542+ public:
1543+ bool load (handle src, bool /* convert */ ) {
1544+ if (isinstance<float_>(src)) {
1545+ value = reinterpret_borrow<float_>(src);
1546+ } else if (isinstance<int_>(src)) {
1547+ value = float_ (reinterpret_borrow<int_>(src));
1548+ } else {
1549+ return false ;
1550+ }
1551+ return true ;
1552+ }
1553+ };
1554+
16031555// Our conditions for enabling moving are quite restrictive:
16041556// At compile time:
16051557// - T needs to be a non-const, non-pointer, non-reference type
@@ -2104,6 +2056,10 @@ using is_pos_only = std::is_same<intrinsic_t<T>, pos_only>;
21042056// forward declaration (definition in attr.h)
21052057struct function_record ;
21062058
2059+ // / (Inline size chosen mostly arbitrarily; 6 should pad function_call out to two cache lines
2060+ // / (16 pointers) in size.)
2061+ constexpr std::size_t arg_vector_small_size = 6 ;
2062+
21072063// / Internal data associated with a single function call
21082064struct function_call {
21092065 function_call (const function_record &f, handle p); // Implementation in attr.h
@@ -2112,10 +2068,10 @@ struct function_call {
21122068 const function_record &func;
21132069
21142070 // / Arguments passed to the function:
2115- std::vector<handle > args;
2071+ argument_vector<arg_vector_small_size > args;
21162072
21172073 // / The `convert` value the arguments should be loaded with
2118- std::vector< bool > args_convert;
2074+ args_convert_vector<arg_vector_small_size > args_convert;
21192075
21202076 // / Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if
21212077 // / present, are also in `args` but without a reference).
0 commit comments