[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

@@ -62,6 +62,7 @@ Index types
</ul>
</li>
<li><a href="#projection">Projection of iterators</a></li>
<li><a href="#node_handling">Node handling operations</a></li>
<li><a href="#complexity">Complexity and exception safety</a></li>
</ul>
@@ -505,11 +506,9 @@ Currently, Boost.MultiIndex provides the following index types:
<code>std::list</code>: they arrange the elements as if in a bidirectional
list.</li>
<li>Hashed indices provide fast access to the elements through hashing
techniques, in a similar way as non-standard <code>hash_set</code>s provided
by some vendors. Recently, <i>unordered associative containers</i> have been
proposed as part of an extension of the C++ standard library known
in the standardization commitee as TR1. Hashed indices closely model this
proposal.</li>
techniques, in a similar way as unordered associative containers
<code>std::unordered_set</code> (if duplicates are not allowed) and
<code>std::unordered_multiset</code> (if they are).</li>
<li>Random access indices provide an interface similar to that of
sequenced indices, and additionally feature random access iterators
and positional access to the elements.</li>
@@ -1218,6 +1217,72 @@ When provided, <code>project</code> can also be used with
<a href="#tagging">tags</a>.
</p>
<h2><a name="node_handling">Node handling operations</a></h2>
<p>
Using direct node manipulation, elements can be passed between
<code>multi_index_container</code>s without actually copying them:
</p>
<blockquote><pre>
<span class=comment>// move an employee to the retiree archive</span>
<span class=keyword>void</span> <span class=identifier>move_to_retirement</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>ssnumber</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>es</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>archive</span><span class=special>)</span>
<span class=special>{</span>
<span class=comment>// extract the employee with given SS number to a node handle</span>
<span class=identifier>employee_set_by_ssn</span><span class=special>::</span><span class=identifier>node_type</span> <span class=identifier>node</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special>&lt;</span><span class=identifier>ssn</span><span class=special>&gt;().</span><span class=identifier>extract</span><span class=special>(</span><span class=identifier>ssnumber</span><span class=special>);</span>
<span class=keyword>if</span><span class=special>(!</span><span class=identifier>node</span><span class=special>.</span><span class=identifier>empty</span><span class=special>()){</span> <span class=comment>// employee found
// re-insert into archive (note the use of std::move)</span>
<span class=identifier>archive</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>move</span><span class=special>(</span><span class=identifier>node</span><span class=special>));</span>
<span class=special>}</span>
<span class=special>}</span>
</pre></blockquote>
<p>
In the example, the internal node is transferred as-is from <code>es</code> to <code>archive</code>,
which is more efficient than erasing from the source and recreating in destination.
<code>node_type</code> is a move-only class used to pass nodes around, and its interface follows
that of the <a href="https://en.cppreference.com/w/cpp/container/node_handle">homonym type</a>
for C++ associative containers (set containers version). Boost.MultiIndex provides node extraction
and insertion operations for all index types, including sequenced ones (by contrast,
<code>std::list</code> does not have such features):
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>src</span><span class=special>;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>dst</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// transfer even numbers from src to dst</span>
<span class=keyword>for</span><span class=special>(</span><span class=keyword>auto</span> <span class=identifier>first</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>last</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>;){</span>
<span class=keyword>if</span><span class=special>(*</span><span class=identifier>first</span><span class=special>%</span><span class=number>2</span><span class=special>==</span><span class=number>0</span><span class=special>)</span> <span class=identifier>dst</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>dst</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>extract</span><span class=special>(</span><span class=identifier>first</span><span class=special>++));</span>
<span class=keyword>else</span> <span class=special>++</span><span class=identifier>first</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
Note that <code>src</code> and <code>dst</code> are of different types,
yet transfer is possible. Two <code>multi_index_container</code>s are
node-compatible (that is, they use the same <code>node_type</code>) if
they have the same element and allocator types and their respective indices match
one by one without regard to whether they are unique or non-unique or to
their particular configuration parameters: they are both ordered, or
both sequenced, etc.
</p>
<h2><a name="complexity">Complexity and exception safety</a></h2>
<p>
@@ -1252,9 +1317,9 @@ Index types
<br>
<p>Revised November 24th 2015</p>
<p>Revised May 9th 2020</p>
<p>&copy; Copyright 2003-2015 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2020 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -125,7 +125,8 @@ is one value of the <code>safe_mode::error_code</code> enumeration:
<span class=identifier>invalid_range</span><span class=special>,</span> <span class=comment>// last not reachable from first</span>
<span class=identifier>inside_range</span><span class=special>,</span> <span class=comment>// iterator lies within a range (and it mustn't)</span>
<span class=identifier>out_of_bounds</span><span class=special>,</span> <span class=comment>// move attempted beyond container limits</span>
<span class=identifier>same_container</span> <span class=comment>// containers ought to be different</span>
<span class=identifier>same_container</span><span class=special>,</span> <span class=comment>// containers ought to be different</span>
<span class=identifier>unequal_allocators</span> <span class=comment>// allocators ought to be equal</span>
<span class=special>};</span>
<span class=special>}</span> <span class=comment>// namespace multi_index::safe_mode</span>
@@ -239,9 +240,9 @@ Techniques
<br>
<p>Revised July 07th 2017</p>
<p>Revised May 9th 2020</p>
<p>&copy; Copyright 2003-2017 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2020 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -61,7 +61,7 @@ Key extraction
<h2><a name="classification">Classification</a></h2>
<p>
Boost.MultiIndex provides six different index types, which can be classified as
Boost.MultiIndex provides eight different index types, which can be classified as
shown in the table below. <a href="basics.html#ord_indices">Ordered</a> and
<a href="basics.html#seq_indices">sequenced</a> indices,
which are the most commonly used, have been explained in the basics section;
@@ -821,9 +821,9 @@ Key extraction
<br>
<p>Revised August 29th 2017</p>
<p>Revised August 6th 2018</p>
<p>&copy; Copyright 2003-2017 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2018 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -39,8 +39,11 @@ Container creation
<ul>
<li><a href="#identity"><code>identity</code></a></li>
<li><a href="#member"><code>member</code></a></li>
<li><a href="#const_mem_fun"><code>const_mem_fun</code>
and <code>mem_fun</code></a></li>
<li><a href="#const_mem_fun"><code>const_mem_fun</code> and <code>mem_fun</code></a>
<ul>
<li><a href="#x_mem_fun">Variants for other types of member functions</a></li>
</ul>
</li>
<li><a href="#global_fun"><code>global_fun</code></a></li>
</ul>
</li>
@@ -50,6 +53,7 @@ Container creation
<li><a href="#composite_keys_hash">Composite keys and hashed indices</a></li>
</ul>
</li>
<li><a href="#key">C++17 terse key specification syntax</a></li>
<li><a href="#advanced_key_extractors">Advanced features of Boost.MultiIndex key
extractors</a></li>
</ul>
@@ -94,10 +98,10 @@ of the element and do not depend on external data.
A key extractor is called <i>read/write</i> if it returns a non-constant reference
to the key when passed a non-constant element, and it is called <i>read-only</i>
otherwise. Boost.MultiIndex requires that the key extractor be read/write
when using the <code>modify_key</code> member function of ordered and hashed
when using the <code>modify_key</code> member function of key-based
indices. In all other situations, read-only extractors suffice.
The section on <a href="#advanced_key_extractors">advanced features
of Boost.MultiIndex key extractors</a> details which of the predefined
of Boost.MultiIndex key extractors</a> shows typical situations on which the predefined
key extractors are read/write.
</p>
@@ -245,10 +249,97 @@ of Boost.MultiIndex key extractors</a>.
provides a complete program showing how to use <code>const_mem_fun</code>.
<p>
<h4><a name="x_mem_fun">Variants for other types of member functions</a></h4>
<p>
Consider the following, non-compiling code:
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>employee</span>
<span class=special>{</span>
<span class=special>...</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>salary</span><span class=special>()</span><span class=keyword>const</span><span class=special><b>&amp;</b>;</span> <span class=comment>// note the &amp;</span>
<span class=special>};</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=special>...</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=comment>// compiler error: can't convert &amp;employee::salary to
// std::size_t (employee::*)() const</span>
<span class=identifier><b>const_mem_fun</b></span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>salary</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
<p>
The problem here is that the type of <code>&amp;employee::salary</code>, which is
<a href="https://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions">ref-qualified</a>,
does not match exactly what <code>const_mem_fun</code> expects. Fortunately, Boost.MultiIndex
provides a variant to fit:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=special>...</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=identifier><b>cref_mem_fun</b></span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>salary</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
<p>
This is the list of all available variants of <code>const_mem_fun</code> and
<code>mem_fun</code>:
</p>
<p align="center">
<table cellspacing="0">
<caption><b>Variants of <code>const_mem_fun</code> and <code>mem_fun</code>.</b></caption>
<tr>
<th>&nbsp;Member function example&nbsp;</th>
<th>Suitable extractor</th>
<th>Behaves as</th>
</tr>
<tr>
<td><code>int f()const volatile</code></td>
<td><a href="../reference/key_extraction.html#cv_mem_fun"><code>cv_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
<td align="center" rowspan="3">&nbsp;<code>const_mem_fun</code>&nbsp;</td>
</tr>
<tr>
<td><code>int f()const&amp;</code></td>
<td><a href="../reference/key_extraction.html#cv_mem_fun"><code>cref_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
</tr>
<tr>
<td><code>int f()const volatile&amp;</code></td>
<td><a href="../reference/key_extraction.html#cv_mem_fun"><code>cvref_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
</tr>
<tr>
<td><code>int f()volatile</code></td>
<td><a href="../reference/key_extraction.html#volatile_mem_fun"><code>volatile_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
<td align="center" rowspan="3"><code>mem_fun</code></td>
</tr>
<tr>
<td><code>int f()&amp;</code></td>
<td><a href="../reference/key_extraction.html#volatile_mem_fun"><code>ref_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
</tr>
<tr>
<td><code>int f()volatile&amp;</code></td>
<td><a href="../reference/key_extraction.html#volatile_mem_fun"><code>vref_mem_fun</code></a><code>&lt;int,X,&amp;X::f&gt;</code></td>
</tr>
</table>
</p>
<h3><a name="global_fun"><code>global_fun</code></a></h3>
<p>
Whereas <code>const_mem_fun</code> and <code>mem_fun</code> are based on a
Whereas <code>const_mem_fun</code> and its variants are based on a
given member function of the base type from where the key is extracted,
<a href="../reference/key_extraction.html#global_fun"><code>global_fun</code></a>
takes a global function (or static member function) accepting the base
@@ -387,7 +478,7 @@ The analogous concept in Boost.MultiIndex is modeled by means of
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=comment>//non-unique as some subscribers might have more than one number</span>
<span class=comment>// non-unique as some subscribers might have more than one number</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=identifier>composite_key</span><span class=special>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
@@ -596,6 +687,86 @@ key depends on all of its elements, it is impossible to calculate it from
partial information.
</p>
<h2><a name="key">C++17 terse key specification syntax</a></h2>
<p>
C++17 introduces the declaration of <code>auto</code> template parameters, which can be
taken advantage of to eliminate some redundancy in the specification of Boost.MultiIndex
predefined key extractors. For instance, instead of the classical:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=identifier>const_mem_fun</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name_length</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
one can now write:
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>key</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=special>...</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier><b>key</b></span><span class=special><b>&lt;&amp;</b></span><span class=identifier><b>employee</b></span><span class=special><b>::</b></span><span class=identifier><b>name</b></span><span class=special><b>&gt;</b>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier><b>key</b></span><span class=special><b>&lt;&amp;</b></span><span class=identifier><b>employee</b></span><span class=special><b>::</b></span><span class=identifier><b>name_length</b></span><span class=special><b>&gt;</b>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
<p>
which results in the exact same defined type, as
<a href="../reference/key_extraction.html#key"><code>key</code></a> constructs are mere
aliases for the old syntax. <code>key</code> can be used to shorten the specification of
<a href="../reference/key_extraction.html#member"><code>member</code></a>,
<a href="../reference/key_extraction.html#const_mem_fun"><code>const_mem_fun</code></a>
(and <a href="../reference/key_extraction.html#cv_mem_fun">variants</a>),
<a href="../reference/key_extraction.html#mem_fun"><code>mem_fun</code></a>
(and <a href="../reference/key_extraction.html#volatile_mem_fun">variants</a>),
<a href="../reference/key_extraction.html#global_fun"><code>global_fun</code></a>
and, with additional terseness benefits,
<a href="../reference/key_extraction.html#composite_key"><code>composite_key</code></a>:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=comment>// composite key on family name and given name</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;
</span><span class=identifier><b>key</b></span><span class=special><b>&lt;&amp;</b></span><span class=identifier><b>phonebook_entry</b></span><span class=special><b>::</b></span><span class=identifier><b>family_name</b></span><span class=special><b>,&amp;</b></span><span class=identifier><b>phonebook_entry</b></span><span class=special><b>::</b></span><span class=identifier><b>given_name</b></span><span class=special><b>&gt;</b></span>
<span class=special>&gt;,</span>
<span class=comment>// unique index on phone number</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>key</span><span class=special>&lt;&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>phone_number</span><span class=special>&gt;&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>phonebook</span><span class=special>;</span>
</pre></blockquote>
In this example, the first usage of <code>key</code> substitutes for the
decidedly more cumbersome:
<blockquote><pre>
<span class=identifier>composite_key</span><span class=special>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
<span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>phonebook_entry</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>family_name</span><span class=special>&gt;,</span>
<span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>phonebook_entry</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>given_name</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
</pre></blockquote>
Note that we did not even have to specify the first <code>phonebook_entry</code>
argument: the internal machinery of <code>key</code> automatically deduces it for
us. Check the <a href="../reference/key_extraction.html#key_synopsis">reference</a>
for technical details.
<h2><a name="advanced_key_extractors">Advanced features of Boost.MultiIndex key
extractors</a></h2>
@@ -955,9 +1126,9 @@ Container creation
<br>
<p>Revised March 25th 2015</p>
<p>Revised April 19th 2020</p>
<p>&copy; Copyright 2003-2015 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2020 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">