added ranked indices, plus some doc stylistic updates

This commit is contained in:
joaquintides 2015-04-19 21:10:31 +02:00
parent 07977932ea
commit d0a7194db7
25 changed files with 3478 additions and 1645 deletions

View File

@ -37,26 +37,12 @@ principle driving the current internal design of <code>multi_index_container</co
<h2>Contents</h2>
<ul>
<li><a href="#ranked_indices">Ranked indices</a></li>
<li><a href="#notifying">Notifying indices</a></li>
<li><a href="#constraints">Constraints</a></li>
<li><a href="#user_defined_indices">User-defined indices</a></li>
<li><a href="#indexed_maps">Indexed maps</a></li>
</ul>
<h2><a name="ranked_indices">Ranked indices</a></h2>
<p>
Ordered indices are implemented using red-black trees; these trees
can be augmented with additional information to obtain a type
of data structure called
<a href="http://pine.cs.yale.edu/pinewiki/OrderStatisticsTree"><i>order-statistics
trees</i></a>, allowing for logarithmic search of the <i>n</i>-th element. It
has been proposed that order-statistics trees be used to devise a new type of
<i>ranked indices</i> that support <code>operator[]</code> while retaining
the functionality of ordered indices.
</p>
<h2><a name="notifying">Notifying indices</a></h2>
<p>
@ -200,9 +186,9 @@ Release notes
<br>
<p>Revised July 6th 2013</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 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

@ -31,12 +31,13 @@ borrowed from relational database terminology and allows for the specification o
complex data structures in the spirit of multiply indexed relational tables where
simple sets and maps are not enough. A wide selection of indices is provided,
modeled after analogous STL containers like <code>std::set</code>,
<code>std::list</code> and hashed sets.
<code>std::list</code> and <code>std::unordered_set</code>.
</p>
<p>
Boost.MultiIndex features additional functionalities, like subobject searching,
range querying and in-place updating of elements, which make it a convenient replacement
range querying, in-place updating of elements and calculation of ranks,
which make it a convenient replacement
for <code>std::set</code> and <code>set::multiset</code> even when no multi-indexing
capabilities are needed.
</p>
@ -85,9 +86,9 @@ Tutorial
<br>
<p>Revised November 30th 2013</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 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

@ -15,8 +15,8 @@
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Hashed indices reference</h1>
<div class="prev_link"><a href="ord_indices.html"><img src="../prev.gif" alt="ordered indices" border="0"><br>
Ordered indices
<div class="prev_link"><a href="rnk_indices.html"><img src="../prev.gif" alt="ranked indices" border="0"><br>
Ranked indices
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
@ -1117,8 +1117,8 @@ and the restored <code>it'</code> a <code>local_iterator</code>, or viceversa.
<hr>
<div class="prev_link"><a href="ord_indices.html"><img src="../prev.gif" alt="ordered indices" border="0"><br>
Ordered indices
<div class="prev_link"><a href="rnk_indices.html"><img src="../prev.gif" alt="ranked indices" border="0"><br>
Ranked indices
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
@ -1129,9 +1129,9 @@ Sequenced indices
<br>
<p>Revised August 20th 2014</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 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

@ -34,6 +34,7 @@ Index
<li><a href="multi_index_container.html">Class template <code>multi_index_container</code></a></li>
<li><a href="indices.html">Index reference</a></li>
<li><a href="ord_indices.html">Ordered indices</a></li>
<li><a href="rnk_indices.html">Ranked indices</a></li>
<li><a href="hash_indices.html">Hashed indices</a></li>
<li><a href="seq_indices.html">Sequenced indices</a></li>
<li><a href="rnd_indices.html">Random access indices</a></li>
@ -59,6 +60,13 @@ The following dependencies among headers of Boost.MultiIndex hold:
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
</ul>
</li>
<li><a href="rnk_indices.html#synopsis">
<code>"boost/multi_index/ranked_index.hpp"</code></a> includes
<ul>
<li><a href="indices.html#tag_synopsis">
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
</ul>
</li>
<li><a href="hash_indices.html#synopsis">
<code>"boost/multi_index/hashed_index.hpp"</code></a> includes
<ul>
@ -127,9 +135,9 @@ Index
<br>
<p>Revised June 19th 2007</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 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

@ -189,11 +189,14 @@ index specifiers
<li><a href="ord_indices.html#unique_non_unique"><code>ordered_unique</code> and
<code>ordered_non_unique</code></a> for
<a href="ord_indices.html">ordered indices</a>,</li>
<li><a href="rnk_indices.html#unique_non_unique"><code>ranked_unique</code> and
<code>ranked_non_unique</code></a> for
<a href="rnk_indices.html">ranked indices</a>,</li>
<li><a href="hash_indices.html#unique_non_unique"><code>hashed_unique</code> and
<code>hashed_non_unique</code></a> for
<a href="hash_indices.html">hashed indices</a>,</li>
<li><a href="seq_indices.html#sequenced"><code>sequenced</code></a> for
<a href="seq_indices.html">sequenced indices</a></li>
<a href="seq_indices.html">sequenced indices</a>,</li>
<li>and <a href="rnd_indices.html#random_access"><code>random_access</code></a> for
<a href="rnd_indices.html">random access indices</a>.</li>
</ul>
@ -310,6 +313,10 @@ reference</a>.
<ul>
<li><a href="ord_indices.html">Ordered indices</a> sort the elements
on the key and provide fast lookup capabilites.</li>
<li><a href="rnk_indices.html">Ranked indices</a> are a variation of
ordered indices providing extra operations based on
<i>rank</i>, the numerical position of an element
in the sequence.</li>
<li><a href="hash_indices.html">Hashed indices</a> offer high
efficiency access through hashing techniques.</li>
</ul>
@ -379,9 +386,9 @@ Ordered indices
<br>
<p>Revised July 7th 2013</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 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

@ -21,8 +21,8 @@ Index reference
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
</a></div>
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
Hashed indices
<div class="next_link"><a href="rnk_indices.html"><img src="../next.gif" alt="ranked indices" border="0"><br>
Ranked indices
</a></div><br clear="all" style="clear: all;">
<hr>
@ -1097,15 +1097,15 @@ Index reference
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
</a></div>
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
Hashed indices
<div class="next_link"><a href="rnk_indices.html"><img src="../next.gif" alt="ranked indices" border="0"><br>
Ranked indices
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised August 20th 2014</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 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

