hsutter / cppfront

A personal experimental C++ Syntax 2 -> Syntax 1 compiler
Other
5.46k stars 238 forks source link

[SUGGESTION] Allow @enum classes as template type arguments #1147

Open MaxSagebaum opened 3 months ago

MaxSagebaum commented 3 months ago

The enums generated by @enum in cppfront can not be used as template type arguments. E.g:

range_flags: @enum type = {
    not_greedy := 1;
    greedy;
    possessive;
}

S: <flag: range_flags> type = {

}

The error is:

main.cpp2:18:22: error: invalid use of incomplete type 'class range_flags'
main.cpp2:12:7: note: forward declaration of 'class range_flags'
main.cpp2:18:22: error: 'range_flags' is not a valid type for a template non-type parameter because it is not structural
main.cpp2:13:19: note: 'range_flags::_value' is not public

Example on compiler explorer: https://cpp2.godbolt.org/z/v3bvPE6EE

This is basically a feature request. I did not have a look at the current implementation. Would it have merit/support if the generated @enum code would support this?

sookach commented 3 months ago

I think that's a really good suggestion since it's something I use pretty often in C++. I played around with the transpiled code a bit and I believe it's going to be a bit tricky to implement. The generated enum values are non structural types so we can't just do something like

template <auto flag> requires(std::is_same_v<CPP2_TYPEOF(flag), range_flags>) class S;

There might be an answer hiding in plain sight, but I'm pretty sure implementing this will require a hefty rework of the generated code.

tsoj commented 1 month ago

The simple fix would be to make the private member _value of the enum class into a public member (perhaps named raw_value). This would of course come with the downside that it can be easily set to invalid enum values, but from my point of view this would be worth the upside of being able to use it as template parameters.