Enums#

Relevant portion of the pybind11 manual and of the nanobind manual

litgen handles enum and enum class enums.

Classic C enums#

See example below:

  • litgen automatically remove the standard prefix from enum values: Foo::Foo_a is exposed as Foo.a

  • comments about values are preserved in the stub

  • litgen automatically handles the enum numbering and outputs the values as a comment in the stub

  • if some macro values are used (like MY_VALUE), we can set their value

  • Computed values are also correctly exposed (see Foo.d)

cpp_code = """
// Doc about Foo
// On several lines
enum Foo
{
    Foo_a, // This is a

    // And this is b and c's comment
    Foo_b,
    Foo_c = MY_VALUE,

    Foo_d = Foo_a | Foo_b + Foo_c, // And a computed value

    Foo_e = 4,

    Foo_count, // And this is count: by default this member is suppressed
};
"""

import litgen
from litgen.demo import litgen_demo

options = litgen.LitgenOptions()
options.srcmlcpp_options.named_number_macros = {"MY_VALUE": 256}
# options.enum_flag_skip_count = False # Uncomment this to generate a definition for Foo::Foo_count
litgen_demo.demo(options, cpp_code)
// Doc about Foo
// On several lines
enum Foo
{
    Foo_a, // This is a

    // And this is b and c's comment
    Foo_b,
    Foo_c = MY_VALUE,

    Foo_d = Foo_a | Foo_b + Foo_c, // And a computed value

    Foo_e = 4,

    Foo_count, // And this is count: by default this member is suppressed
};
class Foo(enum.Enum):
    """ Doc about Foo
     On several lines
    """
    a = enum.auto() # (= 0)  # This is a

    # And this is b and c's comment
    b = enum.auto() # (= 1)
    c = enum.auto() # (= 256)

    d = enum.auto() # (= Foo.a | Foo.b + Foo.c)  # And a computed value

    e = enum.auto() # (= 4)


auto pyEnumFoo =
    py::enum_<Foo>(m, "Foo", py::arithmetic(), " Doc about Foo\n On several lines")
        .value("a", Foo_a, "This is a")
        .value("b", Foo_b, "")
        .value("c", Foo_c, "")
        .value("d", Foo_d, "And a computed value")
        .value("e", Foo_e, "");
auto pyEnumFoo =
    nb::enum_<Foo>(m, "Foo", nb::is_arithmetic(), " Doc about Foo\n On several lines")
        .value("a", Foo_a, "This is a")
        .value("b", Foo_b, "")
        .value("c", Foo_c, "")
        .value("d", Foo_d, "And a computed value")
        .value("e", Foo_e, "");

C++ enums: enum class#

enum class is also supported, see example below:

cpp_code = """
    enum class Foo
    {
        A,
        B,
        C = MY_VALUE,
        D = A | B + C,
        E = 4,
        F
    };
"""

options = litgen.LitgenOptions()
options.srcmlcpp_options.named_number_macros = {"MY_VALUE": 256}
litgen_demo.demo(options, cpp_code)
    enum class Foo
    {
        A,
        B,
        C = MY_VALUE,
        D = A | B + C,
        E = 4,
        F
    };
class Foo(enum.Enum):
    a = enum.auto() # (= 0)
    b = enum.auto() # (= 1)
    c = enum.auto() # (= 256)
    d = enum.auto() # (= A | B + C)
    e = enum.auto() # (= 4)
    f = enum.auto() # (= 5)


auto pyEnumFoo =
    py::enum_<Foo>(m, "Foo", py::arithmetic(), "")
        .value("a", Foo::A, "")
        .value("b", Foo::B, "")
        .value("c", Foo::C, "")
        .value("d", Foo::D, "")
        .value("e", Foo::E, "")
        .value("f", Foo::F, "");
auto pyEnumFoo =
    nb::enum_<Foo>(m, "Foo", nb::is_arithmetic(), "")
        .value("a", Foo::A, "")
        .value("b", Foo::B, "")
        .value("c", Foo::C, "")
        .value("d", Foo::D, "")
        .value("e", Foo::E, "")
        .value("f", Foo::F, "");

Arithmetic enums#

Use options.enum_make_arithmetic__regex to make the enum arithmetic in python, so that it can be converted to a number in python.

cpp_code = """
    enum class Foo { A, B, C};
"""
options = litgen.LitgenOptions()
options.enum_make_arithmetic__regex = "^Foo$"
litgen_demo.demo(options, cpp_code, show_pydef=True)
    enum class Foo { A, B, C};
class Foo(enum.Enum):
    a = enum.auto() # (= 0)
    b = enum.auto() # (= 1)
    c = enum.auto() # (= 2)


auto pyEnumFoo =
    py::enum_<Foo>(m, "Foo", py::arithmetic(), "")
        .value("a", Foo::A, "")
        .value("b", Foo::B, "")
        .value("c", Foo::C, "");
auto pyEnumFoo =
    nb::enum_<Foo>(m, "Foo", nb::is_arithmetic(), "")
        .value("a", Foo::A, "")
        .value("b", Foo::B, "")
        .value("c", Foo::C, "");