@ -0,0 +1,626 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.MultiIndex Documentation - Ranked indices reference</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<link rel="start" href="../index.html">
<link rel="prev" href="indices.html">
<link rel="up" href="index.html">
<link rel="next" href="hash_indices.html">
</head>
<body>
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Ranked indices reference</h1>
<div class="prev_link"><a href="ord_indices.html"><img src="../prev.gif" alt="ordered_indices" border="0"><br>
Ordered indices
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
</a></div>
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
Hashed indices
</a></div><br clear="all" style="clear: all;">
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#rnk_index_fwd_synopsis">Header
<code>"boost/multi_index/ranked_index_fwd.hpp"</code> synopsis</a></li>
<li><a href="#synopsis">Header
<code>"boost/multi_index/ranked_index.hpp"</code> synopsis</a>
<ul>
<li><a href="#unique_non_unique">
Index specifiers <code>ranked_unique</code> and <code>ranked_non_unique</code>
</a></li>
<li><a href="#rnk_indices">Ranked indices</a>
<ul>
<li><a href="#complexity_signature">Complexity signature</a></li>
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#rank_operations">Rank operations</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>
<a name="rnk_index_fwd_synopsis">Header
<a href="../../../../boost/multi_index/ranked_index_fwd.hpp">
<code>"boost/multi_index/ranked_index_fwd.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=comment>// index specifiers ranked_unique and ranked_non_unique</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>consult ranked_unique reference for arguments</b><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>ranked_unique</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>consult ranked_non_unique reference for arguments</b><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>ranked_non_unique</span><span class=special>;</span>
<span class=comment>// indices</span>
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>implementation defined</b><span class=special>&gt;</span> <span class=keyword>class</span> <b>index name is implementation defined</b><span class=special>;</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
<span class=special>}</span> <span class=comment>// namespace boost</span>
</pre></blockquote>
<p>
<code>ranked_index_fwd.hpp</code> provides forward declarations for index specifiers
<a href="#unique_non_unique"><code>ranked_unique</code> and <code>ranked_non_unique</code></a> and
their associated <a href="#rnk_indices">ranked index</a> classes.
</p>
<h2>
<a name="synopsis">Header
<a href="../../../../boost/multi_index/ranked_index.hpp">
<code>"boost/multi_index/ranked_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=comment>// index specifiers ranked_unique and ranked_non_unique</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>consult ranked_unique reference for arguments</b><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>ranked_unique</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>consult ranked_non_unique reference for arguments</b><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>ranked_non_unique</span><span class=special>;</span>
<span class=comment>// indices</span>
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>implementation defined</b><span class=special>&gt;</span> <span class=keyword>class</span> <b>index class name implementation defined</b><span class=special>;</span>
<span class=comment>// index comparison:</span>
<span class=comment>// <b>OP</b> is any of ==,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=comment>// index specialized algorithms:</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>implementation defined</b><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
<span class=special>}</span> <span class=comment>// namespace boost</span>
</pre></blockquote>
<h3><a name="unique_non_unique">
Index specifiers <code>ranked_unique</code> and <code>ranked_non_unique</code>
</a></h3>
<p>
These <a href="indices.html#index_specification">index specifiers</a> allow
for insertion of <a href="#rnk_indices">ranked indices</a> without and with
allowance of duplicate elements, respectively. The syntax of <code>ranked_unique</code>
and <code>ranked_non_unique</code> coincide, thus we describe them in a grouped manner.
<code>ranked_unique</code> and <code>ranked_non_unique</code> can be instantiated in
two different forms, according to whether a tag list for the index is provided or not:
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>TagList</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)</span><span class=special>;</span>
</pre></blockquote>
<p>
If provided, <code>TagList</code> must be an instantiation of the class template
<a href="indices.html#tag"><code>tag</code></a>.
The template arguments are used by the corresponding index implementation,
refer to the <a href="#rnk_indices">ranked indices</a> reference section for further
explanations on their acceptable type values.
</p>
<h3><a name="rnk_indices">Ranked indices</a></h3>
<p>
Ranked indices are a variation of <a href="ord_indices.html">ordered indices</a>
providing additional capabilities for calculation of and access by rank; the <i>rank</i> of an element is the
distance to it from the beginning of the index. Other than this, ranked indices present
the same public interface and complexity guarantees than ordered indices, although
execution times and memory consumption are expected to be poorer due to the internal
bookkeeping needed to maintain rank-related information.
As with ordered indices, ranked indices can be unique (no duplicate elements are allowed)
or non-unique: either version is associated to a different index specifier, but
the interface of both is the same.
</p>
<p>
Being then these a pure extension of ordered indices, we only provide descriptions for
the extra operations they provide.
</p>
<blockquote><pre>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=comment>// see range_rank()</span>
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>implementation defined: dependent on types Value, Allocator,
TagList, KeyFromValue, Compare</b><span class=special>&gt;</span>
<span class=keyword>class</span> <b>name is implementation defined</b>
<span class=special>{</span>
<span class=keyword>public</span><span class=special>:</span>
<span class=comment>// types:</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span> <span class=identifier>key_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>KeyFromValue</span> <span class=identifier>key_from_value</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Compare</span> <span class=identifier>key_compare</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>value_compare</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>&gt;</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>const_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>size_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>difference_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>pointer</span> <span class=identifier>pointer</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_pointer</span> <span class=identifier>const_pointer</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>equivalent to
std::reverse_iterator&lt;iterator&gt;</b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
<span class=keyword>typedef</span> <b>equivalent to
std::reverse_iterator&lt;const_iterator&gt;</b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
<span class=comment>// construct/copy/destroy:</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// iterators:</span>
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span> <span class=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// modifiers:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>emplace_hint</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>size_type</span> <span class=identifier>erase</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
<span class=comment>// observers:</span>
<span class=identifier>key_from_value</span> <span class=identifier>key_extractor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>key_compare</span> <span class=identifier>key_comp</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>value_compare</span> <span class=identifier>value_comp</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// set operations:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>find</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>find</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>lower_bound</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>lower_bound</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>upper_bound</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>upper_bound</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt;</span> <span class=identifier>equal_range</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt;</span> <span class=identifier>equal_range</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// range:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>LowerBounder</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>UpperBounder</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt;</span> <span class=identifier>range</span><span class=special>(</span>
<span class=identifier>LowerBounder</span> <span class=identifier>lower</span><span class=special>,</span><span class=identifier>UpperBounder</span> <span class=identifier>upper</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// rank operations:</span>
<span class=identifier>iterator</span> <span class=identifier>nth</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>size_type</span> <span class=identifier>rank</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>find_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>find_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>lower_bound_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>lower_bound_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>upper_bound_rank</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>size_type</span> <span class=identifier>upper_bound_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>&gt;</span> <span class=identifier>equal_range_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>&gt;</span> <span class=identifier>equal_range_rank</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&amp;</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>LowerBounder</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>UpperBounder</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>size_type</span><span class=special>,</span><span class=identifier>size_type</span><span class=special>&gt;</span>
<span class=identifier>range_rank</span><span class=special>(</span><span class=identifier>LowerBounder</span> <span class=identifier>lower</span><span class=special>,</span><span class=identifier>UpperBounder</span> <span class=identifier>upper</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
<span class=comment>// index comparison:</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>==(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>size</span><span class=special>()==</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>size</span><span class=special>()&amp;&amp;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>equal</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>begin</span><span class=special>());</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&lt;(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>lexicographical_compare</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>!=(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</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>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&gt;(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>y</span><span class=special>&lt;</span><span class=identifier>x</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&gt;=(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special>&lt;</span><span class=identifier>y</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>&lt;=(</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 1</b><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <b>index class name</b><span class=special>&lt;</span><b>arg set 2</b><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special>&gt;</span><span class=identifier>y</span><span class=special>);</span>
<span class=special>}</span>
<span class=comment>// index specialized algorithms:</span>
<span class=keyword>template</span><span class=special>&lt;</span><b>implementation defined</b><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>y</span><span class=special>);</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
<span class=special>}</span> <span class=comment>// namespace boost</span>
</pre></blockquote>
<h4><a name="complexity_signature">Complexity signature</a></h4>
<p>
The same as <a href="ord_indices.html#complexity_signature">ordered indices</a>.
</p>
<h4><a name="instantiation_types">Instantiation types</a></h4>
<p>Ordered indices are instantiated internally to <code>multi_index_container</code> and
specified by means of <a href="indices.html#indexed_by"><code>indexed_by</code></a>
with <a href="#unique_non_unique"> index specifiers <code>ranked_unique</code>
and <code>ranked_non_unique</code></a>. Instantiations are dependent on the
following types:
<ul>
<li><code>Value</code> from <code>multi_index_container</code>,</li>
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag&lt;&gt;</code> is assumed),</li>
<li><code>KeyFromValue</code> from the index specifier,</li>
<li><code>Compare</code> from the index specifier.</li>
</ul>
These types are subject to the same requirements as specified for
<a href="ord_indices.html#instantiation_types">ordered indices</a>.
</p>
<h4><a name="rank_operations">Rank operations</a></h4>
<p>
The <i>rank</i> of an iterator <code>it</code> of a given container <code>c</code> (and,
by extension, of the element it points to if the iterator is dereferenceable)
is <code>std::distance(c.begin(),it)</code>.
</p>
<p>
See the documentation of ordered indices for an explanation of the notions of
<a href="ord_indices.html#set_operations"><i>compatible extension</i>,
<i>compatible key</i></a>,
<a href="ord_indices.html#range_operations"><i>lower bounder</i> and <i>upper bounder</i></a>, which are
referred to above.
</p>
<code>iterator nth(size_type n)const;</code>
<blockquote>
<b>Effects:</b> Returns an iterator with rank <code>n</code>,
or <code>end()</code> if <code>n&gt;=size()</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>size_type rank(iterator position)const;
</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Returns the rank of <code>position</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey> size_type find_rank(const CompatibleKey&amp; x)const;
</code>
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(find(k))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
size_type find_rank(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(find(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
size_type lower_bound_rank(const CompatibleKey&amp; x)const;
</code>
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(lower_bound(x))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
size_type lower_bound_rank(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(lower_bound(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
size_type upper_bound_rank(const CompatibleKey&amp; x)const;
</code>
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(upper_bound(x))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
size_type upper_bound_rank(const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>rank(upper_bound(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey><br>
std::pair&lt;size_type,size_type> equal_range_rank(<br>
&nbsp;&nbsp;const CompatibleKey&amp; x)const;
</code>
<blockquote>
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
<code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to <code>make_pair(lower_bound_rank(x),upper_bound_rank(x))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename CompatibleKey,typename CompatibleCompare><br>
std::pair&lt;size_type,size_type> equal_range_rank(<br>
&nbsp;&nbsp;const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.<br>
<b>Effects:</b> Equivalent to
<code>make_pair(lower_bound_rank(x,comp),upper_bound_rank(x,comp))</code>.<br>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
</blockquote>
<code>template&lt;typename LowerBounder,typename UpperBounder><br>
std::pair&lt;size_type,size_type> range_rank(<br>
&nbsp;&nbsp;LowerBounder lower,UpperBounder upper)const;
</code>
<blockquote>
<b>Requires:</b> <code>LowerBounder</code> and <code>UpperBounder</code> are
a lower and upper bounder of <code>key_compare</code>, respectively.<br>
<b>Effects:</b> Equivalent to
<blockquote><pre>
<span class=keyword>auto</span> <span class=identifier>p</span><span class=special>=</span><span class=identifier>range</span><span class=special>(</span><span class=identifier>lower</span><span class=special>,</span><span class=identifier>upper</span><span class=special>);</span>
<span class=keyword>return</span> <span class=identifier>make_pair</span><span class=special>(</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>first</span><span class=special>),</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>second</span><span class=special>));</span>
</pre></blockquote>
<b>Complexity:</b> <code>O(log(n))</code>.<br>
<b>Variants:</b> In place of <code>lower</code> or <code>upper</code> (or both),
the singular value <code>boost::multi_index::unbounded</code> can be
provided. This acts as a predicate which all values of type <code>key_type</code>
satisfy.<br>
</blockquote>
<h4><a name="serialization">Serialization</a></h4>
<p>
The prerequisites and postconditions associated to serialization of
<code>multi_index_container</code>s with ranked indices are exactly the same
as those of <a href="ord_indices.html#serialization">ordered indices</a>.
<hr>
<div class="prev_link"><a href="ord_indices.html"><img src="../prev.gif" alt="ordered_indices" border="0"><br>
Ordered indices
</a></div>
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
Boost.MultiIndex reference
</a></div>
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
Hashed indices
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2015 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">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>

View File

@ -56,6 +56,7 @@ Acknowledgements
<p>
<ul>
<li>Added <a href="tutorial/indices.html#rnk_indices">ranked indices</a>.</li>
<li>Maintenance fixes.</li>
</ul>
</p>
@ -500,7 +501,7 @@ Acknowledgements
<br>
<p>Revised March 25th 2015</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2015 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software

View File

@ -107,28 +107,32 @@ with some of the least common features offered by Boost.MultiIndex.
<td>Exercises the <code>range</code> facility (ordered indices only).</td>
</tr>
<tr class="odd_tr">
<td><a href="../test/test_rank_ops.cpp"><code>test_rank_ops.cpp</code></a></td>
<td>Specific operations of ranked indices.</td>
</tr>
<tr>
<td><a href="../test/test_rearrange.cpp"><code>test_rearrange.cpp</code></a></td>
<td>Rearrange functions of sequenced and random access indices.</td>
</tr>
<tr>
<tr class="odd_tr">
<td><a href="../test/test_safe_mode.cpp"><code>test_safe_mode.cpp</code></a></td>
<td>Comprehensive coverage of all conditions checked in safe mode.</td>
</tr>
<tr class="odd_tr">
<tr>
<td><a href="../test/test_serialization1.cpp"><code>test_serialization1.cpp</code></a><br>
<a href="../test/test_serialization2.cpp"><code>test_serialization2.cpp</code></a><br>
<a href="../test/test_serialization3.cpp"><code>test_serialization3.cpp</code></a></td>
<td>Serialization support.</td>
</tr>
<tr>
<tr class="odd_tr">
<td><a href="../test/test_set_ops.cpp"><code>test_set_ops.cpp</code></a></td>
<td>Set-like operations particular to ordered indices.</td>
</tr>
<tr class="odd_tr">
<tr>
<td><a href="../test/test_special_set_ops.cpp"><code>test_special_set_ops.cpp</code></a></td>
<td>Checks special lookup operations using compatible sorting criteria.</td>
</tr>
<tr>
<tr class="odd_tr">
<td><a href="../test/test_update.cpp"><code>test_update.cpp</code></a></td>
<td><code>replace</code>, <code>modify</code> and <code>modify_key</code>.</td>
</tr>
@ -150,9 +154,9 @@ Future work
<br>
<p>Revised July 11th 2007</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 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

@ -497,6 +497,10 @@ Currently, Boost.MultiIndex provides the following index types:
provide a similar interface. There are <i>unique</i> and <i>non-unique</i>
variants: the former do not allow for duplicates, while the latter permit
them (like <code>std::multiset</code>.)</li>
<li>Ranked indices are a variation of ordered indices providing extra capabilities
for querying and accessing elements based on their <i>rank</i> (the numerical position
they occupy in the index).
</li>
<li>Sequenced indices are modeled after the semantics and interface of
<code>std::list</code>: they arrange the elements as if in a bidirectional
list.</li>
@ -1248,9 +1252,9 @@ Index types
<br>
<p>Revised November 11th 2014</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2015 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

@ -31,6 +31,12 @@ Key extraction
<ul>
<li><a href="#classification">Classification</a>
<li><a href="#rnk_indices">Ranked indices</a>
<ul>
<li><a href="#rnk_spec">Specification</a></li>
<li><a href="#rnk_ops">Rank operations</a></li>
</ul>
</li>
<li><a href="#hashed_indices">Hashed indices</a>
<ul>
<li><a href="#hash_unique_non_unique">Unique and non-unique variants</a></li>
@ -71,13 +77,19 @@ some added benefits, functionally or in the area of performance.
<th align="center">specifier</th>
</tr>
<tr>
<td align="center" rowspan="4">&nbsp;&nbsp;key-based&nbsp;&nbsp;</td>
<td align="center" rowspan="2">&nbsp;&nbsp;ordered&nbsp;&nbsp;</td>
<td align="center" rowspan="6">&nbsp;&nbsp;key-based&nbsp;&nbsp;</td>
<td align="center" rowspan="4">&nbsp;&nbsp;ordered&nbsp;&nbsp;</td>
<td align="center">&nbsp;&nbsp;<code>ordered_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr class="odd_tr">
<td align="center">&nbsp;&nbsp;<code>ordered_non_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr>
<td align="center">&nbsp;&nbsp;<code>ranked_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr class="odd_tr">
<td align="center">&nbsp;&nbsp;<code>ranked_non_unique</code>&nbsp;&nbsp;</td>
</tr>
<tr>
<td align="center" rowspan="2">&nbsp;&nbsp;hashed&nbsp;&nbsp;</td>
<td align="center">&nbsp;&nbsp;<code>hashed_unique</code>&nbsp;&nbsp;</td>
@ -108,6 +120,111 @@ modeled after the interface of <code>std::list</code>, are the customary
example of a non key-based index.
</p>
<h2><a name="rnk_indices">Ranked indices</a></h2>
<p>
Suppose we have a <code>std::multiset</code> of numbers and we want to output
the values above the 75h <a href="http://en.wikipedia.org/wiki/Percentile">percentile</a>:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=identifier>int_multiset</span><span class=special>;</span>
<span class=keyword>void</span> <span class=identifier>output_above_75th_percentile</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>int_multiset</span><span class=special>&amp;</span> <span class=identifier>s</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>();</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>advance</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</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=comment>// linear on s.size();</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>copy</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream_iterator</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>cout</span><span class=special>,</span><span class=string>&quot;\n&quot;</span><span class=special>));</span>
<span class=special>}</span>
</pre></blockquote>
<p>
The problem with this code is that getting to the beginning of the desired subsequence
involves a linear traversal of the container. Ranked indices provide the mechanisms to do this
much faster:
</p>
<blockquote><pre>
<span class=keyword>typedef</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>ranked_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=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>int_multiset</span><span class=special>;</span>
<span class=keyword>void</span> <span class=identifier>output_above_75th_percentile</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>int_multiset</span><span class=special>&amp;</span> <span class=identifier>s</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>nth</span><span class=special>(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</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=comment>// logarithmic</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>copy</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream_iterator</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>cout</span><span class=special>,</span><span class=string>&quot;\n&quot;</span><span class=special>));</span>
<span class=special>}</span>
</pre></blockquote>
<p>
<code>nth(n)</code> returns an iterator to the element whose <i>rank</i>, i.e. its distance
from the beginning of the index, is <code>n</code>, and does so efficiently in logarithmic time.
Conversely, <code>rank(it)</code> computes in logarithmic time the rank of the element
pointed to by <code>it</code>, or <code>size()</code> if <code>it==end()</code>.
</p>
<blockquote><pre>
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>10</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
<span class=identifier>int_multiset</span><span class=special>::</span><span class=identifier>size_type</span> <span class=identifier>r</span><span class=special>=</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>rank</span><span class=special>(</span><span class=identifier>it</span><span class=special>);</span> <span class=comment>// rank of 10;</span>
</pre></blockquote>
<p>
Ranked indices provide the same interface as ordered indices plus several rank-related operations.
The cost of this extra functionality is higher memory consumption due to some internal additional
data (one word per element) and marginally longer execution times in insertion and erasure.
The <a href="../reference/rnk_indices.html">reference</a> describes these indices in complete detail.
</p>
<h3><a name="rnk_spec">Specification</a></h3>
<p>
The specification of ranked indices is done exactly as with <a href="basics.html#ord_spec">ordered indices</a>,
except that <code>ranked_unique</code> and <code>ranked_non_unique</code> are used instead.
</p>
<blockquote><pre>
<span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)
</span><span class=special>&lt;[</span><i>(tag)</i><span class=special>[,</span><i>(key extractor)</i><span class=special>[,</span><i>(comparison predicate)</i><span class=special>]]]&gt;</span>
<span class=special>(</span><span class=identifier>ranked_unique</span> <span class=special>|</span> <span class=identifier>ranked_non_unique</span><span class=special>)</span>
<span class=special>&lt;[</span><i>(key extractor)</i><span class=special>[,</span><i>(comparison predicate)</i><span class=special>]]&gt;</span>
</pre></blockquote>
<h3><a name="rnk_ops">Rank operations</a></h3>
<p>
Besides <code>nth</code> and <code>rank</code>, ranked indices provide member functions
<ul>
<li><code>find_rank</code>,</li>
<li><code>lower_bound_rank</code>,</li>
<li><code>upper_bound_rank</code>,</li>
<li><code>equal_range_rank</code> and </li>
<li><code>range_rank</code></li>
</ul>
that behave as their normal
<a href="basics.html#special_lookup">lookup</a> and <a href="basics.html#range">range retrieval</a>
counterparts (<code>find</code>, <code>lower_bound</code> etc.) but return ranks rather than iterators.
</p>
<blockquote><pre>
<span class=keyword>void</span> <span class=identifier>percentile</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>int_multiset</span><span class=special>&amp;</span> <span class=identifier>s</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=identifier>n</span><span class=special>&lt;&lt;</span><span class=string>&quot; lies in the &quot;</span><span class=special>&lt;&lt;</span>
<span class=identifier>s</span><span class=special>.</span><span class=identifier>upper_bound_rank</span><span class=special>(</span><span class=identifier>n</span><span class=special>)*</span><span class=number>100.0</span><span class=special>/</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>size</span><span class=special>()&lt;&lt;</span><span class=string>&quot; percentile\n&quot;</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
You might think that <code>upper_bound_rank(n)</code> is mere shorthand for
<code>rank(upper_bound(n))</code>: in reality, though, you should prefer using
<code>*_rank</code> operations directly as they run faster than the
alternative formulations.
</p>
<h2><a name="hashed_indices">Hashed indices</a></h2>
<p>
@ -162,25 +279,10 @@ determining whether a hashed index is preferred over an ordered one.
</p>
<p>
If you are familiar with non-standard <code>hash_set</code>s provided
by some compiler vendors, then learning to use hashed indices should be straightforward.
However, the interface of hashed indices is modeled after the specification
for unordered associative containers by the
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf">C++ Standard
Library Technical Report</a> (TR1),
which differs in some significant aspects from existing pre-standard
implementations:
<ul>
<li>As there is no notion of ordering between keys, the <a href="#hash_lookup">lookup
interface</a> does not offer <code>lower_bound</code> or <code>upper_bound</code>
member functions (unlike Dinkumware's solution.)</li>
<li>A set of member functions is provided for handling the internal
bucket structure on which hashed indices rely. This includes facilities
for <a href="../reference/hash_indices.html#hash_policy">rehashing</a>,
control of the load factor (number of elements divided by number of buckets),
and inspection of the buckets contents. Pre-standard implementations
do not have such an extensive functionality.</li>
</ul>
Hashed indices replicate the interface as <code>std::unordered_set</code> and
<code>std::unordered_multiset</code>, with only minor differences where required
by the general constraints of <code>multi_index_container</code>s, and provide
additional useful capabilities like in-place updating of elements.
Check the <a href="../reference/hash_indices.html">reference</a> for a
complete specification of the interface of hashed indices,
and <a href="../examples.html#example8">example 8</a> and
@ -352,19 +454,18 @@ member functions, with the same functionality as in ordered indices.
Due to the internal constraints imposed by the Boost.MultiIndex framework,
hashed indices provide guarantees on iterator validity and
exception safety that are actually stronger than required by the
C++ Standard Library Technical Report (TR1) with respect
to unordered associative containers:
C++ standard with respect to unordered associative containers:
<ul>
<li>Iterator validity is preserved in any case during insertion or rehashing:
TR1 allows for iterator invalidation when a rehash (implicit or explicit)
C++ unordered associative containers can invalidate iterators when a rehash (implicit or explicit)
is performed.</li>
<li>Erasing an element or range of elements via iterators does not throw ever,
as the internal hash function and equality predicate objects are not actually
invoked.</li>
<li><code>rehash</code> provides the strong exception safety guarantee
unconditionally. TR1 only warrants it if the internal hash function and
unconditionally. The standard only warrants it for unordered associative containers if the internal hash function and
equality predicate objects do not throw. The somewhat surprising consequence
is that a TR1-compliant unordered associative container might erase
is that a standard-compliant <code>std::unordered_set</code>might erase
elements if an exception is thrown during rehashing!</li>
</ul>
In general, these stronger guarantees play in favor of the user's convenience,
@ -673,7 +774,7 @@ in scenarios where access via iterators is not suitable or desireable:
<h2><a name="ordered_node_compression">Ordered indices node compression</a></h2>
<p>
Ordered indices are implemented by means of a data structure
Ordered and ranked indices are implemented by means of a data structure
known as a <i>red-black tree</i>. Nodes of a red-back tree contain pointers
to the parent and the two children nodes, plus a 1-bit field referred to as
the <i>node color</i> (hence the name of the structure). Due to alignment
@ -687,7 +788,7 @@ significant bit of the address must always be zero.
</p>
<p>
Boost.MultiIndex ordered indices implement this type of node compression
Boost.MultiIndex ordered and ranked indices implement this type of node compression
whenever applicable. As compared with common implementations of the STL
container <code>std::set</code>, node compression can
result in a reduction of header overload by 25% (from 16 to 12 bytes on
@ -717,7 +818,7 @@ Key extraction
<br>
<p>Revised March 25th 2015</p>
<p>Revised April 19th 2015</p>
<p>&copy; Copyright 2003-2015 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP
#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost{
namespace multi_index{
namespace detail{
template<
typename KeyFromValue,typename Compare,
typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
>
class ordered_index;
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename AugmentPolicy1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2,
typename AugmentPolicy2
>
bool operator==(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename AugmentPolicy1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2,
typename AugmentPolicy2
>
bool operator<(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename AugmentPolicy1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2,
typename AugmentPolicy2
>
bool operator!=(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename AugmentPolicy1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2,
typename AugmentPolicy2
>
bool operator>(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename AugmentPolicy1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2,
typename AugmentPolicy2
>
bool operator>=(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename AugmentPolicy1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2,
typename AugmentPolicy2
>
bool operator<=(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
template<
typename KeyFromValue,typename Compare,
typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
>
void swap(
ordered_index<
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
ordered_index<
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y);
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -63,24 +63,24 @@ namespace detail{
enum ordered_index_color{red=false,black=true};
enum ordered_index_side{to_left=false,to_right=true};
template<typename Allocator>
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_impl; /* fwd decl. */
template<typename Allocator>
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_std_base
{
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
ordered_index_node_impl<Allocator>
>::type::pointer pointer;
ordered_index_node_impl<AugmentPolicy,Allocator>
>::type::pointer pointer;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
ordered_index_node_impl<Allocator>
>::type::const_pointer const_pointer;
typedef ordered_index_color& color_ref;
typedef pointer& parent_ref;
ordered_index_node_impl<AugmentPolicy,Allocator>
>::type::const_pointer const_pointer;
typedef ordered_index_color& color_ref;
typedef pointer& parent_ref;
ordered_index_color& color(){return color_;}
ordered_index_color color()const{return color_;}
@ -116,11 +116,13 @@ private:
#pragma warning(disable:4312 4311)
#endif
template<typename Allocator>
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_compressed_base
{
typedef ordered_index_node_impl<Allocator>* pointer;
typedef const ordered_index_node_impl<Allocator>* const_pointer;
typedef ordered_index_node_impl<
AugmentPolicy,Allocator>* pointer;
typedef const ordered_index_node_impl<
AugmentPolicy,Allocator>* const_pointer;
struct color_ref
{
@ -203,39 +205,44 @@ private:
#endif
#endif
template<typename Allocator>
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_impl_base:
AugmentPolicy::template augmented_node<
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
mpl::if_c<
!(has_uintptr_type::value)||
(alignment_of<ordered_index_node_compressed_base<Allocator> >::value%2)||
!(is_same<
typename boost::detail::allocator::rebind_to<
Allocator,
ordered_index_node_impl<Allocator>
>::type::pointer,
ordered_index_node_impl<Allocator>*>::value),
ordered_index_node_std_base<Allocator>,
ordered_index_node_compressed_base<Allocator>
>::type
mpl::if_c<
!(has_uintptr_type::value)||
(alignment_of<
ordered_index_node_compressed_base<AugmentPolicy,Allocator>
>::value%2)||
!(is_same<
typename boost::detail::allocator::rebind_to<
Allocator,
ordered_index_node_impl<AugmentPolicy,Allocator>
>::type::pointer,
ordered_index_node_impl<AugmentPolicy,Allocator>*>::value),
ordered_index_node_std_base<AugmentPolicy,Allocator>,
ordered_index_node_compressed_base<AugmentPolicy,Allocator>
>::type
#else
ordered_index_node_std_base<Allocator>
ordered_index_node_std_base<Allocator>
#endif
>::type
{};
template<typename Allocator>
struct ordered_index_node_impl:ordered_index_node_impl_base<Allocator>
template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_impl:
ordered_index_node_impl_base<AugmentPolicy,Allocator>
{
private:
typedef ordered_index_node_impl_base<Allocator> super;
typedef ordered_index_node_impl_base<AugmentPolicy,Allocator> super;
public:
typedef typename super::color_ref color_ref;
typedef typename super::parent_ref parent_ref;
typedef typename super::pointer pointer;
typedef typename super::const_pointer const_pointer;
typedef typename super::color_ref color_ref;
typedef typename super::parent_ref parent_ref;
typedef typename super::pointer pointer;
typedef typename super::const_pointer const_pointer;
/* interoperability with bidir_node_iterator */
@ -288,6 +295,7 @@ public:
else x->parent()->right()=y;
y->left()=x;
x->parent()=y;
AugmentPolicy::rotate_left(x,y);
}
static pointer minimum(pointer x)
@ -314,6 +322,7 @@ public:
else x->parent()->left()=y;
y->right()=x;
x->parent()=y;
AugmentPolicy::rotate_right(x,y);
}
static void rebalance(pointer x,parent_ref root)
@ -382,6 +391,7 @@ public:
x->parent()=position;
x->left()=pointer(0);
x->right()=pointer(0);
AugmentPolicy::add(x,pointer(header->parent()));
ordered_index_node_impl::rebalance(x,header->parent());
}
@ -404,7 +414,9 @@ public:
x=y->right();
}
}
AugmentPolicy::remove(y,pointer(root));
if(y!=z){
AugmentPolicy::copy(z,y);
z->left()->parent()=y; /* relink y in place of z. y is z's successor */
y->left()=z->left();
if(y!=z->right()){
@ -547,9 +559,10 @@ public:
#endif
};
template<typename Super>
template<typename AugmentPolicy,typename Super>
struct ordered_index_node_trampoline:
ordered_index_node_impl<
AugmentPolicy,
typename boost::detail::allocator::rebind_to<
typename Super::allocator_type,
char
@ -557,6 +570,7 @@ struct ordered_index_node_trampoline:
>
{
typedef ordered_index_node_impl<
AugmentPolicy,
typename boost::detail::allocator::rebind_to<
typename Super::allocator_type,
char
@ -564,11 +578,12 @@ struct ordered_index_node_trampoline:
> impl_type;
};
template<typename Super>
struct ordered_index_node:Super,ordered_index_node_trampoline<Super>
template<typename AugmentPolicy,typename Super>
struct ordered_index_node:
Super,ordered_index_node_trampoline<AugmentPolicy,Super>
{
private:
typedef ordered_index_node_trampoline<Super> trampoline;
typedef ordered_index_node_trampoline<AugmentPolicy,Super> trampoline;
public:
typedef typename trampoline::impl_type impl_type;

View File

@ -0,0 +1,298 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP
#define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/mpl/and.hpp>
#include <boost/multi_index/detail/promotes_arg.hpp>
#include <cstddef>
#include <utility>
namespace boost{
namespace multi_index{
namespace detail{
/* Common code for ranked_index memfuns having templatized and
* non-templatized versions.
*/
template<typename Pointer>
inline std::size_t ranked_node_size(Pointer x)
{
return x!=Pointer(0)?x->size:0;
}
template<typename Pointer>
inline Pointer ranked_index_nth(std::size_t n,Pointer top,Pointer end_)
{
if(top==Pointer(0)||n>=top->size)return end_;
for(;;){
std::size_t s=ranked_node_size(top->left());
if(n==s)return top;
if(n<s)top=top->left();
else{
top=top->right();
n-=s+1;
}
}
}
template<typename Pointer>
inline std::size_t ranked_index_rank(Pointer x,Pointer top)
{
if(top==Pointer(0))return 0;
if(x==top->parent())return top->size; /* end */
std::size_t s=ranked_node_size(x->left());
while(x!=top){
Pointer z=x->parent();
if(x==z->right()){
s+=ranked_node_size(z->left())+1;
}
x=z;
}
return s;
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_find_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp)
{
typedef typename KeyFromValue::result_type key_type;
return ranked_index_find_rank(
top,y,key,x,comp,
mpl::and_<
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleCompare
>
inline std::size_t ranked_index_find_rank(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
{
return ranked_index_find_rank(top,y,key,x,comp,mpl::false_());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_find_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
{
if(!top)return 0;
std::size_t s=top->size,
s0=s;
Node* y0=y;
do{
if(!comp(key(top->value()),x)){
y=top;
s-=ranked_node_size(y->right())+1;
top=Node::from_impl(top->left());
}
else top=Node::from_impl(top->right());
}while(top);
return (y==y0||comp(x,key(y->value())))?s0:s;
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_lower_bound_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp)
{
typedef typename KeyFromValue::result_type key_type;
return ranked_index_lower_bound_rank(
top,y,key,x,comp,
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleCompare
>
inline std::size_t ranked_index_lower_bound_rank(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
{
return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_lower_bound_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
{
if(!top)return 0;
std::size_t s=top->size;
do{
if(!comp(key(top->value()),x)){
y=top;
s-=ranked_node_size(y->right())+1;
top=Node::from_impl(top->left());
}
else top=Node::from_impl(top->right());
}while(top);
return s;
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_upper_bound_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp)
{
typedef typename KeyFromValue::result_type key_type;
return ranked_index_upper_bound_rank(
top,y,key,x,comp,
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleCompare
>
inline std::size_t ranked_index_upper_bound_rank(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
{
return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::size_t ranked_index_upper_bound_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
{
if(!top)return 0;
std::size_t s=top->size;
do{
if(comp(x,key(top->value()))){
y=top;
s-=ranked_node_size(y->right())+1;
top=Node::from_impl(top->left());
}
else top=Node::from_impl(top->right());
}while(top);
return s;
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp)
{
typedef typename KeyFromValue::result_type key_type;
return ranked_index_equal_range_rank(
top,y,key,x,comp,
mpl::and_<
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleCompare
>
inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
Node* top,Node* y,const KeyFromValue& key,
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
const CompatibleCompare& comp,mpl::true_)
{
return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_());
}
template<
typename Node,typename KeyFromValue,
typename CompatibleKey,typename CompatibleCompare
>
inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
const CompatibleCompare& comp,mpl::false_)
{
if(!top)return std::pair<std::size_t,std::size_t>(0,0);
std::size_t s=top->size;
do{
if(comp(key(top->value()),x)){
top=Node::from_impl(top->right());
}
else if(comp(x,key(top->value()))){
y=top;
s-=ranked_node_size(y->right())+1;
top=Node::from_impl(top->left());
}
else{
return std::pair<std::size_t,std::size_t>(
s-top->size+
ranked_index_lower_bound_rank(
Node::from_impl(top->left()),top,key,x,comp,mpl::false_()),
s-ranked_node_size(top->right())+
ranked_index_upper_bound_rank(
Node::from_impl(top->right()),y,key,x,comp,mpl::false_()));
}
}while(top);
return std::pair<std::size_t,std::size_t>(s,s);
}
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -14,101 +14,12 @@
#endif
#include <boost/multi_index/detail/ord_index_args.hpp>
#include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
namespace boost{
namespace multi_index{
namespace detail{
template<
typename KeyFromValue,typename Compare,
typename SuperMeta,typename TagList,typename Category
>
class ordered_index;
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2
>
bool operator==(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2
>
bool operator<(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2
>
bool operator!=(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2
>
bool operator>(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2
>
bool operator>=(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
template<
typename KeyFromValue1,typename Compare1,
typename SuperMeta1,typename TagList1,typename Category1,
typename KeyFromValue2,typename Compare2,
typename SuperMeta2,typename TagList2,typename Category2
>
bool operator<=(
const ordered_index<
KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
const ordered_index<
KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y);
template<
typename KeyFromValue,typename Compare,
typename SuperMeta,typename TagList,typename Category
>
void swap(
ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& y);
} /* namespace multi_index::detail */
/* ordered_index specifiers */
template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na>

View File

@ -0,0 +1,382 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_HPP
#define BOOST_MULTI_INDEX_RANKED_INDEX_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/multi_index/detail/ord_index_impl.hpp>
#include <boost/multi_index/detail/rnk_index_ops.hpp>
#include <boost/multi_index/ranked_index_fwd.hpp>
namespace boost{
namespace multi_index{
namespace detail{
/* ranked_index augments a given ordered index to provide rank operations */
template<typename OrderedIndexNodeImpl>
struct ranked_node:OrderedIndexNodeImpl
{
std::size_t size;
};
template<typename OrderedIndexImpl>
class ranked_index:public OrderedIndexImpl
{
typedef typename OrderedIndexImpl super;
protected:
typedef typename super::node_type node_type;
typedef typename super::node_impl_pointer node_impl_pointer;
public:
typedef typename super::ctor_args_list ctor_args_list;
typedef typename super::allocator_type allocator_type;
typedef typename super::iterator iterator;
/* rank operations */
iterator nth(std::size_t n)const
{
return make_iterator(node_type::from_impl(
ranked_index_nth(n,this->root()->impl(),this->header()->impl())));
}
std::size_t rank(iterator position)const
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
return ranked_index_rank(
position.get_node()->impl(),this->root()->impl());
}
template<typename CompatibleKey>
std::size_t find_rank(const CompatibleKey& x)const
{
return ranked_index_find_rank(
this->root(),this->header(),this->key,x,this->comp_);
}
template<typename CompatibleKey,typename CompatibleCompare>
std::size_t find_rank(
const CompatibleKey& x,const CompatibleCompare& comp)const
{
return ranked_index_find_rank(
this->root(),this->header(),this->key,x,comp);
}
template<typename CompatibleKey>
std::size_t lower_bound_rank(const CompatibleKey& x)const
{
return ranked_index_lower_bound_rank(
this->root(),this->header(),this->key,x,this->comp_);
}
template<typename CompatibleKey,typename CompatibleCompare>
std::size_t lower_bound_rank(
const CompatibleKey& x,const CompatibleCompare& comp)const
{
return ranked_index_lower_bound_rank(
this->root(),this->header(),this->key,x,comp);
}
template<typename CompatibleKey>
std::size_t upper_bound_rank(const CompatibleKey& x)const
{
return ranked_index_upper_bound_rank(
this->root(),this->header(),this->key,x,this->comp_);
}
template<typename CompatibleKey,typename CompatibleCompare>
std::size_t upper_bound_rank(
const CompatibleKey& x,const CompatibleCompare& comp)const
{
return ranked_index_upper_bound_rank(
this->root(),this->header(),this->key,x,comp);
}
template<typename CompatibleKey>
std::pair<std::size_t,std::size_t> equal_range_rank(
const CompatibleKey& x)const
{
return ranked_index_equal_range_rank(
this->root(),this->header(),this->key,x,this->comp_);
}
template<typename CompatibleKey,typename CompatibleCompare>
std::pair<std::size_t,std::size_t> equal_range_rank(
const CompatibleKey& x,const CompatibleCompare& comp)const
{
return ranked_index_equal_range_rank(
this->root(),this->header(),this->key,x,comp);
}
template<typename LowerBounder,typename UpperBounder>
std::pair<std::size_t,std::size_t>
range_rank(LowerBounder lower,UpperBounder upper)const
{
typedef typename mpl::if_<
is_same<LowerBounder,unbounded_type>,
BOOST_DEDUCED_TYPENAME mpl::if_<
is_same<UpperBounder,unbounded_type>,
both_unbounded_tag,
lower_unbounded_tag
>::type,
BOOST_DEDUCED_TYPENAME mpl::if_<
is_same<UpperBounder,unbounded_type>,
upper_unbounded_tag,
none_unbounded_tag
>::type
>::type dispatch;
return range_rank(lower,upper,dispatch());
}
protected:
ranked_index(const ranked_index& x):super(x){};
ranked_index(const ranked_index& x,do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()){};
ranked_index(
const ctor_args_list& args_list,const allocator_type& al):
super(args_list,al){}
private:
template<typename LowerBounder,typename UpperBounder>
std::pair<std::size_t,std::size_t>
range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
{
node_type* y=header();
node_type* z=root();
if(!z)return std::pair<std::size_t,std::size_t>(0,0);
std::size_t s=z->size;
do{
if(!lower(key(z->value()))){
z=node_type::from_impl(z->right());
}
else if(!upper(key(z->value()))){
y=z;
s-=ranked_node_size(y->right())+1;
z=node_type::from_impl(z->left());
}
else{
return std::pair<std::size_t,std::size_t>(
s-z->size+
lower_range_rank(node_type::from_impl(z->left()),z,lower),
s-ranked_node_size(z->right())+
upper_range_rank(node_type::from_impl(z->right()),y,upper));
}
}while(z);
return std::pair<std::size_t,std::size_t>(s,s);
}
template<typename LowerBounder,typename UpperBounder>
std::pair<std::size_t,std::size_t>
range_rank(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
{
return std::pair<std::size_t,std::size_t>(
0,
upper_range_rank(root(),header(),upper));
}
template<typename LowerBounder,typename UpperBounder>
std::pair<std::size_t,std::size_t>
range_rank(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
{
return std::pair<std::size_t,std::size_t>(
lower_range_rank(root(),header(),lower),
this->size());
}
template<typename LowerBounder,typename UpperBounder>
std::pair<std::size_t,std::size_t>
range_rank(LowerBounder,UpperBounder,both_unbounded_tag)const
{
return std::pair<std::size_t,std::size_t>(0,this->size());
}
template<typename LowerBounder>
std::size_t
lower_range_rank(node_type* top,node_type* y,LowerBounder lower)const
{
if(!top)return 0;
std::size_t s=top->size;
do{
if(lower(key(top->value()))){
y=top;
s-=ranked_node_size(y->right())+1;
top=node_type::from_impl(top->left());
}
else top=node_type::from_impl(top->right());
}while(top);
return s;
}
template<typename UpperBounder>
std::size_t
upper_range_rank(node_type* top,node_type* y,UpperBounder upper)const
{
if(!top)return 0;
std::size_t s=top->size;
do{
if(!upper(key(top->value()))){
y=top;
s-=ranked_node_size(y->right())+1;
top=node_type::from_impl(top->left());
}
else top=node_type::from_impl(top->right());
}while(top);
return s;
}
};
/* augmenting policy for ordered_index */
struct rank_policy
{
template<typename OrderedIndexNodeImpl>
struct augmented_node
{
typedef ranked_node<OrderedIndexNodeImpl> type;
};
template<typename OrderedIndexImpl>
struct augmented_interface
{
typedef ranked_index<OrderedIndexImpl> type;
};
/* algorihmic stuff */
template<typename Pointer>
static void add(Pointer x,Pointer root)
{
x->size=1;
while(x!=root){
x=x->parent();
++(x->size);
}
}
template<typename Pointer>
static void remove(Pointer x,Pointer root)
{
while(x!=root){
x=x->parent();
--(x->size);
}
}
template<typename Pointer>
static void copy(Pointer x,Pointer y)
{
y->size=x->size;
}
template<typename Pointer>
static void rotate_left(Pointer x,Pointer y) /* in: x==y->left() */
{
y->size=x->size;
x->size=ranked_node_size(x->left())+ranked_node_size(x->right())+1;
};
template<typename Pointer>
static void rotate_right(Pointer x,Pointer y) /* in: x==y->right() */
{
rotate_left(x,y);
};
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
/* invariant stuff */
template<typename Pointer>
static bool invariant(Pointer x)
{
return x->size==ranked_node_size(x->left())+ranked_node_size(x->right())+1;
}
#endif
};
} /* namespace multi_index::detail */
/* ranked_index specifiers */
template<typename Arg1,typename Arg2,typename Arg3>
struct ranked_unique
{
typedef typename detail::ordered_index_args<
Arg1,Arg2,Arg3> index_args;
typedef typename index_args::tag_list_type::type tag_list_type;
typedef typename index_args::key_from_value_type key_from_value_type;
typedef typename index_args::compare_type compare_type;
template<typename Super>
struct node_class
{
typedef detail::ordered_index_node<detail::rank_policy,Super> type;
};
template<typename SuperMeta>
struct index_class
{
typedef detail::ordered_index<
key_from_value_type,compare_type,
SuperMeta,tag_list_type,detail::ordered_unique_tag,
detail::rank_policy> type;
};
};
template<typename Arg1,typename Arg2,typename Arg3>
struct ranked_non_unique
{
typedef detail::ordered_index_args<
Arg1,Arg2,Arg3> index_args;
typedef typename index_args::tag_list_type::type tag_list_type;
typedef typename index_args::key_from_value_type key_from_value_type;
typedef typename index_args::compare_type compare_type;
template<typename Super>
struct node_class
{
typedef detail::ordered_index_node<detail::rank_policy,Super> type;
};
template<typename SuperMeta>
struct index_class
{
typedef detail::ordered_index<
key_from_value_type,compare_type,
SuperMeta,tag_list_type,detail::ordered_non_unique_tag,
detail::rank_policy> type;
};
};
} /* namespace multi_index */
} /* namespace boost */
#endif

View File

@ -0,0 +1,35 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP
#define BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/multi_index/detail/ord_index_args.hpp>
#include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
namespace boost{
namespace multi_index{
/* ranked_index specifiers */
template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na>
struct ranked_unique;
template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na>
struct ranked_non_unique;
} /* namespace multi_index */
} /* namespace boost */
#endif

View File

@ -1,6 +1,6 @@
# Boost.MultiIndex tests Jamfile
#
# Copyright 2003-2007 Joaqu匤 M L<>ez Mu<4D>z.
# Copyright 2003-2015 Joaquín M López Muñoz.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
@ -42,6 +42,7 @@ test-suite "multi_index" :
[ run test_observers.cpp test_observers_main.cpp ]
[ run test_projection.cpp test_projection_main.cpp ]
[ run test_range.cpp test_range_main.cpp ]
[ run test_rank_ops.cpp test_rank_ops_main.cpp ]
[ run test_rearrange.cpp test_rearrange_main.cpp ]
[ run test_safe_mode.cpp test_safe_mode_main.cpp ]
[ run test_serialization.cpp test_serialization1.cpp

View File

@ -1,6 +1,6 @@
/* Used in Boost.MultiIndex tests.
*
* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -21,6 +21,7 @@
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/ranked_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <cstddef>
#include <ostream>
@ -109,7 +110,7 @@ struct employee_set_indices:
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<name,by_name>,
BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
boost::multi_index::ordered_non_unique<
boost::multi_index::ranked_non_unique<
boost::multi_index::tag<age>,
BOOST_MULTI_INDEX_MEMBER(employee,int,age)>,
boost::multi_index::sequenced<

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test suite.
*
* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -24,6 +24,7 @@
#include "test_observers.hpp"
#include "test_projection.hpp"
#include "test_range.hpp"
#include "test_rank_ops.hpp"
#include "test_rearrange.hpp"
#include "test_safe_mode.hpp"
#include "test_serialization.hpp"
@ -48,6 +49,7 @@ int main()
test_observers();
test_projection();
test_range();
test_rank_ops();
test_rearrange();
test_safe_mode();
test_serialization();

140
test/test_rank_ops.cpp Normal file
View File

@ -0,0 +1,140 @@
/* Boost.MultiIndex test for rank operations.
*
* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#include "test_rank_ops.hpp"
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <iterator>
#include <set>
#include <boost/detail/lightweight_test.hpp>
#include "pre_multi_index.hpp"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/ranked_index.hpp>
using namespace boost::multi_index;
template<
typename Sequence1,typename Iterator2,typename Sequence2
>
bool same_position(
std::size_t n1,const Sequence1& s1,Iterator2 it2,const Sequence2& s2)
{
typedef typename Sequence1::const_iterator const_iterator;
const_iterator it1=s1.begin();
std::advance(it1,n1);
return std::distance(s1.begin(),it1)==std::distance(s2.begin(),it2);
}
struct less_equal_than
{
less_equal_than(int n_):n(n_){}
bool operator()(int x)const{return x<=n;}
int n;
};
struct greater_equal_than
{
greater_equal_than(int n_):n(n_){}
bool operator()(int x)const{return x>=n;}
int n;
};
template<typename Sequence>
static void local_test_rank_ops()
{
int data[]={2,2,1,5,6,7,9,10,9,6,9,6,9};
Sequence s(data,data+sizeof(data)/sizeof(data[0]));
std::multiset<int> ss(s.begin(),s.end());
typedef typename Sequence::iterator iterator;
iterator it=s.begin();
for(std::size_t n=0;n<=s.size()+1;++n){
BOOST_TEST(s.nth(n)==it);
BOOST_TEST(s.rank(it)==(std::min)(s.size(),n));
if(it!=s.end())++it;
}
std::pair<std::size_t,std::size_t> p1;
std::pair<iterator,iterator> p2;
p1=s.range_rank(unbounded,unbounded);
p2=s.range(unbounded,unbounded);
BOOST_TEST(same_position(p1.first,s,p2.first,s));
BOOST_TEST(same_position(p1.second,s,p2.second,s));
for(int i=0;i<12;++i){
std::size_t pos=s.find_rank(i);
BOOST_TEST(pos==s.size()&&ss.find(i)==ss.end() || *s.nth(pos)==i);
BOOST_TEST(same_position(s.lower_bound_rank(i),s,ss.lower_bound(i),ss));
BOOST_TEST(same_position(s.upper_bound_rank(i),s,ss.upper_bound(i),ss));
std::pair<std::size_t,std::size_t> posp=s.equal_range_rank(i);
BOOST_TEST(same_position(posp.first,s,ss.lower_bound(i),ss));
BOOST_TEST(same_position(posp.second,s,ss.upper_bound(i),ss));
p1=s.range_rank(greater_equal_than(i),unbounded);
p2=s.range(greater_equal_than(i),unbounded);
BOOST_TEST(same_position(p1.first,s,p2.first,s));
BOOST_TEST(same_position(p1.second,s,p2.second,s));
p1=s.range_rank(unbounded,less_equal_than(i));
p2=s.range(unbounded,less_equal_than(i));
BOOST_TEST(same_position(p1.first,s,p2.first,s));
BOOST_TEST(same_position(p1.second,s,p2.second,s));
for(int j=0;j<12;++j){
p1=s.range_rank(greater_equal_than(i),less_equal_than(j));
p2=s.range(greater_equal_than(i),less_equal_than(j));
BOOST_TEST(same_position(p1.first,s,p2.first,s));
BOOST_TEST(same_position(p1.second,s,p2.second,s));
}
}
Sequence se; /* empty */
BOOST_TEST(se.nth(0)==se.end());
BOOST_TEST(se.nth(1)==se.end());
BOOST_TEST(se.rank(se.end())==0);
BOOST_TEST(se.find_rank(0)==0);
BOOST_TEST(se.lower_bound_rank(0)==0);
BOOST_TEST(se.upper_bound_rank(0)==0);
p1=se.equal_range_rank(0);
BOOST_TEST(p1.first==0&&p1.second==0);
p1=se.range_rank(unbounded,unbounded);
BOOST_TEST(p1.first==0&&p1.second==0);
p1=se.range_rank(greater_equal_than(0),unbounded);
BOOST_TEST(p1.first==0&&p1.second==0);
p1=se.range_rank(unbounded,less_equal_than(0));
BOOST_TEST(p1.first==0&&p1.second==0);
p1=se.range_rank(greater_equal_than(0),less_equal_than(0));
BOOST_TEST(p1.first==0&&p1.second==0);
}
void test_rank_ops()
{
typedef multi_index_container<
int,
indexed_by<
ranked_unique<identity<int> >
>
> ranked_set;
local_test_rank_ops<ranked_set>();
typedef multi_index_container<
int,
indexed_by<
ranked_non_unique<identity<int> >
>
> ranked_multiset;
local_test_rank_ops<ranked_multiset>();
}

11
test/test_rank_ops.hpp Normal file
View File

@ -0,0 +1,11 @@
/* Boost.MultiIndex test for rank operations.
*
* Copyright 2003-20015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
void test_rank_ops();

View File

@ -0,0 +1,18 @@
/* Boost.MultiIndex test for rank operations.
*
* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#include <boost/detail/lightweight_test.hpp>
#include "test_rank_ops.hpp"
int main()
{
test_rank_ops();
return boost::report_errors();
}