@@ -1116,24 +1116,32 @@ class class_ : public detail::generic_type {
1116
1116
template <typename Type> class enum_ : public class_ <Type> {
1117
1117
public:
1118
1118
using class_<Type>::def;
1119
+ using class_<Type>::def_property_readonly_static;
1119
1120
using Scalar = typename std::underlying_type<Type>::type;
1120
1121
template <typename T> using arithmetic_tag = std::is_same<T, arithmetic>;
1121
1122
1122
1123
template <typename ... Extra>
1123
1124
enum_ (const handle &scope, const char *name, const Extra&... extra)
1124
- : class_<Type>(scope, name, extra...), m_parent(scope) {
1125
+ : class_<Type>(scope, name, extra...), m_entries(), m_parent(scope) {
1125
1126
1126
1127
constexpr bool is_arithmetic =
1127
1128
!std::is_same<detail::first_of_t <arithmetic_tag, void , Extra...>,
1128
1129
void >::value;
1129
1130
1130
- auto entries = new std::unordered_map<Scalar, const char *>();
1131
- def (" __repr__" , [name, entries](Type value) -> std::string {
1132
- auto it = entries->find ((Scalar) value);
1133
- return std::string (name) + " ." +
1134
- ((it == entries->end ()) ? std::string (" ???" )
1135
- : std::string (it->second ));
1131
+ auto m_entries_ptr = m_entries.inc_ref ().ptr ();
1132
+ def (" __repr__" , [name, m_entries_ptr](Type value) -> pybind11::str {
1133
+ for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr)) {
1134
+ if (pybind11::cast<Type>(kv.second ) == value)
1135
+ return pybind11::str (" {}.{}" ).format (name, kv.first );
1136
+ }
1137
+ return pybind11::str (" {}.???" ).format (name);
1136
1138
});
1139
+ def_property_readonly_static (" __members__" , [m_entries_ptr](object /* self */ ) {
1140
+ dict m;
1141
+ for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr))
1142
+ m[kv.first ] = kv.second ;
1143
+ return m;
1144
+ }, return_value_policy::copy);
1137
1145
def (" __init__" , [](Type& value, Scalar i) { value = (Type)i; });
1138
1146
def (" __init__" , [](Type& value, Scalar i) { new (&value) Type ((Type) i); });
1139
1147
def (" __int__" , [](Type value) { return (Scalar) value; });
@@ -1172,26 +1180,25 @@ template <typename Type> class enum_ : public class_<Type> {
1172
1180
// Pickling and unpickling -- needed for use with the 'multiprocessing' module
1173
1181
def (" __getstate__" , [](const Type &value) { return pybind11::make_tuple ((Scalar) value); });
1174
1182
def (" __setstate__" , [](Type &p, tuple t) { new (&p) Type ((Type) t[0 ].cast <Scalar>()); });
1175
- m_entries = entries;
1176
1183
}
1177
1184
1178
1185
// / Export enumeration entries into the parent scope
1179
- enum_ &export_values () {
1180
- for (auto item : reinterpret_borrow<dict>(((PyTypeObject *) this ->m_ptr )->tp_dict )) {
1181
- if (isinstance (item.second , this ->m_ptr ))
1182
- m_parent.attr (item.first ) = item.second ;
1183
- }
1186
+ enum_& export_values () {
1187
+ for (const auto &kv : m_entries)
1188
+ m_parent.attr (kv.first ) = kv.second ;
1184
1189
return *this ;
1185
1190
}
1186
1191
1187
1192
// / Add an enumeration entry
1188
1193
enum_& value (char const * name, Type value) {
1189
- this ->attr (name) = pybind11::cast (value, return_value_policy::copy);
1190
- (*m_entries)[(Scalar) value] = name;
1194
+ auto v = pybind11::cast (value, return_value_policy::copy);
1195
+ this ->attr (name) = v;
1196
+ m_entries[pybind11::str (name)] = v;
1191
1197
return *this ;
1192
1198
}
1199
+
1193
1200
private:
1194
- std::unordered_map<Scalar, const char *> * m_entries;
1201
+ dict m_entries;
1195
1202
handle m_parent;
1196
1203
};
1197
1204
0 commit comments