[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,62 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Acknowledgements</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../boost_pfr.html" title="Chapter 28. Boost.PFR 2.0">
<link rel="prev" href="how_it_works.html" title="How it works">
<link rel="next" href="../reference_section.html" title="Reference Section">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="how_it_works.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../reference_section.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_pfr.acknowledgements"></a><a class="link" href="acknowledgements.html" title="Acknowledgements">Acknowledgements</a>
</h2></div></div></div>
<p>
Many thanks to Bruno Dutra for showing the technique to precisely reflect aggregate
initializable type in C++14 <a href="https://github.com/apolukhin/magic_get/issues/5" target="_top">Manual
type registering/structured bindings might be unnecessary</a>.
</p>
<p>
Many thanks to Alexandr Poltavsky for initial implementation the <span class="bold"><strong>BOOST_PFR_USE_LOOPHOLE == 1</strong></span> technique and for describing
it <a href="http://alexpolt.github.io/type-loophole.html" target="_top">in his blog</a>.
</p>
<p>
Many thanks to Chris Beck for implementing the detect-offsets-and-get-field-address
functionality that avoids Undefined Behavior of reinterpret_casting layout
compatible structures.
</p>
<p>
Many thanks to the Boost people who participated in the formal review, especially
to Benedek Thaler, Steven Watanabe and Andrzej Krzemienski.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2016-2021 Antony Polukhin<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="how_it_works.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../reference_section.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,160 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>How it works</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../boost_pfr.html" title="Chapter 28. Boost.PFR 2.0">
<link rel="prev" href="limitations_and_configuration.html" title="Limitations and Configuration">
<link rel="next" href="acknowledgements.html" title="Acknowledgements">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="limitations_and_configuration.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_pfr.how_it_works"></a><a class="link" href="how_it_works.html" title="How it works">How it works</a>
</h2></div></div></div>
<p>
Short description:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
at compile-time: use aggregate initialization to detect fields count in
user-provided structure
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>BOOST_PFR_USE_CPP17 == 1</strong></span>:
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
at compile-time: structured bindings are used to decompose
a type <code class="computeroutput"><span class="identifier">T</span></code> to
known amount of fields
</li></ol></div>
</li>
<li class="listitem">
<span class="bold"><strong>BOOST_PFR_USE_CPP17 == 0 &amp;&amp; BOOST_PFR_USE_LOOPHOLE
== 1</strong></span>:
<div class="orderedlist"><ol class="orderedlist" type="a">
<li class="listitem">
at compile-time: use aggregate initialization to detect fields
count in user-provided structure
</li>
<li class="listitem">
at compile-time: make a structure that is convertible to anything
and remember types it has been converted to during aggregate
initialization of user-provided structure
</li>
<li class="listitem">
at compile-time: using knowledge from previous steps create
a tuple with exactly the same layout as in user-provided structure
</li>
<li class="listitem">
at compile-time: find offsets for each field in user-provided
structure using the tuple from previous step
</li>
<li class="listitem">
at run-time: get pointer to each field, knowing the structure
address and each field offset
</li>
<li class="listitem">
at run-time: a tuple of references to fields is returned =&gt;
all the tuple methods are available for the structure
</li>
</ol></div>
</li>
<li class="listitem">
<span class="bold"><strong>BOOST_PFR_USE_CPP17 == 0 &amp;&amp; BOOST_PFR_USE_LOOPHOLE
== 0</strong></span>:
<div class="orderedlist"><ol class="orderedlist" type="a">
<li class="listitem">
at compile-time: let <code class="computeroutput"><span class="identifier">I</span></code>
be is an index of current field, it equals 0
</li>
<li class="listitem">
<p class="simpara">
at run-time: <code class="computeroutput"><span class="identifier">T</span></code>
is constructed and field <code class="computeroutput"><span class="identifier">I</span></code>
is aggregate initialized using a separate instance of structure
that is convertible to anything
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Additional care is taken to make sure that all the information
about <code class="computeroutput"><span class="identifier">T</span></code> is
available to the compiler and that operations on <code class="computeroutput"><span class="identifier">T</span></code> have no side effects,
so the compiler can optimize away the unnecessary temporary
objects.
</p></td></tr>
</table></div>
</li>
<li class="listitem">
at compile-time: <code class="computeroutput"><span class="identifier">I</span>
<span class="special">+=</span> <span class="number">1</span></code>
</li>
<li class="listitem">
at compile-time: if <code class="computeroutput"><span class="identifier">I</span></code>
does not equal fields count goto step <em class="replaceable"><code>c.</code></em>
from inside of the conversion operator of the structure that
is convertible to anything
</li>
<li class="listitem">
at compile-time: using knowledge from previous steps create
a tuple with exactly the same layout as in user-provided structure
</li>
<li class="listitem">
at compile-time: find offsets for each field in user-provided
structure using the tuple from previous step
</li>
<li class="listitem">
at run-time: get pointer to each field, knowing the structure
address and each field offset
</li>
</ol></div>
</li>
</ul></div>
</li>
<li class="listitem">
at run-time: a tuple of references to fields is returned =&gt; all the
tuple methods are available for the structure
</li>
</ol></div>
<p>
Long description of some basics: <a href="https://youtu.be/UlNUNxLtBI0" target="_top">Antony
Polukhin: Better C++14 reflections</a>. Long description of some basics
of C++14 with <a class="link" href="limitations_and_configuration.html" title="Limitations and Configuration"><span class="bold"><strong>BOOST_PFR_USE_LOOPHOLE == 0</strong></span></a>: <a href="https://youtu.be/abdeAew3gmQ" target="_top">Antony
Polukhin: C++14 Reflections Without Macros, Markup nor External Tooling</a>.
Description of the <span class="bold"><strong>BOOST_PFR_USE_LOOPHOLE == 1</strong></span>
technique by its inventor Alexandr Poltavsky <a href="http://alexpolt.github.io/type-loophole.html" target="_top">in
his blog</a>.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2016-2021 Antony Polukhin<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="limitations_and_configuration.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,207 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Limitations and Configuration</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../boost_pfr.html" title="Chapter 28. Boost.PFR 2.0">
<link rel="prev" href="tutorial.html" title="Tutorial">
<link rel="next" href="how_it_works.html" title="How it works">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="how_it_works.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_pfr.limitations_and_configuration"></a><a class="link" href="limitations_and_configuration.html" title="Limitations and Configuration">Limitations and
Configuration</a>
</h2></div></div></div>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../doc/src/images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
Recommended C++ Standards are C++17 and above. Library requires at least
C++14! Pre C++14 compilers (C++11, C++03...) are not supported.
</p></td></tr>
</table></div>
<p>
Boost.PFR library works with types that satisfy the requirements of <code class="computeroutput"><span class="identifier">SimpleAggregate</span></code>: aggregate types without
base classes, <code class="computeroutput"><span class="keyword">const</span></code> fields, references,
or C arrays:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">simple_aggregate</span> <span class="special">{</span> <span class="comment">// SimpleAggregate</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uuids</span><span class="special">::</span><span class="identifier">uuid</span> <span class="identifier">uuid</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">empty</span> <span class="special">{</span> <span class="comment">// SimpleAggregate</span>
<span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">aggregate</span> <span class="special">:</span> <span class="identifier">empty</span> <span class="special">{</span> <span class="comment">// not a SimpleAggregate</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">uuids</span><span class="special">::</span><span class="identifier">uuid</span> <span class="identifier">uuid</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
The library may work with aggregates that don't satisfy the requirements of
<code class="computeroutput"><span class="identifier">SimpleAggregate</span></code>, but the behavior
tends to be non-portable.
</p>
<h3>
<a name="boost_pfr.limitations_and_configuration.h0"></a>
<span class="phrase"><a name="boost_pfr.limitations_and_configuration.configuration_macro"></a></span><a class="link" href="limitations_and_configuration.html#boost_pfr.limitations_and_configuration.configuration_macro">Configuration
Macro</a>
</h3>
<p>
By default Boost.PFR <span class="bold"><strong>auto-detects your compiler abilities</strong></span>
and automatically defines the configuration macro into appropriate values.
If you wish to override that behavior, just define:
</p>
<div class="table">
<a name="boost_pfr.limitations_and_configuration.linkmacro"></a><p class="title"><b>Table 28.2. Macros</b></p>
<div class="table-contents"><table class="table" summary="Macros">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Macro name
</p>
</th>
<th>
<p>
Effect
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<span class="bold"><strong>BOOST_PFR_USE_CPP17</strong></span>
</p>
</td>
<td>
<p>
Define to <code class="computeroutput"><span class="number">1</span></code> if you wish
to override Boost.PFR choice and use C++17 structured bindings for
reflection. Define to <code class="computeroutput"><span class="number">0</span></code>
to override Boost.PFR choice and disable C++17 structured bindings
usage.
</p>
</td>
</tr>
<tr>
<td>
<p>
<span class="bold"><strong>BOOST_PFR_USE_LOOPHOLE</strong></span>
</p>
</td>
<td>
<p>
Define to <code class="computeroutput"><span class="number">1</span></code> if you wish
to override Boost.PFR choice and exploit <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118" target="_top">CWG
2118</a> for reflection. Define to <code class="computeroutput"><span class="number">0</span></code>
to override Boost.PFR choice and disable CWG 2118 usage.
</p>
</td>
</tr>
<tr>
<td>
<p>
<span class="bold"><strong>BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE</strong></span>
</p>
</td>
<td>
<p>
Define to <code class="computeroutput"><span class="number">0</span></code> if you are
hit by the template instantiation depth issues with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_integer_sequence</span></code> and wish
to use Boost.PFR version of that metafunction. Define to <code class="computeroutput"><span class="number">1</span></code> to override Boost.PFR detection logic.
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><h3>
<a name="boost_pfr.limitations_and_configuration.h1"></a>
<span class="phrase"><a name="boost_pfr.limitations_and_configuration.details_on_limitations"></a></span><a class="link" href="limitations_and_configuration.html#boost_pfr.limitations_and_configuration.details_on_limitations">Details
on Limitations</a>
</h3>
<p>
The Boost.PFRs reflection has some limitations that depend on a C++ Standard
and compiler capabilities:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Static variables are ignored
</li>
<li class="listitem">
T must be aggregate initializable without empty base classes
</li>
<li class="listitem">
if T contains C arrays or it is inherited from non-empty type then the
result of reflection may differ depending on the C++ version and library
configuration
</li>
<li class="listitem">
Additional limitations if <span class="bold"><strong>BOOST_PFR_USE_CPP17 ==
0</strong></span>:
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
Non of the member fields should have a template constructor from
one parameter.
</li>
<li class="listitem">
Additional limitations if <span class="bold"><strong>BOOST_PFR_USE_LOOPHOLE
== 0</strong></span>:
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: square; ">
<li class="listitem">
T must be constexpr aggregate initializable and all its fields
must be constexpr default constructible
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/pfr/get.html" title="Function get">boost::pfr::get</a></code>,
<code class="computeroutput"><a class="link" href="../boost/pfr/structure_to_tuple.html" title="Function template structure_to_tuple">boost::pfr::structure_to_tuple</a></code>,
<code class="computeroutput"><a class="link" href="../boost/pfr/structure_tie.html" title="Function structure_tie">boost::pfr::structure_tie</a></code>,
<code class="computeroutput"><a class="link" href="../reference_section.html#header.boost.pfr.core_hpp" title="Header &lt;boost/pfr/core.hpp&gt;">boost::pfr::tuple_element</a></code>
require T to be a POD type with built-in types only.
</li>
</ul></div>
</li>
</ul></div>
</li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2016-2021 Antony Polukhin<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="how_it_works.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,311 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Short Examples for the Impatient</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../boost_pfr.html" title="Chapter 28. Boost.PFR 2.0">
<link rel="prev" href="../boost_pfr.html" title="Chapter 28. Boost.PFR 2.0">
<link rel="next" href="tutorial.html" title="Tutorial">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost_pfr.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutorial.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_pfr.short_examples_for_the_impatient"></a><a class="link" href="short_examples_for_the_impatient.html" title="Short Examples for the Impatient">Short Examples
for the Impatient</a>
</h2></div></div></div>
<div class="informaltable">
<a name="boost_pfr.short_examples_for_the_impatient.quick_examples"></a><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Code snippet
</p>
</th>
<th>
<p>
Reference:
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Get field by index and assign new value to that field</span>
<span class="keyword">struct</span> <span class="identifier">sample</span> <span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">c</span><span class="special">;</span>
<span class="keyword">float</span> <span class="identifier">f</span><span class="special">;</span>
<span class="special">};</span>
<span class="identifier">sample</span> <span class="identifier">var</span><span class="special">{};</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">var</span><span class="special">)</span> <span class="special">=</span> <span class="number">42.01f</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">var</span><span class="special">.</span><span class="identifier">f</span><span class="special">;</span> <span class="comment">// Outputs: 42.01</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../boost/pfr/get.html" title="Function get">boost::pfr::get</a></code>
</p>
</td>
</tr>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Assert equality.</span>
<span class="comment">// Note that the equality operator for structure is not defined.</span>
<span class="keyword">struct</span> <span class="identifier">test</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">f1</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span> <span class="identifier">f2</span><span class="special">;</span>
<span class="special">};</span>
<span class="identifier">assert</span><span class="special">(</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">eq</span><span class="special">(</span><span class="identifier">test</span><span class="special">{</span><span class="string">"aaa"</span><span class="special">,</span> <span class="string">"zomg"</span><span class="special">},</span> <span class="identifier">test</span><span class="special">{</span><span class="string">"aaa"</span><span class="special">,</span> <span class="string">"zomg"</span><span class="special">})</span>
<span class="special">);</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../reference_section.html#header.boost.pfr.ops_hpp" title="Header &lt;boost/pfr/ops.hpp&gt;">Header boost/pfr/ops.hpp</a></code>:
</p>
<p>
* <code class="computeroutput"><a class="link" href="../boost/pfr/eq.html" title="Function eq">boost::pfr::eq</a></code>
</p>
<p>
* <code class="computeroutput"><a class="link" href="../boost/pfr/ne.html" title="Function ne">boost::pfr::ne</a></code>
</p>
<p>
* <code class="computeroutput"><a class="link" href="../boost/pfr/gt.html" title="Function gt">boost::pfr::gt</a></code>
</p>
<p>
* ...
</p>
</td>
</tr>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Increment each field of the variable on 1 and</span>
<span class="comment">// output the content of the variable.</span>
<span class="keyword">struct</span> <span class="identifier">test</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">f1</span><span class="special">;</span>
<span class="keyword">long</span> <span class="identifier">f2</span><span class="special">;</span>
<span class="special">};</span>
<span class="identifier">test</span> <span class="identifier">var</span><span class="special">{</span><span class="number">42</span><span class="special">,</span> <span class="number">43</span><span class="special">};</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">for_each_field</span><span class="special">(</span><span class="identifier">var</span><span class="special">,</span> <span class="special">[](</span><span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">field</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">field</span> <span class="special">+=</span> <span class="number">1</span><span class="special">;</span>
<span class="special">});</span>
<span class="comment">// Outputs: {43, 44}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">io</span><span class="special">(</span><span class="identifier">var</span><span class="special">);</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../boost/pfr/for_each_field.html" title="Function template for_each_field">boost::pfr::for_each_field</a></code>
</p>
<p>
<code class="computeroutput"><a class="link" href="../boost/pfr/io.html" title="Function template io">boost::pfr::io</a></code>
</p>
</td>
</tr>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Define all the comparison and IO operators for my_structure type along</span>
<span class="comment">// with hash_value function.</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">functions_for</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">my_namespace</span> <span class="special">{</span>
<span class="keyword">struct</span> <span class="identifier">my_structure</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">,</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">e</span><span class="special">,</span><span class="identifier">f</span><span class="special">,</span><span class="identifier">g</span><span class="special">;</span>
<span class="comment">// ...</span>
<span class="special">};</span>
<span class="identifier">BOOST_PFR_FUNCTIONS_FOR</span><span class="special">(</span><span class="identifier">my_structure</span><span class="special">)</span>
<span class="special">}</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../BOOST_PFR_FUNCTIONS_FOR.html" title="Macro BOOST_PFR_FUNCTIONS_FOR">BOOST_PFR_FUNCTIONS_FOR</a></code>
</p>
</td>
</tr>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Define only the equality and inequality operators for my_eq_ne_structure.</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">functions_for</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">my_namespace</span> <span class="special">{</span>
<span class="keyword">struct</span> <span class="identifier">my_eq_ne_structure</span> <span class="special">{</span>
<span class="keyword">float</span> <span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">,</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">e</span><span class="special">,</span><span class="identifier">f</span><span class="special">,</span><span class="identifier">g</span><span class="special">;</span>
<span class="comment">// ...</span>
<span class="special">};</span>
<span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">my_eq_ne_structure</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">my_eq_ne_structure</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">eq_fields</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">my_eq_ne_structure</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">my_eq_ne_structure</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">ne_fields</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../reference_section.html#header.boost.pfr.ops_fields_hpp" title="Header &lt;boost/pfr/ops_fields.hpp&gt;">Header boost/pfr/ops_fields.hpp
</a></code>:
</p>
<p>
* <code class="computeroutput"><a class="link" href="../boost/pfr/eq_fields.html" title="Function template eq_fields">boost::pfr::eq_fields</a></code>
</p>
<p>
* <code class="computeroutput"><a class="link" href="../boost/pfr/ne_fields.html" title="Function template ne_fields">boost::pfr::ne_fields</a></code>
</p>
<p>
* <code class="computeroutput"><a class="link" href="../boost/pfr/gt_fields.html" title="Function template gt_fields">boost::pfr::gt_fields</a></code>
</p>
<p>
* ...
</p>
<p>
<code class="computeroutput"><a class="link" href="../reference_section.html#header.boost.pfr.io_fields_hpp" title="Header &lt;boost/pfr/io_fields.hpp&gt;">Header boost/pfr/io_fields.hpp
</a></code>
</p>
<p>
* <code class="computeroutput"><a class="link" href="../boost/pfr/io_fields.html" title="Function template io_fields">boost::pfr::io_fields</a></code>
</p>
</td>
</tr>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Iterate over fields of a varible and output index and</span>
<span class="comment">// type of a variable.</span>
<span class="keyword">struct</span> <span class="identifier">tag0</span><span class="special">{};</span>
<span class="keyword">struct</span> <span class="identifier">tag1</span><span class="special">{};</span>
<span class="keyword">struct</span> <span class="identifier">sample</span> <span class="special">{</span>
<span class="identifier">tag0</span> <span class="identifier">a</span><span class="special">;</span>
<span class="identifier">tag1</span> <span class="identifier">b</span><span class="special">;</span>
<span class="special">};</span>
<span class="comment">// Outputs:</span>
<span class="comment">// 0: tag0</span>
<span class="comment">// 1: tag1</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">for_each_field</span><span class="special">(</span><span class="identifier">sample</span><span class="special">{},</span> <span class="special">[](</span><span class="keyword">const</span> <span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">field</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">idx</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span> <span class="special">&lt;&lt;</span> <span class="identifier">idx</span> <span class="special">&lt;&lt;</span> <span class="string">": "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">typeindex</span><span class="special">::</span><span class="identifier">type_id_runtime</span><span class="special">(</span><span class="identifier">field</span><span class="special">);</span>
<span class="special">});</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../boost/pfr/for_each_field.html" title="Function template for_each_field">boost::pfr::for_each_field</a></code>
</p>
</td>
</tr>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Getting fields count of some structure</span>
<span class="keyword">struct</span> <span class="identifier">some</span> <span class="special">{</span> <span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">,</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">e</span><span class="special">;</span> <span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Fields count in structure: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">tuple_size</span><span class="special">&lt;</span><span class="identifier">some</span><span class="special">&gt;::</span><span class="identifier">value</span> <span class="comment">// Outputs: 5</span>
<span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../boost/pfr/tuple_size.html" title="Type definition tuple_size">boost::pfr::tuple_size</a></code>
</p>
</td>
</tr>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Getting a std::tuple of values from structures fields</span>
<span class="keyword">struct</span> <span class="identifier">foo</span> <span class="special">{</span> <span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">other</span> <span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">c</span><span class="special">;</span>
<span class="identifier">foo</span> <span class="identifier">nested</span><span class="special">;</span>
<span class="special">};</span>
<span class="identifier">other</span> <span class="identifier">var</span><span class="special">{</span><span class="char">'A'</span><span class="special">,</span> <span class="special">{</span><span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">}};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">&gt;</span> <span class="identifier">t</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">structure_to_tuple</span><span class="special">(</span><span class="identifier">var</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">)</span> <span class="special">==</span> <span class="char">'A'</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">eq</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">),</span> <span class="identifier">foo</span><span class="special">{</span><span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">})</span>
<span class="special">);</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../boost/pfr/structure_to_tuple.html" title="Function template structure_to_tuple">boost::pfr::structure_to_tuple</a></code>
</p>
</td>
</tr>
<tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Getting a std::tuple of references to structure fields</span>
<span class="keyword">struct</span> <span class="identifier">foo</span> <span class="special">{</span> <span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">other</span> <span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">c</span><span class="special">;</span>
<span class="identifier">foo</span> <span class="identifier">f</span><span class="special">;</span>
<span class="special">};</span>
<span class="identifier">other</span> <span class="identifier">var</span><span class="special">{</span><span class="char">'A'</span><span class="special">,</span> <span class="special">{</span><span class="number">14</span><span class="special">,</span> <span class="number">15</span><span class="special">}};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&amp;,</span> <span class="identifier">foo</span><span class="special">&amp;&gt;</span> <span class="identifier">t</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">structure_tie</span><span class="special">(</span><span class="identifier">var</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">foo</span><span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">io</span><span class="special">(</span><span class="identifier">var</span><span class="special">.</span><span class="identifier">f</span><span class="special">);</span> <span class="comment">// Outputs: {1, 2}</span>
</pre>
</td>
<td>
<p>
<code class="computeroutput"><a class="link" href="../boost/pfr/structure_tie.html" title="Function structure_tie">boost::pfr::structure_tie</a></code>
</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2016-2021 Antony Polukhin<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost_pfr.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutorial.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,524 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tutorial</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../boost_pfr.html" title="Chapter 28. Boost.PFR 2.0">
<link rel="prev" href="short_examples_for_the_impatient.html" title="Short Examples for the Impatient">
<link rel="next" href="limitations_and_configuration.html" title="Limitations and Configuration">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="short_examples_for_the_impatient.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="limitations_and_configuration.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_pfr.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="tutorial.html#boost_pfr.tutorial.why_tuples_are_bad_and_aggregate">Why
tuples are bad and aggregates are more preferable?</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_pfr.tutorial.accessing_structure_member_by_in">Accessing
structure member by index</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_pfr.tutorial.custom_printing_of_aggregates">Custom
printing of aggregates</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_pfr.tutorial.three_ways_of_getting_operators">Three
ways of getting operators </a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_pfr.tutorial.reflection_of_unions">Reflection of
unions </a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_pfr.tutorial.why_tuples_are_bad_and_aggregate"></a><a class="link" href="tutorial.html#boost_pfr.tutorial.why_tuples_are_bad_and_aggregate" title="Why tuples are bad and aggregates are more preferable?">Why
tuples are bad and aggregates are more preferable?</a>
</h3></div></div></div>
<p>
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code>
are good for generic programming, however they have disadvantages. First
of all, code that uses them becomes barely readable. Consider two definitions:
</p>
<div class="informaltable">
<a name="boost_pfr.tutorial.why_tuples_are_bad_and_aggregate.tuples_vs_aggregates"></a><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Tuple
</p>
</th>
<th>
<p>
Aggregate
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">using</span> <span class="identifier">auth_info_tuple</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span><span class="special">,</span> <span class="comment">// What does this integer represents?</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">time_t</span>
<span class="special">&gt;;</span>
</pre>
</td>
<td>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">auth_info_aggregate</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span> <span class="identifier">user_id</span><span class="special">;</span> <span class="comment">// Oh, now I see!</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span> <span class="identifier">session_id</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">time_t</span> <span class="identifier">valid_till</span><span class="special">;</span>
<span class="special">};</span>
</pre>
</td>
</tr></tbody>
</table>
</div>
<p>
Definition via aggregate initializable structure is much more clear. Same
story with usages: <code class="computeroutput"><span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">value</span><span class="special">);</span></code> vs. <code class="computeroutput"><span class="keyword">return</span>
<span class="identifier">value</span><span class="special">.</span><span class="identifier">session_id</span><span class="special">;</span></code>.
</p>
<p>
Another advantage of aggregates is a more efficient copy, move construction
and assignments.
</p>
<p>
Because of the above issues some guidelines recommend to <span class="bold"><strong>use
aggregates instead of tuples</strong></span>. However aggregates fail when it
comes to the functional like programming.
</p>
<p>
Boost.PFR library <span class="bold"><strong>provides tuple like methods for aggregate
initializable structures</strong></span>, making aggregates usable in contexts
where only tuples were useful.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_pfr.tutorial.accessing_structure_member_by_in"></a><a class="link" href="tutorial.html#boost_pfr.tutorial.accessing_structure_member_by_in" title="Accessing structure member by index">Accessing
structure member by index</a>
</h3></div></div></div>
<p>
The following example shows how to access structure fields by index using
<code class="computeroutput"><a class="link" href="../boost/pfr/get.html" title="Function get">boost::pfr::get</a></code>.
</p>
<p>
Let's define some structure:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">foo</span> <span class="special">{</span> <span class="comment">// defining structure</span>
<span class="keyword">int</span> <span class="identifier">some_integer</span><span class="special">;</span>
<span class="keyword">char</span> <span class="identifier">c</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
We can access fields of that structure by index:
</p>
<pre class="programlisting"><span class="identifier">foo</span> <span class="identifier">f</span> <span class="special">{</span><span class="number">777</span><span class="special">,</span> <span class="char">'!'</span><span class="special">};</span>
<span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">r1</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">);</span> <span class="comment">// accessing field with index 0, returns reference to `foo::some_integer`</span>
<span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">r2</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">);</span> <span class="comment">// accessing field with index 1, returns reference to `foo::c`</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_pfr.tutorial.custom_printing_of_aggregates"></a><a class="link" href="tutorial.html#boost_pfr.tutorial.custom_printing_of_aggregates" title="Custom printing of aggregates">Custom
printing of aggregates</a>
</h3></div></div></div>
<p>
The following example shows how to write your own io-manipulator for printing:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">ops</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">ostream</span><span class="special">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">my_ns</span> <span class="special">{</span>
<span class="comment">/// Usage:</span>
<span class="comment">/// struct foo {std::uint8_t a, b;};</span>
<span class="comment">/// ...</span>
<span class="comment">/// std::cout &lt;&lt; my_ns::my_io(foo{42, 22});</span>
<span class="comment">///</span>
<span class="comment">/// Output: 42, 22</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">my_io</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">namespace</span> <span class="identifier">detail</span> <span class="special">{</span>
<span class="comment">// Helpers to print individual values</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">print_each</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">v</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">out</span> <span class="special">&lt;&lt;</span> <span class="identifier">v</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">print_each</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">uint8_t</span> <span class="identifier">v</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">out</span> <span class="special">&lt;&lt;</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">);</span> <span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">print_each</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">int8_t</span> <span class="identifier">v</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">out</span> <span class="special">&lt;&lt;</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">);</span> <span class="special">}</span>
<span class="comment">// Structure to keep a reference to value, that will be ostreamed lower</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">io_reference</span> <span class="special">{</span>
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">;</span>
<span class="special">};</span>
<span class="comment">// Output each field of io_reference::value</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">io_reference</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">sep</span> <span class="special">=</span> <span class="string">""</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">for_each_field</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span><span class="special">,</span> <span class="special">[&amp;](</span><span class="keyword">const</span> <span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">v</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">out</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exchange</span><span class="special">(</span><span class="identifier">sep</span><span class="special">,</span> <span class="string">", "</span><span class="special">);</span>
<span class="identifier">detail</span><span class="special">::</span><span class="identifier">print_each</span><span class="special">(</span><span class="identifier">out</span><span class="special">,</span> <span class="identifier">v</span><span class="special">);</span>
<span class="special">});</span>
<span class="keyword">return</span> <span class="identifier">out</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="comment">// Definition:</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">my_io</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">io_reference</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;{</span><span class="identifier">value</span><span class="special">};</span>
<span class="special">}</span>
<span class="special">}</span> <span class="comment">// namespace my_ns</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_pfr.tutorial.three_ways_of_getting_operators"></a><a class="link" href="tutorial.html#boost_pfr.tutorial.three_ways_of_getting_operators" title="Three ways of getting operators">Three
ways of getting operators </a>
</h3></div></div></div>
<p>
There are three ways to start using Boost.PFR hashing, comparison and streaming
for type <code class="computeroutput"><span class="identifier">T</span></code> in your code.
Each method has its own drawbacks and suits own cases.
</p>
<div class="table">
<a name="boost_pfr.tutorial.three_ways_of_getting_operators.ops_comp"></a><p class="title"><b>Table 28.1. Different approaches for operators</b></p>
<div class="table-contents"><table class="table" summary="Different approaches for operators">
<colgroup>
<col>
<col>
<col>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Approach
</p>
</th>
<th>
<p>
When to use
</p>
</th>
<th>
<p>
Operators could be found by ADL
</p>
</th>
<th>
<p>
Works for local types
</p>
</th>
<th>
<p>
Usable locally, without affecting code from other scopes
</p>
</th>
<th>
<p>
Ignores implicit conversion operators
</p>
</th>
<th>
<p>
Respects user defined operators
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><a class="link" href="../reference_section.html#header.boost.pfr.ops_hpp" title="Header &lt;boost/pfr/ops.hpp&gt;">boost/pfr/ops.hpp: eq, ne,
gt, lt, le, ge</a></code>
</p>
<p>
<code class="computeroutput"><a class="link" href="../reference_section.html#header.boost.pfr.io_hpp" title="Header &lt;boost/pfr/io.hpp&gt;">boost/pfr/io.hpp: io</a></code>
</p>
</td>
<td>
<p>
Use when you need to compare values by provided for them operators
or via field-by-field comparison.
</p>
</td>
<td>
<p>
no
</p>
</td>
<td>
<p>
yes
</p>
</td>
<td>
<p>
yes
</p>
</td>
<td>
<p>
no
</p>
</td>
<td>
<p>
yes
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><a class="link" href="../BOOST_PFR_FUNCTIONS_FOR.html" title="Macro BOOST_PFR_FUNCTIONS_FOR">BOOST_PFR_FUNCTIONS_FOR(T)</a></code>
</p>
</td>
<td>
<p>
Use near the type definition to define the whole set of operators
for your type.
</p>
</td>
<td>
<p>
yes
</p>
</td>
<td>
<p>
no
</p>
</td>
<td>
<p>
no
</p>
</td>
<td>
<p>
yes for T
</p>
</td>
<td>
<p>
no (compile time error)
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><a class="link" href="../reference_section.html#header.boost.pfr.ops_fields_hpp" title="Header &lt;boost/pfr/ops_fields.hpp&gt;">boost/pfr/ops_fields.hpp:
eq_fields, ne_fields, gt_fields, lt_fields, le_fields, ge_fields</a></code>
</p>
<p>
<code class="computeroutput"><a class="link" href="../reference_section.html#header.boost.pfr.io_hpp" title="Header &lt;boost/pfr/io.hpp&gt;">boost/pfr/io_fields.hpp: io_fields</a></code>
</p>
</td>
<td>
<p>
Use to implement the required set of operators for your type.
</p>
</td>
<td>
<p>
no
</p>
</td>
<td>
<p>
yes
</p>
</td>
<td>
<p>
yes
</p>
</td>
<td>
<p>
yes
</p>
</td>
<td>
<p>
yes
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><p>
More detailed description follows:
</p>
<p>
<span class="bold"><strong>1. <code class="computeroutput"><span class="identifier">eq</span><span class="special">,</span> <span class="identifier">ne</span><span class="special">,</span>
<span class="identifier">gt</span><span class="special">,</span> <span class="identifier">lt</span><span class="special">,</span> <span class="identifier">le</span><span class="special">,</span> <span class="identifier">ge</span><span class="special">,</span>
<span class="identifier">io</span></code> approach</strong></span>
</p>
<p>
This method is good if you're writing generic algorithms and need to use
operators from Boost.PFR only if there are no operators defined for the type:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">ops</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">uniform_comparator_less</span> <span class="special">{</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">rhs</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span>
<span class="comment">// If T has operator&lt; or conversion operator then it is used.</span>
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">lt</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
This methods effects are local to the function. It works even for local types,
like structures defined in functions.
</p>
<p>
<span class="bold"><strong>2. BOOST_PFR_FUNCTIONS_FOR(T) approach</strong></span>
</p>
<p>
This method is good if you're writing a structure and wish to define operators
for that structure.
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">functions_for</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">pair_like</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">first</span><span class="special">;</span>
<span class="keyword">short</span> <span class="identifier">second</span><span class="special">;</span>
<span class="special">};</span>
<span class="identifier">BOOST_PFR_FUNCTIONS_FOR</span><span class="special">(</span><span class="identifier">pair_like</span><span class="special">)</span> <span class="comment">// Defines operators</span>
<span class="comment">// ...</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">pair_like</span><span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">}</span> <span class="special">&lt;</span> <span class="identifier">pair_like</span><span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">});</span>
</pre>
<p>
Argument Dependant Lookup works well. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span></code>
will find the operators for <code class="computeroutput"><span class="keyword">struct</span>
<span class="identifier">pair_like</span></code>. <code class="computeroutput"><a class="link" href="../BOOST_PFR_FUNCTIONS_FOR.html" title="Macro BOOST_PFR_FUNCTIONS_FOR">BOOST_PFR_FUNCTIONS_FOR(T)</a></code>
can not be used for local types. It does not respect conversion operators
of <code class="computeroutput"><span class="identifier">T</span></code>, so for example the
following code will output different values:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">functions_for</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">empty</span> <span class="special">{</span>
<span class="keyword">operator</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="string">"empty{}"</span><span class="special">;</span> <span class="special">}</span>
<span class="special">};</span>
<span class="comment">// Uncomment to get different output:</span>
<span class="comment">// BOOST_PFR_FUNCTIONS_FOR(empty)</span>
<span class="comment">// ...</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">empty</span><span class="special">{};</span> <span class="comment">// Outputs `empty{}` if BOOST_PFR_FUNCTIONS_FOR(empty) is commented out, '{}' otherwise.</span>
</pre>
<p>
<span class="bold"><strong>3. <code class="computeroutput"><span class="identifier">eq_fields</span><span class="special">,</span> <span class="identifier">ne_fields</span><span class="special">,</span> <span class="identifier">gt_fields</span><span class="special">,</span> <span class="identifier">lt_fields</span><span class="special">,</span> <span class="identifier">le_fields</span><span class="special">,</span> <span class="identifier">ge_fields</span><span class="special">,</span> <span class="identifier">io_fields</span></code>
approach</strong></span>
</p>
<p>
This method is good if you're willing to provide only some operators for
your type:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">io_fields</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">pair_like</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">first</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">second</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">inline</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">pair_like</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">bost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">io_fields</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
All the <code class="computeroutput"><span class="special">*</span><span class="identifier">_fields</span></code>
functions do ignore user defined operators and work only with fields of a
type. This makes them perfect for defining you own operators.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_pfr.tutorial.reflection_of_unions"></a><a class="link" href="tutorial.html#boost_pfr.tutorial.reflection_of_unions" title="Reflection of unions">Reflection of
unions </a>
</h3></div></div></div>
<p>
You could use tuple-like representation if a type contains union. But be
sure that operations for union are manually defined:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">pfr</span><span class="special">/</span><span class="identifier">ops</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">union</span> <span class="identifier">test_union</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
<span class="keyword">float</span> <span class="identifier">f</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">test_union</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">test_union</span> <span class="identifier">r</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span> <span class="comment">// Compile time error without this operator</span>
<span class="keyword">bool</span> <span class="identifier">some_function</span><span class="special">(</span><span class="identifier">test_union</span> <span class="identifier">f1</span><span class="special">,</span> <span class="identifier">test_union</span> <span class="identifier">f2</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">pfr</span><span class="special">::</span><span class="identifier">eq</span><span class="special">(</span><span class="identifier">f1</span><span class="special">,</span> <span class="identifier">f2</span><span class="special">);</span> <span class="comment">// OK</span>
<span class="special">}</span>
</pre>
<p>
Reflection of unions is disabled in the Boost.PFR library for safety reasons.
Alas, there's no way to find out <span class="bold"><strong>active</strong></span>
member of a union and accessing an inactive member is an Undefined Behavior.
For example, library could always return the first member, but ostreaming
<code class="computeroutput"><span class="identifier">u</span></code> in <code class="computeroutput"><span class="keyword">union</span>
<span class="special">{</span><span class="keyword">char</span><span class="special">*</span> <span class="identifier">c</span><span class="special">;</span>
<span class="keyword">long</span> <span class="keyword">long</span>
<span class="identifier">ll</span><span class="special">;</span> <span class="special">}</span> <span class="identifier">u</span><span class="special">;</span>
<span class="identifier">u</span><span class="special">.</span><span class="identifier">ll</span><span class="special">=</span> <span class="number">1</span><span class="special">;</span></code> will crash your program with an invalid
pointer dereference.
</p>
<p>
Any attempt to reflect unions leads to a compile time error. In many cases
a static assert is triggered that outputs the following message:
</p>
<pre class="programlisting"><span class="identifier">error</span><span class="special">:</span> <span class="keyword">static_assert</span> <span class="identifier">failed</span> <span class="string">"====================&gt; Boost.PFR: For safety reasons it is forbidden
to reflect unions. See `Reflection of unions` section in the docs for more info."</span>
</pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2016-2021 Antony Polukhin<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="short_examples_for_the_impatient.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_pfr.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="limitations_and_configuration.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>