mirror of
https://github.com/pybind/pybind11.git
synced 2026-05-05 06:01:36 +00:00
fix: <ranges> support for py::tuple and py::list (#5314)
* feat: add `<ranges>` support for `py::tuple` and `py::list` * fix: format the code * fix: disable `ranges` in clang < 16 * refactor: move `<ranges>` test macro to `test_pytypes.h` * refactor: seperate `ranges` test into 3 funcs * style: compress the if statement * style: pre-commit fixes * style: better formatting --------- Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -13,6 +13,14 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
//__has_include has been part of C++17, no need to check it
|
||||
#if defined(PYBIND11_CPP20) && __has_include(<ranges>)
|
||||
# if !defined(PYBIND11_COMPILER_CLANG) || __clang_major__ >= 16 // llvm/llvm-project#52696
|
||||
# define PYBIND11_TEST_PYTYPES_HAS_RANGES
|
||||
# include <ranges>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace external {
|
||||
namespace detail {
|
||||
bool check(PyObject *o) { return PyFloat_Check(o) != 0; }
|
||||
@@ -923,4 +931,59 @@ TEST_SUBMODULE(pytypes, m) {
|
||||
#else
|
||||
m.attr("defined_PYBIND11_TYPING_H_HAS_STRING_LITERAL") = false;
|
||||
#endif
|
||||
|
||||
#if defined(PYBIND11_TEST_PYTYPES_HAS_RANGES)
|
||||
|
||||
// test_tuple_ranges
|
||||
m.def("tuple_iterator_default_initialization", []() {
|
||||
using TupleIterator = decltype(std::declval<py::tuple>().begin());
|
||||
static_assert(std::random_access_iterator<TupleIterator>);
|
||||
return TupleIterator{} == TupleIterator{};
|
||||
});
|
||||
|
||||
m.def("transform_tuple_plus_one", [](py::tuple &tpl) {
|
||||
py::list ret{};
|
||||
for (auto it : tpl | std::views::transform([](auto &o) { return py::cast<int>(o) + 1; })) {
|
||||
ret.append(py::int_(it));
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
|
||||
// test_list_ranges
|
||||
m.def("list_iterator_default_initialization", []() {
|
||||
using ListIterator = decltype(std::declval<py::list>().begin());
|
||||
static_assert(std::random_access_iterator<ListIterator>);
|
||||
return ListIterator{} == ListIterator{};
|
||||
});
|
||||
|
||||
m.def("transform_list_plus_one", [](py::list &lst) {
|
||||
py::list ret{};
|
||||
for (auto it : lst | std::views::transform([](auto &o) { return py::cast<int>(o) + 1; })) {
|
||||
ret.append(py::int_(it));
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
|
||||
// test_dict_ranges
|
||||
m.def("dict_iterator_default_initialization", []() {
|
||||
using DictIterator = decltype(std::declval<py::dict>().begin());
|
||||
static_assert(std::forward_iterator<DictIterator>);
|
||||
return DictIterator{} == DictIterator{};
|
||||
});
|
||||
|
||||
m.def("transform_dict_plus_one", [](py::dict &dct) {
|
||||
py::list ret{};
|
||||
for (auto it : dct | std::views::transform([](auto &o) {
|
||||
return std::pair{py::cast<int>(o.first) + 1,
|
||||
py::cast<int>(o.second) + 1};
|
||||
})) {
|
||||
ret.append(py::make_tuple(py::int_(it.first), py::int_(it.second)));
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
|
||||
m.attr("defined_PYBIND11_TEST_PYTYPES_HAS_RANGES") = true;
|
||||
#else
|
||||
m.attr("defined_PYBIND11_TEST_PYTYPES_HAS_RANGES") = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user