@@ -1569,6 +1569,59 @@ inline str enum_name(handle arg) {
1569
1569
return " ???" ;
1570
1570
}
1571
1571
1572
+ class enum_meta_info {
1573
+ public:
1574
+ static pybind11::object enum_meta_cls () {
1575
+ return get ().enum_meta_cls_ ;
1576
+ }
1577
+
1578
+ static pybind11::object enum_base_cls () {
1579
+ return get ().enum_base_cls_ ;
1580
+ }
1581
+
1582
+ private:
1583
+ template <typename T>
1584
+ friend T& pybind11::get_or_create_shared_data (const std::string&);
1585
+
1586
+ static const enum_meta_info& get () {
1587
+ return pybind11::get_or_create_shared_data<enum_meta_info>(
1588
+ " _pybind11_enum_meta_info" );
1589
+ }
1590
+
1591
+ enum_meta_info () {
1592
+ handle copy = pybind11::module::import (" copy" ).attr (" copy" );
1593
+ locals_ = copy (pybind11::globals ());
1594
+ locals_[" pybind11_meta_cls" ] = reinterpret_borrow<object>(
1595
+ reinterpret_cast <PyObject*>(get_internals ().default_metaclass ));
1596
+ locals_[" pybind11_base_cls" ] = reinterpret_borrow<object>(
1597
+ get_internals ().instance_base );
1598
+ // TODO: Make the base class work.
1599
+ const char code[] = R"""(
1600
+ pybind11_enum_base_cls = None
1601
+
1602
+ class pybind11_enum_meta_cls(pybind11_meta_cls):
1603
+ is_pybind11_enum = True
1604
+
1605
+ def __iter__(cls):
1606
+ return iter(cls.__members__.values())
1607
+
1608
+ def __len__(cls):
1609
+ return len(cls.__members__)
1610
+ )""" ;
1611
+ PyObject *result = PyRun_String (
1612
+ code, Py_file_input, locals_.ptr (), locals_.ptr ());
1613
+ if (result == nullptr ) {
1614
+ throw error_already_set ();
1615
+ }
1616
+ enum_meta_cls_ = locals_[" pybind11_enum_meta_cls" ];
1617
+ enum_base_cls_ = locals_[" pybind11_enum_base_cls" ];
1618
+ }
1619
+
1620
+ pybind11::object enum_meta_cls_;
1621
+ pybind11::object enum_base_cls_;
1622
+ pybind11::dict locals_;
1623
+ };
1624
+
1572
1625
struct enum_base {
1573
1626
enum_base (handle base, handle parent) : m_base(base), m_parent(parent) { }
1574
1627
@@ -1725,7 +1778,13 @@ template <typename Type> class enum_ : public class_<Type> {
1725
1778
1726
1779
template <typename ... Extra>
1727
1780
enum_ (const handle &scope, const char *name, const Extra&... extra)
1728
- : class_<Type>(scope, name, extra...), m_base(*this , scope) {
1781
+ : class_<Type>(
1782
+ scope, name,
1783
+ // Can't re-declare base type???
1784
+ // detail::enum_meta_info::enum_base_cls(),
1785
+ pybind11::metaclass (detail::enum_meta_info::enum_meta_cls()),
1786
+ extra...),
1787
+ m_base (*this , scope) {
1729
1788
constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value;
1730
1789
constexpr bool is_convertible = std::is_convertible<Type, Scalar>::value;
1731
1790
m_base.init (is_arithmetic, is_convertible);
0 commit comments