| 169 | } // namespace |
| 170 | |
| 171 | TEST_SUBMODULE(copy_move_policies, m) { |
| 172 | // test_lacking_copy_ctor |
| 173 | py::class_<lacking_copy_ctor>(m, "lacking_copy_ctor") |
| 174 | .def_static("get_one", &lacking_copy_ctor::get_one, py::return_value_policy::copy); |
| 175 | // test_lacking_move_ctor |
| 176 | py::class_<lacking_move_ctor>(m, "lacking_move_ctor") |
| 177 | .def_static("get_one", &lacking_move_ctor::get_one, py::return_value_policy::move); |
| 178 | |
| 179 | // test_move_and_copy_casts |
| 180 | // NOLINTNEXTLINE(performance-unnecessary-value-param) |
| 181 | m.def("move_and_copy_casts", [](const py::object &o) { |
| 182 | int r = 0; |
| 183 | r += py::cast<MoveOrCopyInt>(o).value; /* moves */ |
| 184 | r += py::cast<MoveOnlyInt>(o).value; /* moves */ |
| 185 | r += py::cast<CopyOnlyInt>(o).value; /* copies */ |
| 186 | auto m1(py::cast<MoveOrCopyInt>(o)); /* moves */ |
| 187 | auto m2(py::cast<MoveOnlyInt>(o)); /* moves */ |
| 188 | auto m3(py::cast<CopyOnlyInt>(o)); /* copies */ |
| 189 | r += m1.value + m2.value + m3.value; |
| 190 | |
| 191 | return r; |
| 192 | }); |
| 193 | |
| 194 | // test_move_and_copy_loads |
| 195 | m.def("move_only", [](MoveOnlyInt m) { return m.value; }); |
| 196 | // NOLINTNEXTLINE(performance-unnecessary-value-param): we want to test copying |
| 197 | m.def("move_or_copy", [](MoveOrCopyInt m) { return m.value; }); |
| 198 | // NOLINTNEXTLINE(performance-unnecessary-value-param): we want to test copying |
| 199 | m.def("copy_only", [](CopyOnlyInt m) { return m.value; }); |
| 200 | m.def("move_pair", |
| 201 | [](std::pair<MoveOnlyInt, MoveOrCopyInt> p) { return p.first.value + p.second.value; }); |
| 202 | m.def("move_tuple", [](std::tuple<MoveOnlyInt, MoveOrCopyInt, MoveOnlyInt> t) { |
| 203 | return std::get<0>(t).value + std::get<1>(t).value + std::get<2>(t).value; |
| 204 | }); |
| 205 | m.def("copy_tuple", [](std::tuple<CopyOnlyInt, CopyOnlyInt> t) { |
| 206 | return std::get<0>(t).value + std::get<1>(t).value; |
| 207 | }); |
| 208 | m.def("move_copy_nested", |
| 209 | [](std::pair<MoveOnlyInt, |
| 210 | std::pair<std::tuple<MoveOrCopyInt, CopyOnlyInt, std::tuple<MoveOnlyInt>>, |
| 211 | MoveOrCopyInt>> x) { |
| 212 | return x.first.value + std::get<0>(x.second.first).value |
| 213 | + std::get<1>(x.second.first).value |
| 214 | + std::get<0>(std::get<2>(x.second.first)).value + x.second.second.value; |
| 215 | }); |
| 216 | m.def("move_and_copy_cstats", []() { |
| 217 | ConstructorStats::gc(); |
| 218 | // Reset counts to 0 so that previous tests don't affect later ones: |
| 219 | auto &mc = ConstructorStats::get<MoveOrCopyInt>(); |
| 220 | mc.move_assignments = mc.move_constructions = mc.copy_assignments = mc.copy_constructions |
| 221 | = 0; |
| 222 | auto &mo = ConstructorStats::get<MoveOnlyInt>(); |
| 223 | mo.move_assignments = mo.move_constructions = mo.copy_assignments = mo.copy_constructions |
| 224 | = 0; |
| 225 | auto &co = ConstructorStats::get<CopyOnlyInt>(); |
| 226 | co.move_assignments = co.move_constructions = co.copy_assignments = co.copy_constructions |
| 227 | = 0; |
| 228 | py::dict d; |
nothing calls this directly
no test coverage detected