- Hey everyone! So, this
talk's on Wise Enum.
It's the small library that I wrote.
It's almost embarrassingly
short by lines of code.
So I know what already
you're all thinking.
Really? Another one,
a Wise Enum library,
or Smart Enum library.
This is like the C++
equivalent of a to-do app.
Right, there's like four million
of them on the app store.
But probably kind of like to-do apps,
there's a lot of issues with them.
Actually, if you Google
search for smart enum,
the first eight hits are random jists
and stack overflow questions.
It's not exactly a library you
would actually want to use.
Until you finally come to a real library.
It's not really a solved problem.
So what is the problem? We have an enum,
we'd like to be able to
turn it into a string,
we'd like to turn strings
back into our enums,
we like to iterate over them,
and know how many there are.
That's basically it, very useful.
Not that easy to find a library
that does all that properly.
And a lot of the libraries you'll find
have all kinds of issues,
some of them use X macro,
some of them assume that all the enums,
the values go from zero, one, two,
all kinds of different problems.
A lot of them don't declare enums,
they declare classes that
try to behave like enums.
So we don't have reflections, so obviously
the solution's not going to
be pretty, no matter what.
So if you take stock of your options,
so if you manually generate
code that's bug-prone,
if you automatically generate code
that's in your build system.
So we'll just use macros, also ugly.
So here's what the A.P.I. looks like.
You're declaring an enum,
you're explicitly setting
one of the values,
looks pretty, y'know, whatever.
Here's how you would
iterate, wise_enum::range.
You throw in the name of your enumerator,
also pretty straight forward.
Converting, again, your to-string,
you throw it in a string comes out.
You have a string, you
throw the string in,
and what comes out is
actually an optional.
Because if no enum has the right string,
then you'll get an empty optional.
If you don't use exceptions
for example you don't have to worry.
If you're doing meta-programming,
like if you have a logger,
you might want to have the
logger log wise enum differently,
because you know exactly how to log it,
because you have all the strings.
So if you have a type trait
it supports that no problem.
So I'll give a very quick
explanation of how it works.
There's a lot of different
approaches you could use.
Most of them have issues.
Here's the approach here.
When you do this macro, what comes out,
first of all an actual enum
comes out, and like I said,
a lot of the libraries don't
actually declare enums.
The second thing that
happens is it throws in
a couple of detail functions,
and the detail function
basically takes this tag type,
and the tag type is templated on the enum,
so it's found by A.D.L.
It's all pretty straightforward,
there's nothing very complicated here.
But it does work, so there's
that. Working is good.
Okay, so now I'm going to tell
you why it's good, I think.
First it supports 11, 14,
and 17, and it supports
each one of these idiomatically.
So for instance, if you're using 14,
you get template variables, you don't have
to do the nasty colon colon value.
If you're using 17, it
works with string view
and it works with std::optional.
I already talked before about
declaring an actual enum.
It supports, as far as I
know, all the functionality.
You saw already in a slide that I gave
an explicit value to one enumerator.
You can also explicitly
declare the storage.
You could leave it implicit.
It works at namespace scope,
it works at class scope.
Pretty much any of the
things you want to do.
Enum and enum class, obviously.
You can also adapt a third-party enum.
This is an important feature,
but one that's omitted.
Everything's constexpr if you do it
with 14 or later, absolutely everything.
And also important, is that,
if you do the to-string
conversion, for example,
it actually uses the switch case.
A lot of libraries, they do all kinds
of not so nice workarounds,
either linear search,
which is totally
unnecessary, because you can
usually get really good
assembly from switch case.
Yeah, that's pretty much it.
- [Commenter] All right.
[Audience Applause]
