@@ -890,52 +890,45 @@ template <typename... Tuple> class type_caster<std::tuple<Tuple...>> {
890
890
std::tuple<make_caster<Tuple>...> value;
891
891
};
892
892
893
+ template <typename U>
893
894
struct py3_enum_info {
894
895
handle type = {};
895
- std::unordered_map<long long , handle> values = {};
896
+ std::unordered_map<U , handle> values = {};
896
897
897
898
py3_enum_info () = default ;
898
899
899
900
py3_enum_info (handle type, const dict& values) : type(type) {
900
- for (auto item : values)
901
- this ->values [static_cast <long long >(item.second .cast <int >())] = type.attr (item.first );
902
- }
903
-
904
- static std::unordered_map<std::type_index, py3_enum_info>& registry () {
905
- static std::unordered_map<std::type_index, py3_enum_info> map = {};
906
- return map;
907
- }
908
-
909
- template <typename T>
910
- static void bind (handle type, const dict& values) {
911
- registry ()[typeid (T)] = py3_enum_info (type, values);
912
- }
913
-
914
- template <typename T>
915
- static const py3_enum_info* get () {
916
- auto it = registry ().find (typeid (T));
917
- return it == registry ().end () ? nullptr : &it->second ;
901
+ for (auto item : values) {
902
+ this ->values [item.second .cast <U>()] = type.attr (item.first );
903
+ }
918
904
}
919
905
};
920
906
921
907
template <typename T>
922
908
struct type_caster <T, enable_if_t <std::is_enum<T>::value>> {
909
+ using underlying_type = typename std::underlying_type<T>::type;
910
+
923
911
private:
924
912
using base_caster = type_caster_base<T>;
913
+
914
+ static std::unique_ptr<py3_enum_info<underlying_type>>& py3_info () {
915
+ static std::unique_ptr<py3_enum_info<underlying_type>> info;
916
+ return info;
917
+ }
918
+
925
919
base_caster caster;
926
- bool py3 = false ;
927
920
T value;
928
921
929
922
public:
930
923
template <typename U> using cast_op_type = pybind11::detail::cast_op_type<U>;
931
924
932
- operator T*() { return py3 ? &value : static_cast <T*>(caster); }
933
- operator T&() { return py3 ? value : static_cast <T&>(caster); }
925
+ operator T*() { return py3_info () ? &value : static_cast <T*>(caster); }
926
+ operator T&() { return py3_info () ? value : static_cast <T&>(caster); }
934
927
935
928
static handle cast (const T& src, return_value_policy rvp, handle parent) {
936
- if (auto info = py3_enum_info::get<T> ()) {
937
- auto it = info ->values .find (static_cast <long long >(src));
938
- if (it == info ->values .end ())
929
+ if (py3_info ()) {
930
+ auto it = py3_info () ->values .find (static_cast <underlying_type >(src));
931
+ if (it == py3_info () ->values .end ())
939
932
return {};
940
933
return it->second .inc_ref ();
941
934
}
@@ -945,20 +938,22 @@ struct type_caster<T, enable_if_t<std::is_enum<T>::value>> {
945
938
bool load (handle src, bool convert) {
946
939
if (!src)
947
940
return false ;
948
- if (auto info = py3_enum_info::get<T>()) {
949
- py3 = true ;
950
- if (!isinstance (src, info->type ))
941
+ if (py3_info ()) {
942
+ if (!isinstance (src, py3_info ()->type ))
951
943
return false ;
952
- value = static_cast <T>(src.cast <long long >());
944
+ value = static_cast <T>(src.cast <underlying_type >());
953
945
return true ;
954
946
}
955
- py3 = false ;
956
947
return caster.load (src, convert);
957
948
}
958
949
959
950
static PYBIND11_DESCR name () {
960
951
return base_caster::name ();
961
952
}
953
+
954
+ static void bind (handle type, const dict& values) {
955
+ py3_info ().reset (new py3_enum_info<underlying_type>(type, values));
956
+ }
962
957
};
963
958
964
959
// / Helper class which abstracts away certain actions. Users can provide specializations for
0 commit comments