Commit f2226aef by Robert Haschke Committed by GitHub

Allow perfect forwarding of method args (#2048)

parent 1b0bf352
...@@ -75,7 +75,7 @@ public: ...@@ -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: ...@@ -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...);
} }
......
...@@ -21,6 +21,7 @@ public: ...@@ -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: ...@@ -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) { ...@@ -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) { ...@@ -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)
......
...@@ -58,8 +58,8 @@ def test_methods_and_attributes(): ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment