mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +00:00
Accept any sequence type as std::tuple or std::pair
This is more Pythonic and compliments the std::vector and std::list casters which also accept sequences.
This commit is contained in:
parent
719c1733dd
commit
107285b353
@ -737,12 +737,12 @@ template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
|
|||||||
typedef std::pair<T1, T2> type;
|
typedef std::pair<T1, T2> type;
|
||||||
public:
|
public:
|
||||||
bool load(handle src, bool convert) {
|
bool load(handle src, bool convert) {
|
||||||
if (!src)
|
if (!isinstance<sequence>(src))
|
||||||
return false;
|
return false;
|
||||||
else if (!PyTuple_Check(src.ptr()) || PyTuple_Size(src.ptr()) != 2)
|
const auto seq = reinterpret_borrow<sequence>(src);
|
||||||
|
if (seq.size() != 2)
|
||||||
return false;
|
return false;
|
||||||
return first.load(PyTuple_GET_ITEM(src.ptr(), 0), convert) &&
|
return first.load(seq[0], convert) && second.load(seq[1], convert);
|
||||||
second.load(PyTuple_GET_ITEM(src.ptr(), 1), convert);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static handle cast(const type &src, return_value_policy policy, handle parent) {
|
static handle cast(const type &src, return_value_policy policy, handle parent) {
|
||||||
@ -779,9 +779,12 @@ template <typename... Tuple> class type_caster<std::tuple<Tuple...>> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool load(handle src, bool convert) {
|
bool load(handle src, bool convert) {
|
||||||
if (!src || !PyTuple_Check(src.ptr()) || PyTuple_GET_SIZE(src.ptr()) != size)
|
if (!isinstance<sequence>(src))
|
||||||
return false;
|
return false;
|
||||||
return load_impl(src, convert, indices{});
|
const auto seq = reinterpret_borrow<sequence>(src);
|
||||||
|
if (seq.size() != size)
|
||||||
|
return false;
|
||||||
|
return load_impl(seq, convert, indices{});
|
||||||
}
|
}
|
||||||
|
|
||||||
static handle cast(const type &src, return_value_policy policy, handle parent) {
|
static handle cast(const type &src, return_value_policy policy, handle parent) {
|
||||||
@ -800,11 +803,11 @@ protected:
|
|||||||
template <size_t... Is>
|
template <size_t... Is>
|
||||||
type implicit_cast(index_sequence<Is...>) { return type(cast_op<Tuple>(std::get<Is>(value))...); }
|
type implicit_cast(index_sequence<Is...>) { return type(cast_op<Tuple>(std::get<Is>(value))...); }
|
||||||
|
|
||||||
static constexpr bool load_impl(handle, bool, index_sequence<>) { return true; }
|
static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; }
|
||||||
|
|
||||||
template <size_t... Is>
|
template <size_t... Is>
|
||||||
bool load_impl(handle src, bool convert, index_sequence<Is...>) {
|
bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {
|
||||||
for (bool r : {std::get<Is>(value).load(PyTuple_GET_ITEM(src.ptr(), Is), convert)...})
|
for (bool r : {std::get<Is>(value).load(seq[Is], convert)...})
|
||||||
if (!r)
|
if (!r)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -93,6 +93,9 @@ def test_instance(capture):
|
|||||||
|
|
||||||
assert instance.pair_passthrough((True, "test")) == ("test", True)
|
assert instance.pair_passthrough((True, "test")) == ("test", True)
|
||||||
assert instance.tuple_passthrough((True, "test", 5)) == (5, "test", True)
|
assert instance.tuple_passthrough((True, "test", 5)) == (5, "test", True)
|
||||||
|
# Any sequence can be cast to a std::pair or std::tuple
|
||||||
|
assert instance.pair_passthrough([True, "test"]) == ("test", True)
|
||||||
|
assert instance.tuple_passthrough([True, "test", 5]) == (5, "test", True)
|
||||||
|
|
||||||
assert instance.get_bytes_from_string().decode() == "foo"
|
assert instance.get_bytes_from_string().decode() == "foo"
|
||||||
assert instance.get_bytes_from_str().decode() == "bar"
|
assert instance.get_bytes_from_str().decode() == "bar"
|
||||||
|
Loading…
Reference in New Issue
Block a user