mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-06 16:56:42 +08:00
155 lines
5.1 KiB
HTML
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"> </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 — 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 <bitset>
|
|
#include <iostream>
|
|
<em>#include <enum.h></em>
|
|
|
|
template <<em>typename Enum</em>>
|
|
constexpr <em>Enum max_loop</em>(Enum accumulator, size_t index)
|
|
{
|
|
return
|
|
<em>index >= Enum::_size() ? accumulator :
|
|
Enum::_values()[index] > accumulator ?
|
|
max_loop<Enum>(Enum::_values()[index], index + 1) :
|
|
max_loop<Enum>(accumulator, index + 1)</em>;
|
|
}
|
|
|
|
template <<em>typename Enum</em>>
|
|
constexpr <em>Enum max</em>()
|
|
{
|
|
return <em>max_loop<Enum>(Enum::_values()[0], 1)</em>;
|
|
}</pre><p>And use that to declare a bit set template:</p>
|
|
<pre>template <<em>typename Enum</em>>
|
|
using <em>EnumSet</em> = <em>std::bitset</em><<em>max<Enum>()._to_integral()</em> + <em>1</em>>;</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><<em>EFLAGS</em>> eflags = <em>1 << EFLAGS::Carry</em> | <em>1 << EFLAGS::Zero</em>;
|
|
|
|
if (eflags.test(<em>EFLAGS::Carry</em>))
|
|
eflags.set(<em>EFLAGS::Trap</em>);
|
|
|
|
std::cout << <em>eflags</em> << 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<EFLAGS>()._to_integral() < 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 © 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>
|
|
|