mirror of
https://github.com/pybind/pybind11.git
synced 2025-03-12 07:49:28 +00:00
Fix regression: container pointers not castable
PR #936 broke the ability to return a pointer to a stl container (and, likewise, to a tuple) because the added deduced type matched a non-const pointer argument: the pointer-accepting `cast` in PYBIND11_TYPE_CASTER had a `const type *`, which is a worse match for a non-const pointer than the universal reference template #936 added. This changes the provided TYPE_CASTER cast(ptr) to take the pointer by template arg (so that it will accept either const or non-const pointer). It has two other effects: it slightly reduces .so size (because many type casters never actually need the pointer cast at all), and it allows type casters to provide their untemplated pointer `cast()` that will take precedence over the templated version provided in the macro.
This commit is contained in:
parent
fad5d3386c
commit
67a0cc4eed
@ -892,14 +892,15 @@ public:
|
||||
type value; \
|
||||
public: \
|
||||
static PYBIND11_DESCR name() { return type_descr(py_name); } \
|
||||
static handle cast(const type *src, return_value_policy policy, handle parent) { \
|
||||
template <typename T_, enable_if_t<std::is_same<type, remove_cv_t<T_>>::value, int> = 0> \
|
||||
static handle cast(T_ *src, return_value_policy policy, handle parent) { \
|
||||
if (!src) return none().release(); \
|
||||
return cast(*src, policy, parent); \
|
||||
} \
|
||||
operator type*() { return &value; } \
|
||||
operator type&() { return value; } \
|
||||
operator type&&() && { return std::move(value); } \
|
||||
template <typename _T> using cast_op_type = pybind11::detail::movable_cast_op_type<_T>
|
||||
template <typename T_> using cast_op_type = pybind11::detail::movable_cast_op_type<T_>
|
||||
|
||||
|
||||
template <typename CharT> using is_std_char_type = any_of<
|
||||
|
@ -38,6 +38,9 @@ TEST_SUBMODULE(stl, m) {
|
||||
// test_vector
|
||||
m.def("cast_vector", []() { return std::vector<int>{1}; });
|
||||
m.def("load_vector", [](const std::vector<int> &v) { return v.at(0) == 1 && v.at(1) == 2; });
|
||||
// Unnumbered regression (caused by #936): pointers to stl containers aren't castable
|
||||
static std::vector<RValueCaster> lvv{2};
|
||||
m.def("cast_ptr_vector", []() { return &lvv; });
|
||||
|
||||
// test_array
|
||||
m.def("cast_array", []() { return std::array<int, 2> {{1 , 2}}; });
|
||||
@ -78,7 +81,6 @@ TEST_SUBMODULE(stl, m) {
|
||||
v.back()[1].back().emplace("a", RValueCaster{});
|
||||
return v;
|
||||
});
|
||||
static std::vector<RValueCaster> lvv{2};
|
||||
static std::array<RValueCaster, 2> lva;
|
||||
static std::unordered_map<std::string, RValueCaster> lvm{{"a", RValueCaster{}}, {"b", RValueCaster{}}};
|
||||
static std::unordered_map<std::string, std::vector<std::list<std::array<RValueCaster, 2>>>> lvn;
|
||||
|
@ -15,6 +15,9 @@ def test_vector(doc):
|
||||
assert doc(m.cast_vector) == "cast_vector() -> List[int]"
|
||||
assert doc(m.load_vector) == "load_vector(arg0: List[int]) -> bool"
|
||||
|
||||
# Test regression caused by 936: pointers to stl containers weren't castable
|
||||
assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
|
||||
|
||||
|
||||
def test_array(doc):
|
||||
"""std::array <-> list"""
|
||||
|
Loading…
Reference in New Issue
Block a user