| 91 | |
| 92 | template <typename PythonType> |
| 93 | py::list test_random_access_iterator(const PythonType &x) { |
| 94 | if (x.size() < 5) { |
| 95 | throw py::value_error("Please provide at least 5 elements for testing."); |
| 96 | } |
| 97 | |
| 98 | auto checks = py::list(); |
| 99 | auto assert_equal = [&checks](py::handle a, py::handle b) { |
| 100 | auto result = PyObject_RichCompareBool(a.ptr(), b.ptr(), Py_EQ); |
| 101 | if (result == -1) { |
| 102 | throw py::error_already_set(); |
| 103 | } |
| 104 | checks.append(result != 0); |
| 105 | }; |
| 106 | |
| 107 | auto it = x.begin(); |
| 108 | assert_equal(x[0], *it); |
| 109 | assert_equal(x[0], it[0]); |
| 110 | assert_equal(x[1], it[1]); |
| 111 | |
| 112 | assert_equal(x[1], *(++it)); |
| 113 | assert_equal(x[1], *(it++)); |
| 114 | assert_equal(x[2], *it); |
| 115 | assert_equal(x[3], *(it += 1)); |
| 116 | assert_equal(x[2], *(--it)); |
| 117 | assert_equal(x[2], *(it--)); |
| 118 | assert_equal(x[1], *it); |
| 119 | assert_equal(x[0], *(it -= 1)); |
| 120 | |
| 121 | assert_equal(it->attr("real"), x[0].attr("real")); |
| 122 | assert_equal((it + 1)->attr("real"), x[1].attr("real")); |
| 123 | |
| 124 | assert_equal(x[1], *(it + 1)); |
| 125 | assert_equal(x[1], *(1 + it)); |
| 126 | it += 3; |
| 127 | assert_equal(x[1], *(it - 2)); |
| 128 | |
| 129 | checks.append(static_cast<std::size_t>(x.end() - x.begin()) == x.size()); |
| 130 | checks.append((x.begin() + static_cast<std::ptrdiff_t>(x.size())) == x.end()); |
| 131 | checks.append(x.begin() < x.end()); |
| 132 | |
| 133 | return checks; |
| 134 | } |
| 135 | |
| 136 | TEST_SUBMODULE(sequences_and_iterators, m) { |
| 137 | // test_sliceable |