| 3166 | /// Binds C++ enumerations and enumeration classes to Python |
| 3167 | template <typename Type> |
| 3168 | class enum_ : public class_<Type> { |
| 3169 | public: |
| 3170 | using Base = class_<Type>; |
| 3171 | using Base::attr; |
| 3172 | using Base::def; |
| 3173 | using Base::def_property_readonly; |
| 3174 | using Base::def_property_readonly_static; |
| 3175 | using Underlying = typename std::underlying_type<Type>::type; |
| 3176 | // Scalar is the integer representation of underlying type |
| 3177 | using Scalar = detail::conditional_t<detail::any_of<detail::is_std_char_type<Underlying>, |
| 3178 | std::is_same<Underlying, bool>>::value, |
| 3179 | detail::equivalent_integer_t<Underlying>, |
| 3180 | Underlying>; |
| 3181 | |
| 3182 | template <typename... Extra> |
| 3183 | enum_(const handle &scope, const char *name, const Extra &...extra) |
| 3184 | : class_<Type>(scope, name, extra...), m_base(*this, scope) { |
| 3185 | { |
| 3186 | if (detail::global_internals_native_enum_type_map_contains( |
| 3187 | std::type_index(typeid(Type)))) { |
| 3188 | pybind11_fail("pybind11::enum_ \"" + std::string(name) |
| 3189 | + "\" is already registered as a pybind11::native_enum!"); |
| 3190 | } |
| 3191 | } |
| 3192 | |
| 3193 | constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value; |
| 3194 | constexpr bool is_convertible = std::is_convertible<Type, Underlying>::value; |
| 3195 | m_base.init(is_arithmetic, is_convertible); |
| 3196 | |
| 3197 | def(init([](Scalar i) { return static_cast<Type>(i); }), arg("value")); |
| 3198 | def_property_readonly("value", [](Type value) { return (Scalar) value; }, pos_only()); |
| 3199 | def("__int__", [](Type value) { return (Scalar) value; }, pos_only()); |
| 3200 | def("__index__", [](Type value) { return (Scalar) value; }, pos_only()); |
| 3201 | attr("__setstate__") = cpp_function( |
| 3202 | [](detail::value_and_holder &v_h, Scalar arg) { |
| 3203 | detail::initimpl::setstate<Base>( |
| 3204 | v_h, static_cast<Type>(arg), Py_TYPE(v_h.inst) != v_h.type->type); |
| 3205 | }, |
| 3206 | detail::is_new_style_constructor(), |
| 3207 | pybind11::name("__setstate__"), |
| 3208 | is_method(*this), |
| 3209 | arg("state"), |
| 3210 | pos_only()); |
| 3211 | } |
| 3212 | |
| 3213 | /// Export enumeration entries into the parent scope |
| 3214 | enum_ &export_values() { |
| 3215 | m_base.export_values(); |
| 3216 | return *this; |
| 3217 | } |
| 3218 | |
| 3219 | /// Add an enumeration entry |
| 3220 | enum_ &value(char const *name, Type value, const char *doc = nullptr) { |
| 3221 | m_base.value(name, pybind11::cast(value, return_value_policy::copy), doc); |
| 3222 | return *this; |
| 3223 | } |
| 3224 | |
| 3225 | private: |