From 613541947a0a2be1680785f95d04b68bcbc33c85 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 3 Aug 2016 23:45:08 -0400 Subject: [PATCH] Fix scoped enums and add scoped enum example PR #309 broke scoped enums, which failed to compile because the added: value == value2 comparison isn't valid for a scoped enum (they aren't implicitly convertible to the underlying type). This commit fixes it by explicitly converting the enum value to its underlying type before doing the comparison. It also adds a scoped enum example to the constants-and-functions example that triggers the problem fixed in this commit. --- example/example-constants-and-functions.cpp | 15 +++++++++++++++ example/example-constants-and-functions.py | 3 +++ example/example-constants-and-functions.ref | 2 ++ include/pybind11/pybind11.h | 4 ++-- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/example/example-constants-and-functions.cpp b/example/example-constants-and-functions.cpp index b71856cbe..d7f8ad174 100644 --- a/example/example-constants-and-functions.cpp +++ b/example/example-constants-and-functions.cpp @@ -14,6 +14,11 @@ enum EMyEnumeration { ESecondEntry }; +enum class ECMyEnum { + Two = 2, + Three +}; + class ExampleWithEnum { public: enum EMode { @@ -41,6 +46,10 @@ float test_function3(int i) { return (float) i / 2.f; } +void test_ecenum(ECMyEnum z) { + std::cout << "test_ecenum(ECMyEnum::" << (z == ECMyEnum::Two ? "Two" : "Three") << ")" << std::endl; +} + py::bytes return_bytes() { const char *data = "\x01\x00\x02\x00"; return std::string(data, 4); @@ -56,6 +65,7 @@ void init_ex_constants_and_functions(py::module &m) { m.def("test_function", &test_function1); m.def("test_function", &test_function2); m.def("test_function", &test_function3); + m.def("test_ecenum", &test_ecenum); m.attr("some_constant") = py::int_(14); py::enum_(m, "EMyEnumeration") @@ -63,6 +73,11 @@ void init_ex_constants_and_functions(py::module &m) { .value("ESecondEntry", ESecondEntry) .export_values(); + py::enum_(m, "ECMyEnum") + .value("Two", ECMyEnum::Two) + .value("Three", ECMyEnum::Three) + ; + py::class_ exenum_class(m, "ExampleWithEnum"); exenum_class.def_static("test_function", &ExampleWithEnum::test_function); py::enum_(exenum_class, "EMode") diff --git a/example/example-constants-and-functions.py b/example/example-constants-and-functions.py index f9292ee9e..0a5224a02 100755 --- a/example/example-constants-and-functions.py +++ b/example/example-constants-and-functions.py @@ -6,6 +6,7 @@ sys.path.append('.') from example import test_function from example import some_constant from example import EMyEnumeration +from example import ECMyEnum, test_ecenum from example import EFirstEntry from example import ExampleWithEnum from example import return_bytes @@ -20,6 +21,8 @@ print(test_function()) print(test_function(7)) print(test_function(EMyEnumeration.EFirstEntry)) print(test_function(EMyEnumeration.ESecondEntry)) +test_ecenum(ECMyEnum.Three) +test_ecenum(ECMyEnum.Two) print("enum->integer = %i" % int(EMyEnumeration.ESecondEntry)) print("integer->enum = %s" % str(EMyEnumeration(2))) diff --git a/example/example-constants-and-functions.ref b/example/example-constants-and-functions.ref index 1d08223f8..f82480694 100644 --- a/example/example-constants-and-functions.ref +++ b/example/example-constants-and-functions.ref @@ -10,6 +10,8 @@ test_function(enum=1) None test_function(enum=2) None +test_ecenum(ECMyEnum::Three) +test_ecenum(ECMyEnum::Two) enum->integer = 2 integer->enum = EMyEnumeration.ESecondEntry A constant = 14 diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index ae5a75420..6bab4a95e 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1019,9 +1019,9 @@ public: this->def("__init__", [](Type& value, UnderlyingType i) { new (&value) Type((Type) i); }); this->def("__int__", [](Type value) { return (UnderlyingType) value; }); this->def("__eq__", [](const Type &value, Type *value2) { return value2 && value == *value2; }); - this->def("__eq__", [](const Type &value, UnderlyingType value2) { return value == value2; }); + this->def("__eq__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value == value2; }); this->def("__ne__", [](const Type &value, Type *value2) { return !value2 || value != *value2; }); - this->def("__ne__", [](const Type &value, UnderlyingType value2) { return value != value2; }); + this->def("__ne__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value != value2; }); this->def("__hash__", [](const Type &value) { return (UnderlyingType) value; }); m_entries = entries; }