Anton Bachin 0f63667106 Overloaded stream operators.
To avoid paying the huge penalty of including iostream and string for
users that don't need those headers, and to avoid creating a second,
optional header file, I resorted to defining the operators as templates
to prevent type checking until the user tries to actually use them. The
stream types and strings are wrapped in a metafunction that depends on
the template parameter. This is basically a hack, but it seems to work.
2015-06-11 23:05:46 -05:00
doc Updated contact information and other errata. 2015-06-06 13:54:40 -05:00
example Updated and improved documentation. 2015-06-05 13:01:28 -05:00
script Eliminated underscored internal macro names. 2015-06-05 19:20:18 -05:00
test Overloaded stream operators. 2015-06-11 23:05:46 -05:00
.gitattributes Complete documentation and testing overhaul. 2015-05-27 09:58:34 -05:00
.gitignore Made the test script use only the system compiler by default and extended some 2015-05-27 18:40:39 -05:00
CONTRIBUTING.md Added CONTRIBUTING file and acknowledgements. 2015-06-05 21:57:33 -05:00
CONTRIBUTORS Experimental generalization of underlying types. 2015-06-11 20:39:46 -05:00
enum.h Overloaded stream operators. 2015-06-11 23:05:46 -05:00
LICENSE Initial release. 2015-05-11 17:38:41 -04:00
README.md Made ENUM usable in namespaces. 2015-06-07 17:05:31 -05:00

Better Enums

Reflective compile-time C++ enum library with clean syntax, in a single header file. For example:

#include <enum.h>
ENUM(Channel, uint8_t, Red = 1, Green, Blue)

defines a type Channel. You can then do natural things such as:

Channel channel = Channel::Green;

channel._to_string();           // Results in the string "Green"
Channel::_from_string("Red");   // Results in Channel::Red

Channel::_from_integral(3);     // Checked cast, Channel::Blue

Channel::_size;                 // Number of channels (3)
Channel::_values()[0];          // Get the first channel

for (Channel channel : Channel::_values()) {
    process(channel);           // Iterate over all channels
}

// Natural switch, compiler checks the cases
switch (channel) {
    case Channel::Red:   break;
    case Channel::Green: break;
    case Channel::Blue:  break;
}

...and more.

In C++11, everything is available at compile time. You can convert your enums, loop over them, find their max, statically enforce conventions, and pass along the results as template arguments or to constexpr functions. All the reflection is available for your metaprogramming needs.

The interface is the same for C++98 — you just have to use most of it at run time only. This library does provide scoped and sized enums, something not built into C++98.

See the project page for full documentation and here for a simple working program.

Installation

Simply add enum.h to your project — that's it.

Then, include it and use the ENUM macro. Your compiler will generate the rich enums that are missing from standard C++.

Additional features

  • No dependencies and no external build tools. Uses only standard C++, though, for C++98, variadic macro support is required.
  • Supported and tested on clang, gcc, and msvc.
  • Fast compilation. You have to declare a few dozen enums to slow down your compiler as much as just including iostream does.
  • Use any initializers and sparse ranges, just like with a built-in enum.
  • Guaranteed size and alignment — you choose the representation type.

Limitations

The biggest current limitation is that the ENUM macro can't be used inside a class. This seems difficult to remove, but I am looking into it. In the meantime, there is a workaround with a typedef (or using):

ENUM(UniquePrefix_Color, uint8_t, Red, Green, Blue)

struct triplet {
    typedef UniquePrefix_Color      Color;
    Color                           r, g, b;
};

triplet::Color  color;

You can, however, use ENUM inside a namespace.

Contact

Don't hesitate to contact me about features or bugs: antonbachin@yahoo.com, Twitter @better_enums, or open an issue on GitHub.

License and history

Better Enums is released under the BSD 2-clause license. See LICENSE.

The library was originally developed by the author in the winter of 2012-2013 at Hudson River Trading, as a replacement for an older generator called BETTER_ENUM.