|
Boost : |
Subject: Re: [boost] Query for interest in library: reflective enum
From: Nir Friedman (quicknir_at_[hidden])
Date: 2018-01-17 20:33:32
Hah, already realized I made a silly mistake. The current implementation
uses variable templates and therefore isn't 11 compatible of course. The
template variables can be optionally compiled for C++14, and C++11 can use
static members of template structs.
On Wed, Jan 17, 2018 at 3:21 PM, Nir Friedman <quicknir_at_[hidden]> wrote:
> Hello,
>
> I recently needed a reflective enum for work (that is an enum where you
> can programmatically convert to and from strings, know how many enumerators
> there are, and iterate over all enumerators). I looked online but I didn't
> find anything that met my requirements. I was surprised that there wasn't
> one in Boost. So I'd like to see if there is interest; I wrote an
> implementation that I think has several nice features.
>
> The most polished existing smart enum implementation I could find was
> http://aantron.github.io/better-enums/. However, the enum implemented
> there is not a true enum; it uses a nested member of a class kind of
> approach. So for example, the is_enum type trait will not recognize is as
> an enum. You cannot use it as a non-type template parameter.
>
> I strongly think that a good generic smart enum macro should generate the
> exact "vanilla" enum (or enum class) declaration. My library's syntax looks
> like this:
>
> WISE_ENUM(Foo, BAR, (BAZ, 3))
>
> This generates, among other things, exactly:
>
> enum Foo { BAR, BAZ=3};
>
> I intend this as an explicit guarantee of the library that the programmer
> can count on. That way when Foo is used for things unrelating to
> reflection, the developer can be confident that there will not be any
> surprises. Beyond compatability with C++ facilities for enums, and
> minimizing surprise, another advantage of this approach is that it's
> guaranteed to be backwards compatible. An existing codebase with an
> existing enum/enum class can switch to this smart enum with very high
> confidence that existing code will continue to work as before.
>
> The WISE_ENUM macro, beyond generating the vanilla enum, also generates a
> switch-case function for to-string conversion (for maximal efficiency), and
> finally it generates a constexpr function that returns a
> std::array<std::pair<const char*, Foo>> listing all of the arrays and their
> string descriptions. This constexpr function, which is found via ADL,
> allows writing a sequence of (constexpr) variables and functions providing
> the rest of the desired functionality. Usage looks like this:
>
> std::cerr << "My enum's size is : " << wise_enum::size<Foo> // this is
> constexpr template variable
> auto x = wise_enum::from_string<Foo>("BAR").value(); // from_string
> returns an optional
> auto y = wise_enum::to_string(x); // y is string literal, no heap
> allocation
>
> My implementation (POC level) is here: https://github.com/
> quicknir/wise_enum. I don't yet have separate macros to cover enum/enum
> class/explicit/implicit backing type combinations. It's only about 100
> lines of code, leaning heavily on BOOST_PP to do the heavy lifting. It
> requires variadic macros, and can probably target C++11 (if it doesn't
> already). I probably need to "comma harden" the macros for bizarre stuff
> like WISE_ENUM(Foo, (BAR, my_func<3,4>())).
>
> It has the limitation that the macro cannot be used inside a class (this
> is hard to workaround for reflective macros). It's also unclear how
> repeated enumeration values would be handled (enum Foo { BAR = 1, BAZ =
> 1}). As it stands this will cause a compilation failure in the generated
> switch case of the to_string function. Can discuss more in subsequent
> emails.
>
> One suggested feature is an is_contiguous trait. Another reasonable bit of
> functionality might be an is_wise_enum trait. Version 2 of this library
> could target enum sets.
>
> Although it's not fancy, I think this nicely covers a piece of
> functionality I often need, and it does so avoiding any downside compared
> to using a simple enum (beyond having to use macros). Hope other people
> will agree!
>
> Cheers,
>
> Nir
>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk