-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[smart_holder] Auto select return value policy for clif_automatic #4381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
5b7d08e
d1b36c9
b7f2e9f
5b7bd24
8f992dd
853c556
74a9e7a
5f310ab
2e3c2b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,75 @@ | ||
#include <pybind11/smart_holder.h> | ||
|
||
#include "pybind11_tests.h" | ||
|
||
namespace test_return_value_policy_override { | ||
|
||
struct some_type {}; | ||
|
||
struct obj { | ||
std::string mtxt; | ||
obj(const std::string &mtxt_) : mtxt(mtxt_) {} | ||
obj(const obj &other) { mtxt = other.mtxt + "_CpCtor"; } | ||
obj(obj &&other) { mtxt = other.mtxt + "_MvCtor"; } | ||
obj &operator=(const obj &other) { | ||
mtxt = other.mtxt + "_CpCtor"; | ||
return *this; | ||
} | ||
obj &operator=(obj &&other) { | ||
mtxt = other.mtxt + "_MvCtor"; | ||
return *this; | ||
} | ||
}; | ||
|
||
struct nocopy { | ||
std::string mtxt; | ||
nocopy(const std::string &mtxt_) : mtxt(mtxt_) {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't you still need to delete the copy ctor? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing this out. I forgot this. I deleted the copy ctor. |
||
nocopy(const nocopy &) = delete; | ||
nocopy(nocopy &&other) { mtxt = other.mtxt + "_MvCtor"; } | ||
nocopy &operator=(const nocopy &) = delete; | ||
nocopy &operator=(nocopy &&other) { | ||
mtxt = other.mtxt + "_MvCtor"; | ||
return *this; | ||
} | ||
}; | ||
|
||
obj *return_pointer() { | ||
static obj value("pointer"); | ||
return &value; | ||
} | ||
|
||
const obj *return_const_pointer() { | ||
static obj value("const_pointer"); | ||
return &value; | ||
} | ||
|
||
obj &return_reference() { | ||
static obj value("reference"); | ||
return value; | ||
} | ||
|
||
const obj &return_const_reference() { | ||
static obj value("const_reference"); | ||
return value; | ||
} | ||
|
||
std::shared_ptr<obj> return_shared_pointer() { | ||
return std::shared_ptr<obj>(new obj("shared_pointer")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initially I used |
||
} | ||
|
||
std::unique_ptr<obj> return_unique_pointer() { | ||
return std::unique_ptr<obj>(new obj("unique_pointer")); | ||
} | ||
|
||
nocopy &return_reference_nocopy() { | ||
static nocopy value("reference_nocopy"); | ||
return value; | ||
} | ||
|
||
} // namespace test_return_value_policy_override | ||
|
||
using test_return_value_policy_override::nocopy; | ||
using test_return_value_policy_override::obj; | ||
using test_return_value_policy_override::some_type; | ||
|
||
namespace pybind11 { | ||
|
@@ -51,6 +115,9 @@ struct type_caster<some_type> : type_caster_base<some_type> { | |
} // namespace detail | ||
} // namespace pybind11 | ||
|
||
PYBIND11_SMART_HOLDER_TYPE_CASTERS(obj) | ||
PYBIND11_SMART_HOLDER_TYPE_CASTERS(nocopy) | ||
|
||
TEST_SUBMODULE(return_value_policy_override, m) { | ||
m.def("return_value_with_default_policy", []() { return some_type(); }); | ||
m.def( | ||
|
@@ -79,4 +146,39 @@ TEST_SUBMODULE(return_value_policy_override, m) { | |
return &value; | ||
}, | ||
py::return_value_policy::_clif_automatic); | ||
|
||
py::classh<obj>(m, "object").def(py::init<std::string>()).def_readonly("mtxt", &obj::mtxt); | ||
m.def( | ||
"return_object_value_with_policy_clif_automatic", | ||
[]() { return obj("value"); }, | ||
py::return_value_policy::_clif_automatic); | ||
// test_return_value_policy_override::return_pointer with default policy | ||
// causes crash | ||
m.def("return_object_pointer_with_policy_clif_automatic", | ||
&test_return_value_policy_override::return_pointer, | ||
py::return_value_policy::_clif_automatic); | ||
// test_return_value_policy_override::return_const_pointer with default | ||
// policy causes crash | ||
m.def("return_object_const_pointer_with_policy_clif_automatic", | ||
&test_return_value_policy_override::return_const_pointer, | ||
py::return_value_policy::_clif_automatic); | ||
m.def("return_object_reference_with_policy_clif_automatic", | ||
&test_return_value_policy_override::return_reference, | ||
py::return_value_policy::_clif_automatic); | ||
m.def("return_object_const_reference_with_policy_clif_automatic", | ||
&test_return_value_policy_override::return_const_reference, | ||
py::return_value_policy::_clif_automatic); | ||
m.def("return_object_unique_ptr_with_policy_clif_automatic", | ||
&test_return_value_policy_override::return_unique_pointer, | ||
py::return_value_policy::_clif_automatic); | ||
m.def("return_object_shared_ptr_with_policy_clif_automatic", | ||
&test_return_value_policy_override::return_shared_pointer, | ||
py::return_value_policy::_clif_automatic); | ||
|
||
py::classh<nocopy>(m, "nocopy") | ||
.def(py::init<std::string>()) | ||
.def_readonly("mtxt", &nocopy::mtxt); | ||
m.def("return_nocopy_reference_with_policy_clif_automatic", | ||
&test_return_value_policy_override::return_reference_nocopy, | ||
py::return_value_policy::_clif_automatic); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
obj
is usually used for instances, it's surprising as a type name.The combinations of copyable/movable keep coming up, it would be good have some systematic naming that we could use throughout. What do you think about
?
With a comment like:
Question that's maybe beyond this PR: do we have (or would it be safest) to add tests for the other two combinations?
IIUC here you have only
type_cp1_mv1
andtype_cp0_mv1
, is that correct?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your suggestions. I updated the PR with more tests.