mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-06 08:46:42 +08:00
163 lines
6.3 KiB
HTML
163 lines
6.3 KiB
HTML
<!-- Generated automatically - edit the templates! -->
|
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
<head>
|
|
|
|
<title>Maps - Better Enums</title>
|
|
|
|
<link rel="canonical" href="http://aantron.github.io/better-enums/tutorial/Maps.html" />
|
|
<meta name="description" content="Mapping enums to arbitrary types and vice versa." />
|
|
<meta name="author" content="Anton Bachin" />
|
|
|
|
<meta name="viewport" content="width=device-width" />
|
|
|
|
<link rel="stylesheet" href="../better-enums.css" />
|
|
|
|
<script>
|
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
|
|
|
ga('create', 'UA-62962513-1', 'auto');
|
|
ga('send', 'pageview');
|
|
|
|
</script>
|
|
|
|
</head>
|
|
<body class="">
|
|
|
|
<nav>
|
|
<div class="container">
|
|
<a class="first" href="https://raw.githubusercontent.com/aantron/better-enums/0.11.3/enum.h"
|
|
download>Download</a>
|
|
<a href="https://github.com/aantron/better-enums">GitHub</a>
|
|
<a href="../index.html">Home</a>
|
|
<a href="../tutorial/HelloWorld.html">Tutorial</a>
|
|
<a href="../ApiReference.html">Reference</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="spacer"> </div>
|
|
|
|
<header>
|
|
<div class="container">
|
|
<section>
|
|
<h1><a href="../index.html">Better Enums</a></h1>
|
|
<h2>Reflective compile-time enums for <span class="cpp">C++</span></h2>
|
|
<h3>Open-source under the BSD license</h3>
|
|
</section>
|
|
|
|
<section class="notes">
|
|
<p>Version 0.11.3</p>
|
|
<p>To install, just add <code>enum.h</code> to your project.</p>
|
|
<p>
|
|
Visit the GitHub repo for issues, feedback, and the latest development.
|
|
</p>
|
|
</section>
|
|
|
|
<section class="buttons">
|
|
<a href="https://raw.githubusercontent.com/aantron/better-enums/0.11.3/enum.h"
|
|
download>Download <code>enum.h</code></a>
|
|
<a href="https://github.com/aantron/better-enums">GitHub</a>
|
|
</section>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="main">
|
|
<div class="container">
|
|
|
|
|
|
<p>
|
|
Welcome to the Better Enums tutorials! The code in this tutorial forms a
|
|
valid program, which you can <a href="https://github.com/aantron/better-enums/blob/0.11.3/example/5-map.cc">download</a> and play with. The
|
|
program runs as part of the automated test suite.
|
|
</p>
|
|
|
|
<h2>Maps</h2>
|
|
<p>It is possible to create <code>constexpr</code> bidirectional maps between Better Enums and
|
|
any type. This is currently an experimental feature. Feedback is very much
|
|
wanted, but please don't build any mission-critical code on top of this :)</p>
|
|
<p>The way it works is you give Better Enums a function — say,
|
|
<code>const char* describe(Channel)</code>. The library enumerates it to make a map.</p>
|
|
<p>The reason for using a function is that a <code>switch</code> statement is, I believe, the
|
|
only place where a compiler will check for exhaustiveness. If you forget to
|
|
create a case for one of the enum's constants, the compiler can let you know.
|
|
Obviously, a <code>switch</code> statement is not data, and needs to be inside a function.
|
|
It can only be inside a <code>constexpr</code> function in <span class="cpp">C++</span><span class="eleven">14</span>, so this feature is most
|
|
natural in <span class="cpp">C++</span><span class="eleven">14</span>. When you pass the function to Better Enums, the library can
|
|
build up a lookup data structure at compile time.</p>
|
|
<p>Actually, right now, Better Enums doesn't quite do that — it enumerates
|
|
the function <em>every</em> time you want to convert to an enum (but not <em>from</em> an
|
|
enum). It simply does a linear scan every time. This is because I haven't yet
|
|
found a data structure whose compile-time generation is fast enough for
|
|
practical use.</p>
|
|
<hr>
|
|
<pre>#include <iostream>
|
|
<em>#include</em> <<em>enum.h</em>>
|
|
|
|
<em>BETTER_ENUM</em>(<em>Channel</em>, <em>int</em>, <em>Red</em>, <em>Green</em>, <em>Blue</em>)</pre><p>We will create a map from this function:</p>
|
|
<pre>constexpr <em>const char* describe</em>(<em>Channel channel</em>)
|
|
{
|
|
switch(<em>channel</em>) {
|
|
case <em>Channel::Red</em>: return <em>"the red channel"</em>;
|
|
case <em>Channel::Green</em>: return <em>"the green channel"</em>;
|
|
case <em>Channel::Blue</em>: return <em>"the blue channel"</em>;
|
|
}
|
|
|
|
return "needed for gcc 5";
|
|
}</pre><p>Here is the map. The actual type is <code>better_enums::map<Channel, const char*></code>.</p>
|
|
<pre>constexpr auto <em>descriptions</em> = <em>better_enums::make_map</em>(<em>describe</em>);</pre><p>And the usage:</p>
|
|
<pre>int main()
|
|
{
|
|
std::cout << <em>descriptions[Channel::Red]</em> << std::endl;
|
|
|
|
std::cout << <em>descriptions</em>.<em>from_enum</em>(<em>Channel::Red</em>) << std::endl;
|
|
std::cout << <em>descriptions</em>.<em>to_enum</em>(<em>"the green channel"</em>) << std::endl;
|
|
|
|
auto <em>not_a_literal</em> = <em>std::string</em>(<em>"the blue channel"</em>);
|
|
std::cout << <em>descriptions</em>.<em>to_enum</em>(<em>not_a_literal</em>.<em>c_str()</em>) << std::endl;
|
|
|
|
return 0;
|
|
}</pre><hr>
|
|
<p><code>make_map</code> above produces a value of type <code>better_enums::map<E, T></code>. The full
|
|
signature of the template <code>better_enums::map</code> is</p>
|
|
<pre class="comment"><em>template <typename Enum, typename T, typename Compare = map_compare<T>></em></pre><p><code>Compare</code> has to be a class with a static member function
|
|
<code>bool less(const T&, const T&)</code>. The default implementation
|
|
<code>better_enums::map_compare</code> simply applies <code>operator <</code>, except when <code>T</code> is
|
|
<code>const char*</code> or <code>const wchar_t*</code>. In that case, it does lexicographic comparison.</p>
|
|
|
|
|
|
<section class="tutorial-footer">
|
|
<p class="next">
|
|
Continue to the next tutorial: <a href="../tutorial/StreamOperators.html">Stream operators</a>
|
|
</p>
|
|
|
|
<p class="up">
|
|
Or, return to the
|
|
<a href="../index.html#Tutorial">tutorial index</a>.
|
|
</p>
|
|
</section>
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<footer>
|
|
<div class="container">
|
|
Copyright © 2015-2019 Anton Bachin. Released under the BSD 2-clause
|
|
license. See
|
|
<a href="https://github.com/aantron/better-enums/blob/0.11.3/doc/LICENSE">
|
|
LICENSE</a>.
|
|
<br />
|
|
This page is part of the documentation for Better Enums 0.11.3.
|
|
</div>
|
|
</footer>
|
|
|
|
</body>
|
|
</html>
|
|
|