better-enums/doc/index.html
2015-05-15 10:15:31 -05:00

259 lines
8.5 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<link rel="canonical" href="http://aantron.github.io/better-enums" />
<title>Better Enums - Clean Reflective Enums for C++</title>
<meta name="description" content="Clean, reflective enums for C++11. Conversions
from/to string, constant list, and compile-time operations. Natural syntax
and a high degree of type safety. Generator-free in typical usage. The
library is header-only and easy to install. Since most operations are
constexpr, they can be used in your own compile-time code. The library
depends only on the standard library and one type of compiler extension. It
is therefore almost entirely standard C++. This page is a tutorial." />
<meta name="author" content="Anton Bachin" />
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<nav>
<div>
<a class="first"
href="https://github.com/aantron/better-enums/releases/latest">
Download
</a>
<a href="https://github.com/aantron/better-enums">GitHub</a>
<a href="#tutorial">Tutorial</a>
<a href="https://github.com/aantron/better-enums/tree/master/example">
Samples
</a>
<a href="api.html">Reference</a>
<a href="mailto:antonbachin@yahoo.com">Contact</a>
</div>
</nav>
<header>
<h1>Better Enums</h1>
<h2 class="tagline">Clean compile-time reflective enums for
<span class="cpp">C++</span><span class="eleven">11</span></h2>
<h3>&mdash; <span class="cpp">C++</span><span class="eleven">98</span> support coming soon without the "compile-time" :)</h3>
</header>
<main>
<section>
<p>
Have you noticed the awkward situation with enums in
<span class="cpp">C++</span>? Built-in <code>enum class</code> is missing
basic features, such as string conversion. There are several approaches to
address this, but most seem to involve unnatural syntax or code
repetition. See some <a href="http://stackoverflow.com/questions/201593/is-there-a-simple-script-to-convert-c-enum-to-string">here</a>.
</p>
<p>
Better Enums gives you rich, reflective enums with the nicest syntax yet
seen.<sup><a href="#note">1</a></sup> All you have to do is add two short,
simple header files to your project, and you are ready to go.
</p>
<pre>#include &lt;enum.h&gt;
ENUM(Channel, int, Red, Green, Blue);</pre>
<p>
This gives you an <code>int</code>-sized enum type with all sorts of
reflective capacity, including string conversions, value listing,
compile-time operations, static information about the range of declared
constants, and (last and probably least) the name <code>"Channel"</code>
itself.
</p>
<p>
The enum is easy to maintain. There is no duplication of value names,
no repetition of cumbersome macros, and no generator to run on every
build. The library is header-only and has no dependencies, so there aren't
any object files to link with. You can assign explicit values to constants
and alias them like with a normal <code>enum</code>.
</p>
<p>
Better Enums is free, available under the BSD license. The
author is committed to further development and support, so please
<a href="mailto:antonbachin@yahoo.com">contact me</a>, open an issue on
<a href="https://github.com/aantron/better-enums">GitHub</a>, or ask a
question on Stack Overflow.
</p>
</section>
<section>
<h2>Installation</h2>
<p>
Download the
<a href="https://github.com/aantron/better-enums/releases/latest">
latest release</a>, then copy the files
<code>enum.h</code> and <code>enum_preprocessor_map.h</code> to your
project. That's it! Just make sure both files are in your include path and
you are compiling with <span class="cc">gcc</span> or
<span class="cc">clang</span> in
<span class="cpp">C++</span><span class="eleven">11</span> mode.
</p>
<p>
<span class="cc">msvc</span> support is coming in a near-future version
with some enum features disabled. This is because
<span class="cc">msvc</span>'s support for <code>constexpr</code> is
lagging. The same patch will probably make it possible to use Better Enums
with <span class="cpp">C++</span><span class="eleven">98</span>.
</p>
</section>
<section>
<h2 id="tutorial">Tutorial</h2>
<p>
Create a file and put this code in it:
</p>
<pre>#include &lt;iostream&gt;
#include &lt;enum.h&gt;
ENUM(Channel, int, Red, Green, Blue);
int main()
{
Channel my_channel = Channel::Green;
std::cout
&lt;&lt; "Channel "
&lt;&lt; my_channel.to_string()
&lt;&lt; " has value "
&lt;&lt; my_channel.to_integral()
&lt;&lt; std::endl;
return 0;
}</pre>
<p>
Compile and run, and you should see the output
<samp>Channel Green has value 1</samp>. Congratulations! You have compiled
your first Better Enum.
</p>
<hr />
<p>
Values are assigned to Better Enums just like to regular
<span class="cpp">C++</span> enums. That means you can change the enum
above to something like this:
</p>
<pre>ENUM(Channel, int, Red, Green = 5, Blue, Last = Blue);</pre>
<p>
and the result would be just as you'd expect: <code>Red</code> is 0,
<code>Green</code> is 5, <code>Blue</code> is 6, and <code>Last</code> is
also 6.
</p>
<hr />
<p>
There is no need for <code>Last</code>, however. Every Better Enum comes
with a built-in value called <code>_last</code>. So, if you have
</p>
<pre>ENUM(Channel, int, Red, Green, Blue);</pre>
<p>
Then <code>Channel::_last</code> is <code>Channel::Blue</code>! In fact,
<code>Channel</code> also gets <code>_first</code>, <code>_min</code>,
<code>_max</code>, <code>_span</code>, and <code>_size</code>. These
built-in values have underscores so that you can define your own enums
without having to worry about naming problems:
</p>
<pre>ENUM(Position, int, first, last, other);</pre>
<hr />
<p>
You already saw how to convert an enum to a string or an integer. As you
might guess, it is also possible to go the other way:
<p>
<pre>Channel my_channel = Channel::_from_string("Blue");
Channel my_channel = Channel::_from_integral(2);</pre>
<p>
If your code tries to convert an invalid string or integer to a
<code>Channel</code>, it will get an <code>std::runtime_error</code>
exception.
</p>
<hr />
<p>
You can iterate over all the declared values of an enum:
</p>
<pre>for(Channel channel : Channel::_values)
std::cout &lt;&lt; channel.to_string() &lt;&lt; std::endl;</pre>
<p>
and directly over their names with <code>Channel::_names</code>.
</p>
<hr />
<p>
Finally, most of the above is declared <code>constexpr</code> and can be
run at compile time. This means you can do all sorts of parsing and
processing at the same time the rest of your code is being compiled,
improving runtime and startup performance! See some
<a href="https://github.com/aantron/better-enums/blob/master/example/4-constexpr.cc">examples</a>
and another
<a href="https://github.com/aantron/better-enums/blob/master/example/6-traits.cc">example</a>.
</p>
</section>
<section>
<h2>Where to go from here</h2>
<ul>
<li><a href="https://github.com/aantron/better-enums/releases/latest">
Download Better Enums</a> and start using them in your project</li>
<li>Browse the commented code
<a href="https://github.com/aantron/better-enums/tree/master/example">
samples</a>, including advanced usage</li>
<li>Read the <a href="api.html">API documentation</a></li>
<li style="display: none;">See results of <a href="performance.html">performance testing</a></li>
<li>View, discuss, and contribute on
<a href="https://github.com/aantron/better-enums">GitHub</a></li>
<li>
<a href="mailto:antonbachin@yahoo.com">Contact the author</a> directly
&mdash; all feedback is welcome!
</li>
</ul>
</section>
</main>
<footer>
Copyright &copy; 2015 Anton Bachin. Released under the BSD 2-clause license.
See <a href="https://github.com/aantron/better-enums/blob/master/LICENSE">
LICENSE</a>.
<br />
This page is part of the documentation for Better Enums 0.8.0.
<br />
<br />
<span id="note"><sup>1</sup> Yet seen by the author, of course :)</span>
</footer>
</body>
</html>