feature: Support move-only iterators in py::make_*iterator (#4834)

* feature: Support move-only iterators in `py::make_*iterator`

* fix: Missing static assertion message

* fixup: Missing `explicit` in single argument constructors

* fix: Simplify tests: make existing iterator move-only

* fix: Missing `noexcept`
This commit is contained in:
Sergei Izmailov
2023-09-07 21:57:39 +09:00
committed by GitHub
parent 4a2f7e4681
commit c83605936b
2 changed files with 29 additions and 4 deletions

View File

@@ -28,6 +28,13 @@ class NonZeroIterator {
public:
explicit NonZeroIterator(const T *ptr) : ptr_(ptr) {}
// Make the iterator non-copyable and movable
NonZeroIterator(const NonZeroIterator &) = delete;
NonZeroIterator(NonZeroIterator &&) noexcept = default;
NonZeroIterator &operator=(const NonZeroIterator &) = delete;
NonZeroIterator &operator=(NonZeroIterator &&) noexcept = default;
const T &operator*() const { return *ptr_; }
NonZeroIterator &operator++() {
++ptr_;
@@ -78,6 +85,7 @@ private:
int value_;
};
using NonCopyableIntPair = std::pair<NonCopyableInt, NonCopyableInt>;
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableInt>);
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableIntPair>);
@@ -375,6 +383,17 @@ TEST_SUBMODULE(sequences_and_iterators, m) {
private:
std::vector<std::pair<int, int>> data_;
};
{
// #4383 : Make sure `py::make_*iterator` functions work with move-only iterators
using iterator_t = NonZeroIterator<std::pair<int, int>>;
static_assert(std::is_move_assignable<iterator_t>::value, "");
static_assert(std::is_move_constructible<iterator_t>::value, "");
static_assert(!std::is_copy_assignable<iterator_t>::value, "");
static_assert(!std::is_copy_constructible<iterator_t>::value, "");
}
py::class_<IntPairs>(m, "IntPairs")
.def(py::init<std::vector<std::pair<int, int>>>())
.def(