Allow perfect forwarding of method args (#2048)

This commit is contained in:
Robert Haschke 2020-07-07 15:56:07 +02:00 committed by GitHub
parent 1b0bf352fa
commit f2226aefe0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 9 additions and 4 deletions

View File

@ -75,7 +75,7 @@ public:
/// Construct a cpp_function from a class method (non-const, no ref-qualifier) /// Construct a cpp_function from a class method (non-const, no ref-qualifier)
template <typename Return, typename Class, typename... Arg, typename... Extra> template <typename Return, typename Class, typename... Arg, typename... Extra>
cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) { cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) {
initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); }, initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
(Return (*) (Class *, Arg...)) nullptr, extra...); (Return (*) (Class *, Arg...)) nullptr, extra...);
} }
@ -91,7 +91,7 @@ public:
/// Construct a cpp_function from a class method (const, no ref-qualifier) /// Construct a cpp_function from a class method (const, no ref-qualifier)
template <typename Return, typename Class, typename... Arg, typename... Extra> template <typename Return, typename Class, typename... Arg, typename... Extra>
cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) { cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) {
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); }, initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
(Return (*)(const Class *, Arg ...)) nullptr, extra...); (Return (*)(const Class *, Arg ...)) nullptr, extra...);
} }

View File

@ -21,6 +21,7 @@ public:
ExampleMandA() { print_default_created(this); } ExampleMandA() { print_default_created(this); }
ExampleMandA(int value) : value(value) { print_created(this, value); } ExampleMandA(int value) : value(value) { print_created(this, value); }
ExampleMandA(const ExampleMandA &e) : value(e.value) { print_copy_created(this); } ExampleMandA(const ExampleMandA &e) : value(e.value) { print_copy_created(this); }
ExampleMandA(std::string&&) {}
ExampleMandA(ExampleMandA &&e) : value(e.value) { print_move_created(this); } ExampleMandA(ExampleMandA &&e) : value(e.value) { print_move_created(this); }
~ExampleMandA() { print_destroyed(this); } ~ExampleMandA() { print_destroyed(this); }
@ -43,6 +44,8 @@ public:
void add9(int *other) { value += *other; } // passing by pointer void add9(int *other) { value += *other; } // passing by pointer
void add10(const int *other) { value += *other; } // passing by const pointer void add10(const int *other) { value += *other; } // passing by const pointer
void consume_str(std::string&&) {}
ExampleMandA self1() { return *this; } // return by value ExampleMandA self1() { return *this; } // return by value
ExampleMandA &self2() { return *this; } // return by reference ExampleMandA &self2() { return *this; } // return by reference
const ExampleMandA &self3() { return *this; } // return by const reference const ExampleMandA &self3() { return *this; } // return by const reference
@ -150,6 +153,7 @@ TEST_SUBMODULE(methods_and_attributes, m) {
py::class_<ExampleMandA> emna(m, "ExampleMandA"); py::class_<ExampleMandA> emna(m, "ExampleMandA");
emna.def(py::init<>()) emna.def(py::init<>())
.def(py::init<int>()) .def(py::init<int>())
.def(py::init<std::string&&>())
.def(py::init<const ExampleMandA&>()) .def(py::init<const ExampleMandA&>())
.def("add1", &ExampleMandA::add1) .def("add1", &ExampleMandA::add1)
.def("add2", &ExampleMandA::add2) .def("add2", &ExampleMandA::add2)
@ -161,6 +165,7 @@ TEST_SUBMODULE(methods_and_attributes, m) {
.def("add8", &ExampleMandA::add8) .def("add8", &ExampleMandA::add8)
.def("add9", &ExampleMandA::add9) .def("add9", &ExampleMandA::add9)
.def("add10", &ExampleMandA::add10) .def("add10", &ExampleMandA::add10)
.def("consume_str", &ExampleMandA::consume_str)
.def("self1", &ExampleMandA::self1) .def("self1", &ExampleMandA::self1)
.def("self2", &ExampleMandA::self2) .def("self2", &ExampleMandA::self2)
.def("self3", &ExampleMandA::self3) .def("self3", &ExampleMandA::self3)

View File

@ -58,8 +58,8 @@ def test_methods_and_attributes():
assert cstats.alive() == 0 assert cstats.alive() == 0
assert cstats.values() == ["32"] assert cstats.values() == ["32"]
assert cstats.default_constructions == 1 assert cstats.default_constructions == 1
assert cstats.copy_constructions == 3 assert cstats.copy_constructions == 2
assert cstats.move_constructions >= 1 assert cstats.move_constructions >= 2
assert cstats.copy_assignments == 0 assert cstats.copy_assignments == 0
assert cstats.move_assignments == 0 assert cstats.move_assignments == 0