Renamed top-level macro ENUM to BETTER_ENUM.

To reduce name clashes.

Fixes #11.
This commit is contained in:
Anton Bachin 2015-10-04 10:46:42 -05:00
parent 977f8ef145
commit e1e237a4ea
42 changed files with 338 additions and 319 deletions

View File

@ -38,8 +38,8 @@ See the [project page][project] for full documentation.
Simply add `enum.h` to your project — that's it. Simply add `enum.h` to your project — that's it.
Then, include it, and use the `ENUM` macro. Your compiler will generate the rich Then, include it, and use the `BETTER_ENUM` macro. Your compiler will generate
enums that are missing from standard C++. the rich enums that are missing from standard C++.
## Additional features ## Additional features
@ -61,12 +61,12 @@ enums that are missing from standard C++.
## Limitations ## Limitations
The biggest limitation is that the `ENUM` macro can't be used inside a class. The biggest limitation is that the `BETTER_ENUM` macro can't be used inside a
This seems [difficult to remove][nested]. There is a workaround with `typedef` class. This seems [difficult to remove][nested]. There is a workaround with
(or C++11 `using`): `typedef` (or C++11 `using`):
```cpp ```cpp
ENUM(UniquePrefix_Color, uint8_t, Red, Green, Blue) BETTER_ENUM(UniquePrefix_Color, uint8_t, Red, Green, Blue)
struct triplet { struct triplet {
typedef UniquePrefix_Color Color; typedef UniquePrefix_Color Color;
@ -76,7 +76,7 @@ struct triplet {
triplet::Color color; triplet::Color color;
``` ```
You can, however, use `ENUM` inside a namespace. You can, however, use `BETTER_ENUM` inside a namespace.
[nested]: http://aantron.github.io/better-enums/DesignDecisionsFAQ.html#NoEnumInsideClass [nested]: http://aantron.github.io/better-enums/DesignDecisionsFAQ.html#NoEnumInsideClass

View File

@ -7,7 +7,7 @@ $internal_toc
The declaration The declaration
#include <enum.h> #include <enum.h>
<em>ENUM</em>(<em>Enum</em>, <em>underlying_type</em>, <em>A</em>, <em>B</em>, <em>C</em>, ...) <em>BETTER_ENUM</em>(<em>Enum</em>, <em>underlying_type</em>, <em>A</em>, <em>B</em>, <em>C</em>, ...)
generates a new class type `Enum` which is notionally similar to the type generates a new class type `Enum` which is notionally similar to the type
created by this $cxx11 declaration: created by this $cxx11 declaration:
@ -20,29 +20,29 @@ That is, `Enum` is a scoped enumerated type with constants `Enum::A`, `Enum::B`,
`Enum::C`, and so on, with memory representation the same as `underlying_type`. `Enum::C`, and so on, with memory representation the same as `underlying_type`.
It is possible to supply initializers for any of the constants: It is possible to supply initializers for any of the constants:
<em>ENUM</em>(Enum, underlying_type, <em>A</em> = <em>1</em>, <em>B</em> = <em>constant_expression</em>, <em>C</em> = <em>A</em>, ...) <em>BETTER_ENUM</em>(Enum, underlying_type, <em>A</em> = <em>1</em>, <em>B</em> = <em>constant_expression</em>, <em>C</em> = <em>A</em>, ...)
The initializers have the same meaning and constraints as in a built-in `enum` The initializers have the same meaning and constraints as in a built-in `enum`
or `enum class` declaration. or `enum class` declaration.
--- ---
The principal differences between the types declared by the `ENUM` macro and The principal differences between the types declared by the `BETTER_ENUM` macro
`enum class` are: and `enum class` are:
- `ENUM` is available for $cxx98 - `BETTER_ENUM` is available for $cxx98
[compilers](${prefix}CompilerSupport.html) supporting `__VA_ARGS__` &mdash; [compilers](${prefix}CompilerSupport.html) supporting `__VA_ARGS__` &mdash;
all major compilers &mdash; while `enum class` is restricted to $cxx11, all major compilers &mdash; while `enum class` is restricted to $cxx11,
- the `ENUM` type is implicitly convertible to integral types, though this can - the `BETTER_ENUM` type is implicitly convertible to integral types, though
be [disabled](${prefix}OptInFeatures.html#StrictConversions) when using this can be [disabled](${prefix}OptInFeatures.html#StrictConversions) when
$cxx11, and using $cxx11, and
- the `ENUM` type supports a set of reflective operations, detailed in the - the `BETTER_ENUM` type supports a set of reflective operations, detailed in
rest of this reference. the rest of this reference.
--- ---
The types produced by the `ENUM` macro are called *Better Enums* in the rest of The types produced by the `BETTER_ENUM` macro are called *Better Enums* in the
this reference. rest of this reference.
Better Enums are similar to their underlying type for the purposes of argument Better Enums are similar to their underlying type for the purposes of argument
passing. This means that they typically fit into a machine word, and should be passing. This means that they typically fit into a machine word, and should be
@ -66,7 +66,7 @@ section.
The rest of this reference uses the following declaration as a running example: The rest of this reference uses the following declaration as a running example:
<em>ENUM</em>(<em>Enum</em>, <em>int</em>, <em>A</em>, <em>B</em>, <em>C</em>) <em>BETTER_ENUM</em>(<em>Enum</em>, <em>int</em>, <em>A</em>, <em>B</em>, <em>C</em>)
@ -78,8 +78,8 @@ rest of the documentation.
#### <em>typedef _enumerated</em> #### <em>typedef _enumerated</em>
An internal type used to declare constants. The `ENUM` macro generates something An internal type used to declare constants. The `BETTER_ENUM` macro generates
similar to something similar to
~~~comment ~~~comment
<em>struct Enum</em> { <em>struct Enum</em> {

View File

@ -29,7 +29,7 @@ constants declared by the user. I chose to prefix members with underscores to
lessen the chances of collision. For example, take `_valid`, and suppose it was lessen the chances of collision. For example, take `_valid`, and suppose it was
`valid` instead. That would make this enum impossible: `valid` instead. That would make this enum impossible:
<em>ENUM(Status, char, valid, invalid)</em> <em>BETTER_ENUM(Status, char, valid, invalid)</em>
because the constant `Status::valid` would clash with the member because the constant `Status::valid` would clash with the member
`Status::valid`. `Status::valid`.
@ -67,7 +67,7 @@ initializers as built-in enums. So, I am trying to keep even this one macro out
of the user's way. I wouldn't accept any change that involved turning the of the user's way. I wouldn't accept any change that involved turning the
declaration into a preprocessor sequence or tuple, i.e. something like declaration into a preprocessor sequence or tuple, i.e. something like
<em>ENUM(Channel, int, (Red)(Green)((Blue)(5)))</em> <em>BETTER_ENUM(Channel, int, (Red)(Green)((Blue)(5)))</em>
even if it promised extra capabilities. even if it promised extra capabilities.
@ -88,10 +88,10 @@ This is due to an interaction between linkage and `constexpr`.
arrays can be declared in namespace scope, in class scope, or in function arrays can be declared in namespace scope, in class scope, or in function
scope, but they also need to be defined somewhere. scope, but they also need to be defined somewhere.
If `ENUM` is to be usable in both namespace and class scope, it already can't If `BETTER_ENUM` is to be usable in both namespace and class scope, it
assume that it can declare arrays in namespace scope, since if `ENUM` is used already can't assume that it can declare arrays in namespace scope, since if
in a class, its entire expansion will be enclosed in the declaration of that `BETTER_ENUM` is used in a class, its entire expansion will be enclosed in
class. the declaration of that class.
That leaves class scope and function scope. If the arrays are declared in That leaves class scope and function scope. If the arrays are declared in
class scope, there needs to be a separate definition of them in some class scope, there needs to be a separate definition of them in some
@ -120,7 +120,7 @@ $cxx98.
A Better Enum value is an "object," whose memory representation is the same as A Better Enum value is an "object," whose memory representation is the same as
its underlying type. For example, its underlying type. For example,
<em>ENUM(Channel, int, Red, Green, Blue)</em> <em>BETTER_ENUM(Channel, int, Red, Green, Blue)</em>
expands to something like expands to something like
@ -136,7 +136,7 @@ There is an alternative interpretation, in which the Better Enums library
generates enum traits instead, i.e. the generated arrays and members sit generates enum traits instead, i.e. the generated arrays and members sit
alongside built-in enums instead of wrapping them: alongside built-in enums instead of wrapping them:
<em>ENUM(Channel, int, Red, Green, Blue)</em> <em>BETTER_ENUM(Channel, int, Red, Green, Blue)</em>
generates generates
@ -251,7 +251,7 @@ Enum is simply an index, then getting its string representation is simply
indexing an array, rather than some kind of data structure lookup. indexing an array, rather than some kind of data structure lookup.
// Representations 0, 1, 2, 3 instead of 1, 2, 3, 1. // Representations 0, 1, 2, 3 instead of 1, 2, 3, 1.
<em>ENUM(Kind, int, A = 1, B, C, D = A)</em> <em>BETTER_ENUM(Kind, int, A = 1, B, C, D = A)</em>
Choosing this approach has serious drawbacks. Choosing this approach has serious drawbacks.

View File

@ -1,8 +1,8 @@
## Extending limits ## Extending limits
The `ENUM` macro makes heavy use of the preprocessor, and some of the internal The `BETTER_ENUM` macro makes heavy use of the preprocessor, and some of the
macros have size limits. There are two: on the number of constants you can internal macros have size limits. There are two: on the number of constants you
declare, and on the maximum length of a constant name under very specific can declare, and on the maximum length of a constant name under very specific
conditions. If you run into either one, you can extend the limit by following conditions. If you run into either one, you can extend the limit by following
the instructions on this page. the instructions on this page.

View File

@ -19,8 +19,9 @@ Doing this enables the following usage:
// The enum. // The enum.
<em>ENUM(Color, html_color, <em>BETTER_ENUM(Color, html_color,
darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954)</em> darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
slimegreen = 0xbce954)</em>
@ -72,9 +73,10 @@ chosen integral type:
};</em> };</em>
// The enum. // The enum.
<em>ENUM(Color, html_color, <em>BETTER_ENUM(Color, html_color,
darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954, darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
celeste = html_color(0x50, 0xeb, 0xec))</em> slimegreen = 0xbce954,
celeste = html_color(0x50, 0xeb, 0xec))</em>
This is not possible at all in $cxx98, however. This is not possible at all in $cxx98, however.
@ -84,7 +86,8 @@ You don't have to use initializers. For example, as long as your example type
`file_descriptor` knows how to deal with the values, you can have the compiler `file_descriptor` knows how to deal with the values, you can have the compiler
generate them in sequence: generate them in sequence:
<em>ENUM(FD, file_descriptor, STDIN, STDOUT, STDERR, SomePipeYourDaemonHas, ...)</em> <em>BETTER_ENUM(FD, file_descriptor,
STDIN, STDOUT, STDERR, SomePipeYourDaemonHas, ...)</em>
SAMPLE SAMPLE

View File

@ -22,7 +22,8 @@ slow enums to get the same penalty as including `iostream` &mdash; but it is
a steep penalty nonetheless. I don't think most people need this feature most of a steep penalty nonetheless. I don't think most people need this feature most of
the time, so it's too high a price to pay. If I improve compilation times to the the time, so it's too high a price to pay. If I improve compilation times to the
point where compile-time name trimming can be the default, I will simply point where compile-time name trimming can be the default, I will simply
redefine `SLOW_ENUM` as `ENUM` and deprecate it, so your code will still work. redefine `SLOW_ENUM` as `BETTER_ENUM` and deprecate it, so your code will still
work.
### Strict conversions ### Strict conversions

View File

@ -46,10 +46,10 @@ A macro allows us to override the invalid value by specializing the template:
Now, we can declare enums like these: Now, we can declare enums like these:
ENUM(<em>Channel</em>, int, Red, Green, Blue, <em>Invalid</em>) BETTER_ENUM(<em>Channel</em>, int, Red, Green, Blue, <em>Invalid</em>)
// Invalid is the invalid value by default // Invalid is the invalid value by default
ENUM(<em>Compression</em>, int, <em>Undefined</em>, None, Huffman) BETTER_ENUM(<em>Compression</em>, int, <em>Undefined</em>, None, Huffman)
OVERRIDE_INVALID(<em>Compression</em>, <em>Undefined</em>) OVERRIDE_INVALID(<em>Compression</em>, <em>Undefined</em>)
and use them: and use them:
@ -100,7 +100,7 @@ And, as before, the usage:
And, if you do And, if you do
ENUM(<em>Answer</em>, int, Yes, No, <em>Invalid</em>) BETTER_ENUM(<em>Answer</em>, int, Yes, No, <em>Invalid</em>)
// OVERRIDE_DEFAULT(<em>Answer</em>, <em>Invalid</em>) // OVERRIDE_DEFAULT(<em>Answer</em>, <em>Invalid</em>)
you will get a helpful compile-time error saying you will get a helpful compile-time error saying

View File

@ -55,8 +55,9 @@ current version.
// The enum itself. // The enum itself.
<em>ENUM(Color, html_color, <em>BETTER_ENUM(Color, html_color,
darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954)</em> darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
slimegreen = 0xbce954)</em>
Now, we can do: Now, we can do:
@ -122,9 +123,10 @@ struct integral_mapping<better_html_color> {
This allows: This allows:
~~~comment ~~~comment
ENUM(BetterColor, better_html_color, BETTER_ENUM(BetterColor, better_html_color,
darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954, darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
<em>celeste = better_html_color(0x50, 0xeb, 0xec)</em>) slimegreen = 0xbce954,
<em>celeste = better_html_color(0x50, 0xeb, 0xec)</em>)
~~~ ~~~
If you can't edit your literal type to add this converting operator, or don't If you can't edit your literal type to add this converting operator, or don't
@ -142,7 +144,8 @@ Of course, as long as the values are valid, you can let the compiler enumerate
your type as in a regular enum, by omitting initializers: your type as in a regular enum, by omitting initializers:
~~~comment ~~~comment
<em>ENUM(FD, file_descriptor, STDIN, STDOUT, STDERR, SomePipeYourDaemonHas, ...)</em> <em>BETTER_ENUM(FD, file_descriptor,
STDIN, STDOUT, STDERR, SomePipeYourDaemonHas, ...)</em>
~~~ ~~~
Here, `FD::STDIN` maps to the integral representation 0, `STDOUT` to 1, and so Here, `FD::STDIN` maps to the integral representation 0, `STDOUT` to 1, and so

View File

@ -38,10 +38,10 @@ Now, we can have bit sets that are wide enough to hold whatever range we
declared. We just declare enums, and the numeric values of their constants will declared. We just declare enums, and the numeric values of their constants will
be bit indices. The rest is straightforward. be bit indices. The rest is straightforward.
ENUM(<em>EFLAGS</em>, int, BETTER_ENUM(<em>EFLAGS</em>, int,
<em>Carry</em>, <em>Parity</em> = 2, <em>Adjust</em> = 4, <em>Zero</em>, <em>Sign</em>, <em>Trap</em>, <em>Interrupt</em>, <em>Direction</em>, <em>Carry</em>, <em>Parity</em> = 2, <em>Adjust</em> = 4, <em>Zero</em>, <em>Sign</em>, <em>Trap</em>, <em>Interrupt</em>, <em>Direction</em>,
<em>Overflow</em>, <em>NestedTask</em> = 14, <em>Resume</em> = 16, <em>V8086</em>, <em>AlignmentCheck</em>, <em>Overflow</em>, <em>NestedTask</em> = 14, <em>Resume</em> = 16, <em>V8086</em>, <em>AlignmentCheck</em>,
<em>CPUIDPresent</em> = 21) <em>CPUIDPresent</em> = 21)
int main() int main()
{ {

View File

@ -8,7 +8,7 @@ buffer for the definition at compile time.
Ok, so it's not really a quine, because we won't be writing all the code needed Ok, so it's not really a quine, because we won't be writing all the code needed
to generate the definition to the buffer as well. And, there are better ways to to generate the definition to the buffer as well. And, there are better ways to
dump the definition than shown here. You could simply define a macro that dump the definition than shown here. You could simply define a macro that
expands to an `ENUM` declaration and also stringizes it. expands to an `BETTER_ENUM` declaration and also stringizes it.
But that's not the point here. The point of this page is to show some of the But that's not the point here. The point of this page is to show some of the
reflective capabilities of Better Enums, so you can adapt them for cases where a reflective capabilities of Better Enums, so you can adapt them for cases where a
@ -37,8 +37,8 @@ since we will be calling `_to_string`. Let's make sure it's enabled by defining
Now, let's declare some enums to dump later: Now, let's declare some enums to dump later:
ENUM(<em>Channel</em>, int, Red, Green, Blue) BETTER_ENUM(<em>Channel</em>, int, Red, Green, Blue)
ENUM(<em>Depth</em>, int, TrueColor = 1, HighColor = 0) BETTER_ENUM(<em>Depth</em>, int, TrueColor = 1, HighColor = 0)
@ -102,7 +102,7 @@ the whole enum:
constexpr <em>size_t declaration_length</em>() constexpr <em>size_t declaration_length</em>()
{ {
return return
<em>string_length("ENUM(") <em>string_length("BETTER_ENUM(")
+ string_length(Enum::_name()) + string_length(Enum::_name())
+ string_length(", int") + string_length(", int")
+ constants_length<Enum>() + constants_length<Enum>()
@ -129,7 +129,7 @@ so that we can do a sanity check on it.
{ {
size_t offset = 0; size_t offset = 0;
offset += std::sprintf(buffer, <em>"ENUM(%s, int", Enum::_name()</em>); offset += std::sprintf(buffer, <em>"BETTER_ENUM(%s, int", Enum::_name()</em>);
<em>for</em> (<em>Enum value</em> : <em>Enum::_values()</em>) { <em>for</em> (<em>Enum value</em> : <em>Enum::_values()</em>) {
offset += offset +=
@ -166,8 +166,8 @@ Now, we can write and run this code.
It prints: It prints:
~~~comment ~~~comment
ENUM(Channel, int, Red = 0, Green = 1, Blue = 2) BETTER_ENUM(Channel, int, Red = 0, Green = 1, Blue = 2)
ENUM(Depth, int, TrueColor = 1, HighColor = 0) BETTER_ENUM(Depth, int, TrueColor = 1, HighColor = 0)
~~~ ~~~
%% description = Have a Better Enum print its own definition. Shows how to %% description = Have a Better Enum print its own definition. Shows how to

View File

@ -48,8 +48,8 @@ The optional Better Enums header file [`extra/better-enums/n4428.h`][header]
implements this interface, though with two necessary differences. implements this interface, though with two necessary differences.
1. The interface is only available for Better Enums, i.e. enums declared through 1. The interface is only available for Better Enums, i.e. enums declared through
the `ENUM` macro. This is because the macro is what generates the information the `BETTER_ENUM` macro. This is because the macro is what generates the
necessary for reflection. information necessary for reflection.
2. The type of `identifier` is `const char*`, not the ${cxx17} proposed 2. The type of `identifier` is `const char*`, not the ${cxx17} proposed
`string_literal`. `string_literal`.
@ -70,7 +70,7 @@ So, with that out of the way, we can do a little test. Let's assume that
Let's declare an enum: Let's declare an enum:
<em>ENUM</em>(<em>Channel</em>, <em>char</em>, <em>Red</em> = <em>1</em>, <em>Green</em>, <em>Blue</em>) <em>BETTER_ENUM</em>(<em>Channel</em>, <em>char</em>, <em>Red</em> = <em>1</em>, <em>Green</em>, <em>Blue</em>)
...and try N4428: ...and try N4428:
@ -120,9 +120,10 @@ The reason for the `#define` in the code above is that there is one quirk:
the interface above is available only for Better Enums for which the interface above is available only for Better Enums for which
[compile-time name trimming][slow-enum] is enabled, i.e. those declared when [compile-time name trimming][slow-enum] is enabled, i.e. those declared when
`BETTER_ENUMS_CONSTEXPR_TO_STRING` was defined, or declared with the `SLOW_ENUM` `BETTER_ENUMS_CONSTEXPR_TO_STRING` was defined, or declared with the `SLOW_ENUM`
variant of `ENUM`. As mentioned on the linked page, the reason compile-time name variant of `BETTER_ENUM`. As mentioned on the linked page, the reason
trimming is not the default is that, while still pretty fast, it is four times compile-time name trimming is not the default is that, while still pretty fast,
slower than program-startup-time name trimming. The latter is the default. it is four times slower than program-startup-time name trimming. The latter is
the default.
Despite the above, a variation on the interface is available for enums without Despite the above, a variation on the interface is available for enums without
compile-time name trimming: compile-time name trimming:
@ -158,7 +159,7 @@ function, and you have to access it through `get_alt<I>`.
~~~comment ~~~comment
// Without compile-time name trimming. // Without compile-time name trimming.
<em>ENUM(Depth, int, HighColor, TrueColor) <em>BETTER_ENUM(Depth, int, HighColor, TrueColor)
int main() int main()
{ {

View File

@ -29,7 +29,7 @@ compilation
</pre> </pre>
<pre class="right"><em>#include &lt;enum.h&gt;</em> <pre class="right"><em>#include &lt;enum.h&gt;</em>
<em>ENUM(Channel, int, Red = 1, Green, Blue)</em> <em>BETTER_ENUM(Channel, int, Red = 1, Green, Blue)</em>
Channel c = <em>Channel::_from_string("Red")</em>; Channel c = <em>Channel::_from_string("Red")</em>;

View File

@ -5,7 +5,7 @@ Download <a $download><code>enum.h</code></a>, then compile this program:
#include <iostream> #include <iostream>
<em>#include "enum.h"</em> <em>#include "enum.h"</em>
<em>ENUM</em>(<em>Word</em>, <em>int</em>, <em>Hello</em>, <em>World</em>) <em>BETTER_ENUM</em>(<em>Word</em>, <em>int</em>, <em>Hello</em>, <em>World</em>)
int main() int main()
{ {

View File

@ -7,7 +7,7 @@ Let's begin by including `enum.h` and declaring our enum:
<em>#include <enum.h></em> <em>#include <enum.h></em>
<em>ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Cyan</em> = <em>1</em>, <em>Magenta</em>, <em>Yellow</em>, <em>Black</em>) <em>BETTER_ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Cyan</em> = <em>1</em>, <em>Magenta</em>, <em>Yellow</em>, <em>Black</em>)
We now have an `int`-sized enum with four constants. We now have an `int`-sized enum with four constants.

View File

@ -6,7 +6,7 @@ example, this:
#include <iostream> #include <iostream>
#include <enum.h> #include <enum.h>
<em>ENUM(Channel, int, Red, Green = 2, Blue)</em> <em>BETTER_ENUM(Channel, int, Red, Green = 2, Blue)</em>
int main() int main()
{ {

View File

@ -5,7 +5,7 @@ A Better Enum can be used directly in a `switch` statement:
#include <iostream> #include <iostream>
<em>#include <enum.h></em> <em>#include <enum.h></em>
<em>ENUM(Channel, int, Red, Green, Blue)</em> <em>BETTER_ENUM(Channel, int, Red, Green, Blue)</em>
int main() int main()
{ {

View File

@ -26,7 +26,7 @@ practical use.
#include <iostream> #include <iostream>
<em>#include</em> <<em>enum.h</em>> <em>#include</em> <<em>enum.h</em>>
<em>ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Red</em>, <em>Green</em>, <em>Blue</em>) <em>BETTER_ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Red</em>, <em>Green</em>, <em>Blue</em>)
We will create a map from this function: We will create a map from this function:

View File

@ -7,7 +7,7 @@ operators:
#include <iostream> #include <iostream>
#include <enum.h> #include <enum.h>
<em>ENUM(Channel, int, Red, Green, Blue)</em> <em>BETTER_ENUM(Channel, int, Red, Green, Blue)</em>
int main() int main()
{ {

View File

@ -12,7 +12,7 @@ You have probably noticed by now that Better Enums are scoped: when you declare
#include <cassert> #include <cassert>
<em>#include <enum.h></em> <em>#include <enum.h></em>
<em>ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Red</em> = <em>1</em>, <em>Green</em>, <em>Blue</em>) <em>BETTER_ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Red</em> = <em>1</em>, <em>Green</em>, <em>Blue</em>)
you don't get names such as `Red` in the global namespace. Instead, you get you don't get names such as `Red` in the global namespace. Instead, you get
`Channel`, and `Red` is accessible as `Channel::Red`. This is no big deal in `Channel`, and `Red` is accessible as `Channel::Red`. This is no big deal in
@ -20,7 +20,7 @@ $cxx11, which has `enum class`. In $cxx98, however, this typically requires
effort. Better Enums brings scope uniformly to both variants. So, despite the effort. Better Enums brings scope uniformly to both variants. So, despite the
above declaration, you can safely declare above declaration, you can safely declare
<em>ENUM</em>(<em>Node</em>, <em>char</em>, <em>Red</em>, <em>Black</em>) <em>BETTER_ENUM</em>(<em>Node</em>, <em>char</em>, <em>Red</em>, <em>Black</em>)
and everything will work as expected. and everything will work as expected.

View File

@ -7,7 +7,7 @@ will declare a more unusual enum than the ones we have seen.
#include <iostream> #include <iostream>
<em>#include <enum.h></em> <em>#include <enum.h></em>
<em>ENUM</em>(<em>ContentType</em>, <em>short</em>, <em>BETTER_ENUM</em>(<em>ContentType</em>, <em>short</em>,
<em>CompressedVideo</em> = <em>5</em>, <em>PCM</em> = <em>8</em>, <em>Subtitles</em> = <em>17</em>, <em>Comment</em> = <em>44</em>) <em>CompressedVideo</em> = <em>5</em>, <em>PCM</em> = <em>8</em>, <em>Subtitles</em> = <em>17</em>, <em>Comment</em> = <em>44</em>)
This is for a hypothetical multimedia container file format. Perhaps the files This is for a hypothetical multimedia container file format. Perhaps the files

View File

@ -15,7 +15,7 @@ get an idea of what can be done. Here, you will see the basics.
<em>#include <enum.h></em> <em>#include <enum.h></em>
<em>ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Red</em> = <em>1</em>, <em>Green</em> = <em>2</em>, <em>Blue</em> = <em>3</em>) <em>BETTER_ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Red</em> = <em>1</em>, <em>Green</em> = <em>2</em>, <em>Blue</em> = <em>3</em>)
<em>constexpr</em> Channel channel = <em>Channel::_from_integral(2)</em>; <em>constexpr</em> Channel channel = <em>Channel::_from_integral(2)</em>;
<em>constexpr</em> int value = <em>channel._to_integral()</em>; <em>constexpr</em> int value = <em>channel._to_integral()</em>;

4
enum.h
View File

@ -1146,7 +1146,7 @@ BETTER_ENUMS__CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \
// Top-level macros. // Top-level macros.
#define ENUM(Enum, Underlying, ...) \ #define BETTER_ENUM(Enum, Underlying, ...) \
BETTER_ENUMS__ID(BETTER_ENUMS__TYPE( \ BETTER_ENUMS__ID(BETTER_ENUMS__TYPE( \
BETTER_ENUMS__CXX11_UNDERLYING_TYPE, \ BETTER_ENUMS__CXX11_UNDERLYING_TYPE, \
BETTER_ENUMS__DEFAULT_SWITCH_TYPE, \ BETTER_ENUMS__DEFAULT_SWITCH_TYPE, \
@ -1172,7 +1172,7 @@ BETTER_ENUMS__CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \
#else #else
#define ENUM(Enum, Underlying, ...) \ #define BETTER_ENUM(Enum, Underlying, ...) \
BETTER_ENUMS__ID(BETTER_ENUMS__TYPE( \ BETTER_ENUMS__ID(BETTER_ENUMS__TYPE( \
BETTER_ENUMS__CXX98_UNDERLYING_TYPE, \ BETTER_ENUMS__CXX98_UNDERLYING_TYPE, \
BETTER_ENUMS__DEFAULT_SWITCH_TYPE, \ BETTER_ENUMS__DEFAULT_SWITCH_TYPE, \

View File

@ -7,7 +7,7 @@
#include <iostream> #include <iostream>
#include "enum.h" #include "enum.h"
ENUM(Word, int, Hello, World) BETTER_ENUM(Word, int, Hello, World)
int main() int main()
{ {

View File

@ -44,10 +44,10 @@ constexpr Enum invalid_impl<Enum>() { return Enum::Value; }
// Now, we can declare enums like these: // Now, we can declare enums like these:
ENUM(Channel, int, Red, Green, Blue, Invalid) BETTER_ENUM(Channel, int, Red, Green, Blue, Invalid)
// Invalid is the invalid value by default // Invalid is the invalid value by default
ENUM(Compression, int, Undefined, None, Huffman) BETTER_ENUM(Compression, int, Undefined, None, Huffman)
OVERRIDE_INVALID(Compression, Undefined) OVERRIDE_INVALID(Compression, Undefined)
// and use them: // and use them:
@ -98,7 +98,7 @@ static_assert(default_impl<Compression>() == +Compression::None, "");
// And, if you do // And, if you do
ENUM(Answer, int, Yes, No, Invalid) BETTER_ENUM(Answer, int, Yes, No, Invalid)
// OVERRIDE_DEFAULT(Answer, Invalid) // OVERRIDE_DEFAULT(Answer, Invalid)
// you will get a helpful compile-time error saying Answer: default cannot equal // you will get a helpful compile-time error saying Answer: default cannot equal

View File

@ -57,8 +57,9 @@ struct integral_mapping<html_color> {
// The enum itself. // The enum itself.
ENUM(Color, html_color, BETTER_ENUM(Color, html_color,
darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954) darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
slimegreen = 0xbce954)
// Now, we can do: // Now, we can do:
@ -121,9 +122,10 @@ int main()
// //
// This allows: // This allows:
// //
// ENUM(BetterColor, better_html_color, // BETTER_ENUM(BetterColor, better_html_color,
// darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954, // darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
// celeste = better_html_color(0x50, 0xeb, 0xec)) // slimegreen = 0xbce954,
// celeste = better_html_color(0x50, 0xeb, 0xec))
// //
// If you can't edit your literal type to add this converting operator, or don't // If you can't edit your literal type to add this converting operator, or don't
// want to for type safety reasons, you can achieve a similar effect by // want to for type safety reasons, you can achieve a similar effect by
@ -132,14 +134,15 @@ int main()
// U is for declarations only. // U is for declarations only.
// //
// Constructors in initializers require C++11. Also, g++ doesn't support this // Constructors in initializers require C++11. Also, g++ doesn't support this
// before g++5. // before 5.1.
// //
// Letting the compiler enumerate your type // Letting the compiler enumerate your type
// //
// Of course, as long as the values are valid, you can let the compiler // Of course, as long as the values are valid, you can let the compiler
// enumerate your type as in a regular enum, by omitting initializers: // enumerate your type as in a regular enum, by omitting initializers:
// //
// ENUM(FD, file_descriptor, STDIN, STDOUT, STDERR, SomePipeYourDaemonHas, ...) // BETTER_ENUM(FD, file_descriptor,
// STDIN, STDOUT, STDERR, SomePipeYourDaemonHas, ...)
// //
// Here, FD::STDIN maps to the integral representation 0, STDOUT to 1, and so // Here, FD::STDIN maps to the integral representation 0, STDOUT to 1, and so
// on. // on.

View File

@ -38,10 +38,10 @@ using EnumSet = std::bitset<max<Enum>()._to_integral() + 1>;
// declared. We just declare enums, and the numeric values of their constants // declared. We just declare enums, and the numeric values of their constants
// will be bit indices. The rest is straightforward. // will be bit indices. The rest is straightforward.
ENUM(EFLAGS, int, BETTER_ENUM(EFLAGS, int,
Carry, Parity = 2, Adjust = 4, Zero, Sign, Trap, Interrupt, Direction, Carry, Parity = 2, Adjust = 4, Zero, Sign, Trap, Interrupt, Direction,
Overflow, NestedTask = 14, Resume = 16, V8086, AlignmentCheck, Overflow, NestedTask = 14, Resume = 16, V8086, AlignmentCheck,
CPUIDPresent = 21) CPUIDPresent = 21)
int main() int main()
{ {

View File

@ -10,7 +10,7 @@
// Ok, so it's not really a quine, because we won't be writing all the code // Ok, so it's not really a quine, because we won't be writing all the code
// needed to generate the definition to the buffer as well. And, there are // needed to generate the definition to the buffer as well. And, there are
// better ways to dump the definition than shown here. You could simply define a // better ways to dump the definition than shown here. You could simply define a
// macro that expands to an ENUM declaration and also stringizes it. // macro that expands to an BETTER_ENUM declaration and also stringizes it.
// //
// But that's not the point here. The point of this page is to show some of the // But that's not the point here. The point of this page is to show some of the
// reflective capabilities of Better Enums, so you can adapt them for cases // reflective capabilities of Better Enums, so you can adapt them for cases
@ -34,8 +34,8 @@
// Now, let's declare some enums to dump later: // Now, let's declare some enums to dump later:
ENUM(Channel, int, Red, Green, Blue) BETTER_ENUM(Channel, int, Red, Green, Blue)
ENUM(Depth, int, TrueColor = 1, HighColor = 0) BETTER_ENUM(Depth, int, TrueColor = 1, HighColor = 0)
@ -99,7 +99,7 @@ template <typename Enum>
constexpr size_t declaration_length() constexpr size_t declaration_length()
{ {
return return
string_length("ENUM(") string_length("BETTER_ENUM(")
+ string_length(Enum::_name()) + string_length(Enum::_name())
+ string_length(", int") + string_length(", int")
+ constants_length<Enum>() + constants_length<Enum>()
@ -127,7 +127,7 @@ size_t format(char *buffer)
{ {
size_t offset = 0; size_t offset = 0;
offset += std::sprintf(buffer, "ENUM(%s, int", Enum::_name()); offset += std::sprintf(buffer, "BETTER_ENUM(%s, int", Enum::_name());
for (Enum value : Enum::_values()) { for (Enum value : Enum::_values()) {
offset += offset +=
@ -163,5 +163,5 @@ int main()
// It prints: // It prints:
// //
// ENUM(Channel, int, Red = 0, Green = 1, Blue = 2) // BETTER_ENUM(Channel, int, Red = 0, Green = 1, Blue = 2)
// ENUM(Depth, int, TrueColor = 1, HighColor = 0) // BETTER_ENUM(Depth, int, TrueColor = 1, HighColor = 0)

View File

@ -2,6 +2,8 @@
// C++17 reflection proposal // C++17 reflection proposal
// //
// You can try this demo live online.
//
// Better Enums can be used to implement the enums portion of the C++17 // Better Enums can be used to implement the enums portion of the C++17
// reflection proposal N4428 in C++11. N4428 proposes the following traits // reflection proposal N4428 in C++11. N4428 proposes the following traits
// interface: // interface:
@ -42,9 +44,9 @@
// this interface, though with two necessary differences. // this interface, though with two necessary differences.
// //
// 1. The interface is only available for Better Enums, i.e. enums declared // 1. The interface is only available for Better Enums, i.e. enums declared
// through the ENUM macro. This is because the macro is what generates the // through the BETTER_ENUM macro. This is because the macro is what
// information necessary for reflection. // generates the information necessary for reflection.
// 2. The type of identifier is const char*, not the ${cxx17}-proposed // 2. The type of identifier is const char*, not the ${cxx17} proposed
// string_literal. // string_literal.
// //
// Demo // Demo
@ -63,7 +65,7 @@
// Let's declare an enum: // Let's declare an enum:
ENUM(Channel, char, Red = 1, Green, Blue) BETTER_ENUM(Channel, char, Red = 1, Green, Blue)
// ...and try N4428: // ...and try N4428:
@ -111,10 +113,10 @@ int main()
// interface above is available only for Better Enums for which compile-time // interface above is available only for Better Enums for which compile-time
// name trimming is enabled, i.e. those declared when // name trimming is enabled, i.e. those declared when
// BETTER_ENUMS_CONSTEXPR_TO_STRING was defined, or declared with the SLOW_ENUM // BETTER_ENUMS_CONSTEXPR_TO_STRING was defined, or declared with the SLOW_ENUM
// variant of ENUM. As mentioned on the linked page, the reason compile-time // variant of BETTER_ENUM. As mentioned on the linked page, the reason
// name trimming is not the default is that, while still pretty fast, it is four // compile-time name trimming is not the default is that, while still pretty
// times slower than program-startup-time name trimming. The latter is the // fast, it is four times slower than program-startup-time name trimming. The
// default. // latter is the default.
// //
// Despite the above, a variation on the interface is available for enums // Despite the above, a variation on the interface is available for enums
// without compile-time name trimming: // without compile-time name trimming:
@ -147,7 +149,7 @@ int main()
// function, and you have to access it through get_alt<I>. // function, and you have to access it through get_alt<I>.
// //
// // Without compile-time name trimming. // // Without compile-time name trimming.
// ENUM(Depth, int, HighColor, TrueColor) // BETTER_ENUM(Depth, int, HighColor, TrueColor)
// //
// int main() // int main()
// { // {

View File

@ -9,7 +9,7 @@
#include <enum.h> #include <enum.h>
ENUM(Channel, int, Cyan = 1, Magenta, Yellow, Black) BETTER_ENUM(Channel, int, Cyan = 1, Magenta, Yellow, Black)
// We now have an int-sized enum with four constants. // We now have an int-sized enum with four constants.
// //

View File

@ -8,7 +8,7 @@
#include <iostream> #include <iostream>
#include <enum.h> #include <enum.h>
ENUM(Channel, int, Red, Green = 2, Blue) BETTER_ENUM(Channel, int, Red, Green = 2, Blue)
int main() int main()
{ {

View File

@ -7,7 +7,7 @@
#include <iostream> #include <iostream>
#include <enum.h> #include <enum.h>
ENUM(Channel, int, Red, Green, Blue) BETTER_ENUM(Channel, int, Red, Green, Blue)
int main() int main()
{ {

View File

@ -28,7 +28,7 @@
#include <iostream> #include <iostream>
#include <enum.h> #include <enum.h>
ENUM(Channel, int, Red, Green, Blue) BETTER_ENUM(Channel, int, Red, Green, Blue)
// We will create a map from this function: // We will create a map from this function:

View File

@ -9,7 +9,7 @@
#include <iostream> #include <iostream>
#include <enum.h> #include <enum.h>
ENUM(Channel, int, Red, Green, Blue) BETTER_ENUM(Channel, int, Red, Green, Blue)
int main() int main()
{ {

View File

@ -13,7 +13,7 @@
#include <cassert> #include <cassert>
#include <enum.h> #include <enum.h>
ENUM(Channel, int, Red = 1, Green, Blue) BETTER_ENUM(Channel, int, Red = 1, Green, Blue)
// you don't get names such as Red in the global namespace. Instead, you get // you don't get names such as Red in the global namespace. Instead, you get
// Channel, and Red is accessible as Channel::Red. This is no big deal in C++11, // Channel, and Red is accessible as Channel::Red. This is no big deal in C++11,
@ -21,7 +21,7 @@ ENUM(Channel, int, Red = 1, Green, Blue)
// Better Enums brings scope uniformly to both variants. So, despite the above // Better Enums brings scope uniformly to both variants. So, despite the above
// declaration, you can safely declare // declaration, you can safely declare
ENUM(Node, char, Red, Black) BETTER_ENUM(Node, char, Red, Black)
// and everything will work as expected. // and everything will work as expected.

View File

@ -9,7 +9,7 @@
#include <iostream> #include <iostream>
#include <enum.h> #include <enum.h>
ENUM(ContentType, short, BETTER_ENUM(ContentType, short,
CompressedVideo = 5, PCM = 8, Subtitles = 17, Comment = 44) CompressedVideo = 5, PCM = 8, Subtitles = 17, Comment = 44)
// This is for a hypothetical multimedia container file format. Perhaps the // This is for a hypothetical multimedia container file format. Perhaps the

View File

@ -17,7 +17,7 @@
#include <enum.h> #include <enum.h>
ENUM(Channel, int, Red = 1, Green = 2, Blue = 3) BETTER_ENUM(Channel, int, Red = 1, Green = 2, Blue = 3)
constexpr Channel channel = Channel::_from_integral(2); constexpr Channel channel = Channel::_from_integral(2);
constexpr int value = channel._to_integral(); constexpr int value = channel._to_integral();

View File

@ -12,15 +12,15 @@
ENUM(Channel, short, Red, Green, Blue) BETTER_ENUM(Channel, short, Red, Green, Blue)
ENUM(Depth, short, HighColor = 40, TrueColor = 20) BETTER_ENUM(Depth, short, HighColor = 40, TrueColor = 20)
ENUM(Compression, short, None, Huffman, Default = Huffman) BETTER_ENUM(Compression, short, None, Huffman, Default = Huffman)
namespace test { namespace test {
ENUM(Namespaced, short, One, Two) BETTER_ENUM(Namespaced, short, One, Two)
} }
@ -300,7 +300,7 @@ class EnumTests : public CxxTest::TestSuite {
ENUM(InternalNameCollisions, int, BETTER_ENUM(InternalNameCollisions, int,
EnumClassForSwitchStatements, PutNamesInThisScopeAlso, EnumClassForSwitchStatements, PutNamesInThisScopeAlso,
force_initialization, value_array, raw_names, name_storage, name_array, force_initialization, value_array, raw_names, name_storage,
initialized, the_raw_names, the_name_array) name_array, initialized, the_raw_names, the_name_array)

View File

@ -4,7 +4,7 @@
ENUM(Compiler, int, GCC, Clang, MSVC) BETTER_ENUM(Compiler, int, GCC, Clang, MSVC)

View File

@ -36,8 +36,9 @@ struct integral_mapping<html_color_1> {
} }
ENUM(HtmlColor1, html_color_1, BETTER_ENUM(HtmlColor1, html_color_1,
darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954) darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
slimegreen = 0xbce954)
@ -75,12 +76,13 @@ struct html_color_2 {
#endif #endif
#ifdef SUPPORT_INITIALIZER #ifdef SUPPORT_INITIALIZER
ENUM(HtmlColor2, html_color_2, BETTER_ENUM(HtmlColor2, html_color_2,
darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954, darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
celeste = html_color_2(0x50, 0xeb, 0xec)) slimegreen = 0xbce954, celeste = html_color_2(0x50, 0xeb, 0xec))
#else #else
ENUM(HtmlColor2, html_color_2, BETTER_ENUM(HtmlColor2, html_color_2,
darksalmon = 0xc47451, purplemimosa = 0x9e7bff, slimegreen = 0xbce954) darksalmon = 0xc47451, purplemimosa = 0x9e7bff,
slimegreen = 0xbce954)
#endif #endif

View File

@ -1,2 +1,2 @@
ENUM(Channel, int, Red = 0, Green = 1, Blue = 2) BETTER_ENUM(Channel, int, Red = 0, Green = 1, Blue = 2)
ENUM(Depth, int, TrueColor = 1, HighColor = 0) BETTER_ENUM(Depth, int, TrueColor = 1, HighColor = 0)

View File

@ -3,6 +3,6 @@
#include <enum.h> #include <enum.h>
ENUM(Channel, int, Red, Green, Blue) BETTER_ENUM(Channel, int, Red, Green, Blue)
#endif // #ifndef _SHARED_H_ #endif // #ifndef _SHARED_H_

View File

@ -1,219 +1,223 @@
#include <enum.h> #include <enum.h>
ENUM(Channel, int, BETTER_ENUM(Channel, int,
Red, Green, Blue, Cyan, Magenta, Yellow, Black, Hue, Saturation, Value) Red, Green, Blue, Cyan, Magenta, Yellow, Black, Hue, Saturation,
Value)
ENUM(Direction, int, BETTER_ENUM(Direction, int,
North, East, South, West, NorthEast, SouthEast, SouthWest, NorthWest, North, East, South, West, NorthEast, SouthEast, SouthWest,
NorthNorthEast, EastNorthEast, EastSouthEast, SouthSouthEast, NorthWest, NorthNorthEast, EastNorthEast, EastSouthEast,
SouthSouthWest, WestSouthWest, WestNorthWest, NorthNorthWest) SouthSouthEast, SouthSouthWest, WestSouthWest, WestNorthWest,
NorthNorthWest)
ENUM(ASTNode, int, BETTER_ENUM(ASTNode, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(State, int, BETTER_ENUM(State, int,
Attacking, Defending, Searching, Pursuing, Hungry, Fleeing, Confused, Attacking, Defending, Searching, Pursuing, Hungry, Fleeing,
Healing, Stunned) Confused, Healing, Stunned)
ENUM(APIMethod, int, BETTER_ENUM(APIMethod, int,
ReadPost, WritePost, PollPost, ReadImage, WriteImage, PollImage, ReadKey, ReadPost, WritePost, PollPost, ReadImage, WriteImage, PollImage,
WriteKey, PollKey, ReadUser, WriteUser, PollUser, ReadOrganization, ReadKey, WriteKey, PollKey, ReadUser, WriteUser, PollUser,
WriteOrganization, PollOrganization, ReadGroup, WriteGroup, PollGroup, ReadOrganization, WriteOrganization, PollOrganization, ReadGroup,
ReadProject, WriteProject, PollProject, ReadComment, WriteComment, WriteGroup, PollGroup, ReadProject, WriteProject, PollProject,
PollComment, ReadPermission, WritePermission, PollPermission, ReadOwner, ReadComment, WriteComment, PollComment, ReadPermission,
WriteOwner, PollOwner, ReadProposal, WriteProposal, PollProposal, WritePermission, PollPermission, ReadOwner, WriteOwner, PollOwner,
ReadHistory, WriteHistory, PollHistory) ReadProposal, WriteProposal, PollProposal, ReadHistory,
WriteHistory, PollHistory)
ENUM(Lipsum, int, BETTER_ENUM(Lipsum, int,
Lorem, ipsum, dolor, sit, amet, consectetur, adipiscing, elit, Vivamus, Lorem, ipsum, dolor, sit, amet, consectetur, adipiscing, elit,
libero, massa, tincidunt, at, ex, nec, porta, malesuada, arcu, Nullam, Vivamus, libero, massa, tincidunt, at, ex, nec, porta, malesuada,
lectus, nibh, dictum, eget, convallis, ac, feugiat, felis, Suspendisse, arcu, Nullam, lectus, nibh, dictum, eget, convallis, ac, feugiat,
quis, purus, vel, lacus, cursus, tristique, Donec, augue, tortor, luctus, felis, Suspendisse, quis, purus, vel, lacus, cursus, tristique,
a, sed, mattis, in, quam, Cras, vitae, euismod, Cum, sociis, natoque, Donec, augue, tortor, luctus, a, sed, mattis, in, quam, Cras, vitae,
penatibus, et, magnis, dis, parturient) euismod, Cum, sociis, natoque, penatibus, et, magnis, dis,
parturient)
ENUM(ASTNode0, int, BETTER_ENUM(ASTNode0, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode1, int, BETTER_ENUM(ASTNode1, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode2, int, BETTER_ENUM(ASTNode2, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode3, int, BETTER_ENUM(ASTNode3, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode4, int, BETTER_ENUM(ASTNode4, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode5, int, BETTER_ENUM(ASTNode5, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode6, int, BETTER_ENUM(ASTNode6, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode7, int, BETTER_ENUM(ASTNode7, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode8, int, BETTER_ENUM(ASTNode8, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode9, int, BETTER_ENUM(ASTNode9, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode10, int, BETTER_ENUM(ASTNode10, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode11, int, BETTER_ENUM(ASTNode11, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode12, int, BETTER_ENUM(ASTNode12, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode13, int, BETTER_ENUM(ASTNode13, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode14, int, BETTER_ENUM(ASTNode14, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode15, int, BETTER_ENUM(ASTNode15, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode16, int, BETTER_ENUM(ASTNode16, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode17, int, BETTER_ENUM(ASTNode17, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode18, int, BETTER_ENUM(ASTNode18, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode19, int, BETTER_ENUM(ASTNode19, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode20, int, BETTER_ENUM(ASTNode20, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode21, int, BETTER_ENUM(ASTNode21, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode22, int, BETTER_ENUM(ASTNode22, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode23, int, BETTER_ENUM(ASTNode23, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode24, int, BETTER_ENUM(ASTNode24, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode25, int, BETTER_ENUM(ASTNode25, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode26, int, BETTER_ENUM(ASTNode26, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode27, int, BETTER_ENUM(ASTNode27, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode28, int, BETTER_ENUM(ASTNode28, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
ENUM(ASTNode29, int, BETTER_ENUM(ASTNode29, int,
IntegerLiteral, StringLiteral, CharacterLiteral, Variable, UnaryOperation, IntegerLiteral, StringLiteral, CharacterLiteral, Variable,
BinaryOperation, ApplicationExpression, Abstraction, LetBinding, UnaryOperation, BinaryOperation, ApplicationExpression, Abstraction,
CaseExpression, Pattern, Signature, Module, Functor, TypeVariable, LetBinding, CaseExpression, Pattern, Signature, Module, Functor,
BasicType, ArrowType, VariantTypeConstant) TypeVariable, BasicType, ArrowType, VariantTypeConstant)
int main() int main()
{ {