better-enums/demo/BitSets.html
2020-10-19 09:11:42 +03:00

155 lines
5.1 KiB
HTML

<!-- Generated automatically - edit the templates! -->
<!DOCTYPE html>
<html>
<head>
<title>Bit sets - Better Enums</title>
<link rel="canonical" href="http://aantron.github.io/better-enums/demo/BitSets.html" />
<meta name="description" content="Finding the maximum value of a Better Enum for use in declaring
statically-sized bit set types." />
<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">&nbsp;</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>
This is an example of code you can write on top of Better Enums. It's a valid
program &mdash; you can <a href="https://github.com/aantron/better-enums/blob/0.11.3/example/103-bitset.cc">download</a> it and try it out. The
program is also part of the test suite.
</p>
<h2>Bit sets</h2>
<p>If you want to use <code>std::bitset</code> or a similar library to have enums be keys into
a bit set, you need to know the number of bits at compile time. You can easily
automate this with Better Enums, even when constants are not declared in
increasing order.</p>
<hr>
<p>We simply need to find the maximum value of any given enum type.</p>
<pre>#include &lt;bitset&gt;
#include &lt;iostream&gt;
<em>#include &lt;enum.h&gt;</em>
template &lt;<em>typename Enum</em>&gt;
constexpr <em>Enum max_loop</em>(Enum accumulator, size_t index)
{
return
<em>index &gt;= Enum::_size() ? accumulator :
Enum::_values()[index] &gt; accumulator ?
max_loop&lt;Enum&gt;(Enum::_values()[index], index + 1) :
max_loop&lt;Enum&gt;(accumulator, index + 1)</em>;
}
template &lt;<em>typename Enum</em>&gt;
constexpr <em>Enum max</em>()
{
return <em>max_loop&lt;Enum&gt;(Enum::_values()[0], 1)</em>;
}</pre><p>And use that to declare a bit set template:</p>
<pre>template &lt;<em>typename Enum</em>&gt;
using <em>EnumSet</em> = <em>std::bitset</em>&lt;<em>max&lt;Enum&gt;()._to_integral()</em> + <em>1</em>&gt;;</pre><p>Now, we can have bit sets that are wide enough to hold whatever range we
declared. We just declare enums, and the numeric values of their constants will
be bit indices. The rest is straightforward.</p>
<pre>BETTER_ENUM(<em>EFLAGS</em>, int,
<em>Carry</em>, <em>Parity</em> = 2, <em>Adjust</em> = 4, <em>Zero</em>, <em>Sign</em>, <em>Trap</em>, <em>Interrupt</em>, <em>Direction</em>,
<em>Overflow</em>, <em>NestedTask</em> = 14, <em>Resume</em> = 16, <em>V8086</em>, <em>AlignmentCheck</em>,
<em>CPUIDPresent</em> = 21)
int main()
{
<em>EnumSet</em>&lt;<em>EFLAGS</em>&gt; eflags = <em>1 &lt;&lt; EFLAGS::Carry</em> | <em>1 &lt;&lt; EFLAGS::Zero</em>;
if (eflags.test(<em>EFLAGS::Carry</em>))
eflags.set(<em>EFLAGS::Trap</em>);
std::cout &lt;&lt; <em>eflags</em> &lt;&lt; std::endl;
return 0;
}</pre><hr>
<p>If we want bit sets of fixed known width instead, we can use the code above to
check that we haven't declared any bit indices out of range:</p>
<pre class="comment">static_assert(max&lt;EFLAGS&gt;()._to_integral() &lt; 32,
"some bit indices are out of range");</pre>
<section class="tutorial-footer">
<p class="up">
Return to the <a href="../index.html#CompileTimeDemos">demo index</a>.
</p>
</section>
</div>
</div>
<footer>
<div class="container">
Copyright &copy; 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>