mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-26 07:02:11 +00:00
Add failing optional test
This commit is contained in:
parent
8e85fadff2
commit
a3daf87d45
@ -50,6 +50,17 @@ namespace std {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <template <typename> typename OptionalImpl, typename T>
|
||||||
|
struct OptionalHolder
|
||||||
|
{
|
||||||
|
OptionalHolder() = default;
|
||||||
|
bool member_initialized() const {
|
||||||
|
return member && member->initialized;
|
||||||
|
}
|
||||||
|
OptionalImpl<T> member = T{};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
TEST_SUBMODULE(stl, m) {
|
TEST_SUBMODULE(stl, m) {
|
||||||
// test_vector
|
// test_vector
|
||||||
m.def("cast_vector", []() { return std::vector<int>{1}; });
|
m.def("cast_vector", []() { return std::vector<int>{1}; });
|
||||||
@ -154,6 +165,23 @@ TEST_SUBMODULE(stl, m) {
|
|||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
.def(py::init<int>());
|
.def(py::init<int>());
|
||||||
|
|
||||||
|
|
||||||
|
struct MoveOutDetector
|
||||||
|
{
|
||||||
|
MoveOutDetector() = default;
|
||||||
|
MoveOutDetector(const MoveOutDetector&) = default;
|
||||||
|
MoveOutDetector(MoveOutDetector&& other) noexcept
|
||||||
|
: initialized(other.initialized) {
|
||||||
|
// steal underlying resource
|
||||||
|
other.initialized = false;
|
||||||
|
}
|
||||||
|
bool initialized = true;
|
||||||
|
};
|
||||||
|
py::class_<MoveOutDetector>(m, "MoveOutDetector", "Class with move tracking")
|
||||||
|
.def(py::init<>())
|
||||||
|
.def_readonly("initialized", &MoveOutDetector::initialized);
|
||||||
|
|
||||||
|
|
||||||
#ifdef PYBIND11_HAS_OPTIONAL
|
#ifdef PYBIND11_HAS_OPTIONAL
|
||||||
// test_optional
|
// test_optional
|
||||||
m.attr("has_optional") = true;
|
m.attr("has_optional") = true;
|
||||||
@ -175,6 +203,12 @@ TEST_SUBMODULE(stl, m) {
|
|||||||
|
|
||||||
m.def("nodefer_none_optional", [](std::optional<int>) { return true; });
|
m.def("nodefer_none_optional", [](std::optional<int>) { return true; });
|
||||||
m.def("nodefer_none_optional", [](py::none) { return false; });
|
m.def("nodefer_none_optional", [](py::none) { return false; });
|
||||||
|
|
||||||
|
using opt_holder = OptionalHolder<std::optional, MoveOutDetector>;
|
||||||
|
py::class_<opt_holder>(m, "OptionalHolder", "Class with optional member")
|
||||||
|
.def(py::init<>())
|
||||||
|
.def_readonly("member", &opt_holder::member)
|
||||||
|
.def("member_initialized", &opt_holder::member_initialized);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PYBIND11_HAS_EXP_OPTIONAL
|
#ifdef PYBIND11_HAS_EXP_OPTIONAL
|
||||||
@ -195,6 +229,12 @@ TEST_SUBMODULE(stl, m) {
|
|||||||
m.def("test_no_assign_exp", [](const exp_opt_no_assign &x) {
|
m.def("test_no_assign_exp", [](const exp_opt_no_assign &x) {
|
||||||
return x ? x->value : 42;
|
return x ? x->value : 42;
|
||||||
}, py::arg_v("x", std::experimental::nullopt, "None"));
|
}, py::arg_v("x", std::experimental::nullopt, "None"));
|
||||||
|
|
||||||
|
using opt_exp_holder = OptionalHolder<std::experimental::optional, MoveOutDetector>;
|
||||||
|
py::class_<opt_exp_holder>(m, "OptionalExpHolder", "Class with optional member")
|
||||||
|
.def(py::init<>())
|
||||||
|
.def_readonly("member", &opt_exp_holder::member)
|
||||||
|
.def("member_initialized", &opt_exp_holder::member_initialized);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PYBIND11_HAS_VARIANT
|
#ifdef PYBIND11_HAS_VARIANT
|
||||||
|
@ -127,6 +127,11 @@ def test_optional():
|
|||||||
|
|
||||||
assert m.nodefer_none_optional(None)
|
assert m.nodefer_none_optional(None)
|
||||||
|
|
||||||
|
holder = m.OptionalHolder()
|
||||||
|
mvalue = holder.member
|
||||||
|
assert mvalue.initialized
|
||||||
|
assert holder.member_initialized()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not hasattr(m, "has_exp_optional"), reason='no <experimental/optional>')
|
@pytest.mark.skipif(not hasattr(m, "has_exp_optional"), reason='no <experimental/optional>')
|
||||||
def test_exp_optional():
|
def test_exp_optional():
|
||||||
@ -148,6 +153,11 @@ def test_exp_optional():
|
|||||||
assert m.test_no_assign_exp(m.NoAssign(43)) == 43
|
assert m.test_no_assign_exp(m.NoAssign(43)) == 43
|
||||||
pytest.raises(TypeError, m.test_no_assign_exp, 43)
|
pytest.raises(TypeError, m.test_no_assign_exp, 43)
|
||||||
|
|
||||||
|
holder = m.OptionalExpHolder()
|
||||||
|
mvalue = holder.member
|
||||||
|
assert mvalue.initialized
|
||||||
|
assert holder.member_initialized()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not hasattr(m, "load_variant"), reason='no <variant>')
|
@pytest.mark.skipif(not hasattr(m, "load_variant"), reason='no <variant>')
|
||||||
def test_variant(doc):
|
def test_variant(doc):
|
||||||
|
Loading…
Reference in New Issue
Block a user