mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-26 15:12:01 +00:00
Merge pull request #313 from jagerman/scoped-enums
Fix scoped enums and add scoped enum example
This commit is contained in:
commit
2fb81afb59
@ -14,6 +14,11 @@ enum EMyEnumeration {
|
|||||||
ESecondEntry
|
ESecondEntry
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ECMyEnum {
|
||||||
|
Two = 2,
|
||||||
|
Three
|
||||||
|
};
|
||||||
|
|
||||||
class ExampleWithEnum {
|
class ExampleWithEnum {
|
||||||
public:
|
public:
|
||||||
enum EMode {
|
enum EMode {
|
||||||
@ -41,6 +46,10 @@ float test_function3(int i) {
|
|||||||
return (float) i / 2.f;
|
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() {
|
py::bytes return_bytes() {
|
||||||
const char *data = "\x01\x00\x02\x00";
|
const char *data = "\x01\x00\x02\x00";
|
||||||
return std::string(data, 4);
|
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_function1);
|
||||||
m.def("test_function", &test_function2);
|
m.def("test_function", &test_function2);
|
||||||
m.def("test_function", &test_function3);
|
m.def("test_function", &test_function3);
|
||||||
|
m.def("test_ecenum", &test_ecenum);
|
||||||
m.attr("some_constant") = py::int_(14);
|
m.attr("some_constant") = py::int_(14);
|
||||||
|
|
||||||
py::enum_<EMyEnumeration>(m, "EMyEnumeration")
|
py::enum_<EMyEnumeration>(m, "EMyEnumeration")
|
||||||
@ -63,6 +73,11 @@ void init_ex_constants_and_functions(py::module &m) {
|
|||||||
.value("ESecondEntry", ESecondEntry)
|
.value("ESecondEntry", ESecondEntry)
|
||||||
.export_values();
|
.export_values();
|
||||||
|
|
||||||
|
py::enum_<ECMyEnum>(m, "ECMyEnum")
|
||||||
|
.value("Two", ECMyEnum::Two)
|
||||||
|
.value("Three", ECMyEnum::Three)
|
||||||
|
;
|
||||||
|
|
||||||
py::class_<ExampleWithEnum> exenum_class(m, "ExampleWithEnum");
|
py::class_<ExampleWithEnum> exenum_class(m, "ExampleWithEnum");
|
||||||
exenum_class.def_static("test_function", &ExampleWithEnum::test_function);
|
exenum_class.def_static("test_function", &ExampleWithEnum::test_function);
|
||||||
py::enum_<ExampleWithEnum::EMode>(exenum_class, "EMode")
|
py::enum_<ExampleWithEnum::EMode>(exenum_class, "EMode")
|
||||||
|
@ -6,6 +6,7 @@ sys.path.append('.')
|
|||||||
from example import test_function
|
from example import test_function
|
||||||
from example import some_constant
|
from example import some_constant
|
||||||
from example import EMyEnumeration
|
from example import EMyEnumeration
|
||||||
|
from example import ECMyEnum, test_ecenum
|
||||||
from example import EFirstEntry
|
from example import EFirstEntry
|
||||||
from example import ExampleWithEnum
|
from example import ExampleWithEnum
|
||||||
from example import return_bytes
|
from example import return_bytes
|
||||||
@ -20,6 +21,27 @@ print(test_function())
|
|||||||
print(test_function(7))
|
print(test_function(7))
|
||||||
print(test_function(EMyEnumeration.EFirstEntry))
|
print(test_function(EMyEnumeration.EFirstEntry))
|
||||||
print(test_function(EMyEnumeration.ESecondEntry))
|
print(test_function(EMyEnumeration.ESecondEntry))
|
||||||
|
test_ecenum(ECMyEnum.Three)
|
||||||
|
z = ECMyEnum.Two
|
||||||
|
test_ecenum(z)
|
||||||
|
try:
|
||||||
|
z == 2
|
||||||
|
print("Bad: expected a TypeError exception")
|
||||||
|
except TypeError:
|
||||||
|
try:
|
||||||
|
z != 3
|
||||||
|
print("Bad: expected a TypeError exception")
|
||||||
|
except TypeError:
|
||||||
|
print("Good: caught expected TypeError exceptions for scoped enum ==/!= int comparisons")
|
||||||
|
|
||||||
|
y = EMyEnumeration.ESecondEntry
|
||||||
|
try:
|
||||||
|
y == 2
|
||||||
|
y != 2
|
||||||
|
print("Good: no TypeError exception for unscoped enum ==/!= int comparisions")
|
||||||
|
except TypeError:
|
||||||
|
print("Bad: caught TypeError exception for unscoped enum ==/!= int comparisons")
|
||||||
|
|
||||||
print("enum->integer = %i" % int(EMyEnumeration.ESecondEntry))
|
print("enum->integer = %i" % int(EMyEnumeration.ESecondEntry))
|
||||||
print("integer->enum = %s" % str(EMyEnumeration(2)))
|
print("integer->enum = %s" % str(EMyEnumeration(2)))
|
||||||
|
|
||||||
|
@ -10,6 +10,10 @@ test_function(enum=1)
|
|||||||
None
|
None
|
||||||
test_function(enum=2)
|
test_function(enum=2)
|
||||||
None
|
None
|
||||||
|
test_ecenum(ECMyEnum::Three)
|
||||||
|
test_ecenum(ECMyEnum::Two)
|
||||||
|
Good: caught expected TypeError exceptions for scoped enum ==/!= int comparisons
|
||||||
|
Good: no TypeError exception for unscoped enum ==/!= int comparisions
|
||||||
enum->integer = 2
|
enum->integer = 2
|
||||||
integer->enum = EMyEnumeration.ESecondEntry
|
integer->enum = EMyEnumeration.ESecondEntry
|
||||||
A constant = 14
|
A constant = 14
|
||||||
|
@ -1019,9 +1019,14 @@ public:
|
|||||||
this->def("__init__", [](Type& value, UnderlyingType i) { new (&value) Type((Type) i); });
|
this->def("__init__", [](Type& value, UnderlyingType i) { new (&value) Type((Type) i); });
|
||||||
this->def("__int__", [](Type value) { return (UnderlyingType) value; });
|
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, Type *value2) { return value2 && value == *value2; });
|
||||||
this->def("__eq__", [](const Type &value, UnderlyingType value2) { return value == value2; });
|
|
||||||
this->def("__ne__", [](const Type &value, Type *value2) { return !value2 || 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; });
|
if (std::is_convertible<Type, UnderlyingType>::value) {
|
||||||
|
// Don't provide comparison with the underlying type if the enum isn't convertible,
|
||||||
|
// i.e. if Type is a scoped enum, mirroring the C++ behaviour. (NB: we explicitly
|
||||||
|
// convert Type to UnderlyingType below anyway because this needs to compile).
|
||||||
|
this->def("__eq__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value == value2; });
|
||||||
|
this->def("__ne__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value != value2; });
|
||||||
|
}
|
||||||
this->def("__hash__", [](const Type &value) { return (UnderlyingType) value; });
|
this->def("__hash__", [](const Type &value) { return (UnderlyingType) value; });
|
||||||
m_entries = entries;
|
m_entries = entries;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user