merged [85001], [85004], [85005], [85016], [85017], [85018], [85022], [85028], [85099] and [85100] from trunk

[SVN r85146]
This commit is contained in:
Joaquín M López Muñoz 2013-07-24 07:52:40 +00:00
parent d2f0ef79a2
commit 0bc802ad7d
26 changed files with 2699 additions and 1877 deletions

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,6 @@ principle driving the current internal design of <code>multi_index_container</co
<li><a href="#constraints">Constraints</a></li> <li><a href="#constraints">Constraints</a></li>
<li><a href="#user_defined_indices">User-defined indices</a></li> <li><a href="#user_defined_indices">User-defined indices</a></li>
<li><a href="#indexed_maps">Indexed maps</a></li> <li><a href="#indexed_maps">Indexed maps</a></li>
<li><a href="#move_semantics">Move semantics</a></li>
</ul> </ul>
<h2><a name="ranked_indices">Ranked indices</a></h2> <h2><a name="ranked_indices">Ranked indices</a></h2>
@ -187,31 +186,6 @@ a careful study when designing the interface of a potential
indexed map. indexed map.
</p> </p>
<h2><a name="move_semantics">Move semantics</a></h2>
<p>
Andrei Alexandrescu introduced a technique for simulating move
constructors called Mojo (see his article in C/C++ User Journal
<a href="http://www.cuj.com/documents/s=8246/cujcexp2102alexandr/">
"Generic&lt;Programming>: Move Constructors"</a>.) Move semantics
alleviates the computational load involved in the creation and copying
of temporary objects, specially for heavy classes as
<code>multi_index_container</code>s are. David Abrahams and Gary Powell provide
an alternative implementation of move semantics in their paper
<a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html">
"Clarification of Initialization of Class Objects by rvalues"</a> for
the C++ Evolution Working Group.
</p>
<p>
Adding move semantics to <code>multi_index_container</code> is particularly
beneficial when the container is used as an internal building block in other
libraries (vg. relational database frameworks), enabling the efficient
development of functions returning <code>multi_index_container</code>s. Without support
for move semantics, this scheme is impractical and less elegant syntaxes
should be resorted to.
</p>
<hr> <hr>
<div class="prev_link"><a href="tests.html"><img src="prev.gif" alt="tests" border="0"><br> <div class="prev_link"><a href="tests.html"><img src="prev.gif" alt="tests" border="0"><br>
@ -226,9 +200,9 @@ Release notes
<br> <br>
<p>Revised July 5th 2007</p> <p>Revised July 6th 2013</p>
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -99,6 +99,8 @@ their associated <a href="#hash_indices">hashed index</a> classes.
<code>"boost/multi_index/hashed_index.hpp"</code></a> synopsis</a></h2> <code>"boost/multi_index/hashed_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre> <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>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span> <span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -170,11 +172,8 @@ explanations on their acceptable type values.
<p> <p>
A hashed index provides fast retrieval of elements of a <code>multi_index_container</code> A hashed index provides fast retrieval of elements of a <code>multi_index_container</code>
through hashing tecnhiques. The interface and semantics of hashed indices are modeled according through hashing tecnhiques.
to the proposal for unordered associative containers given in the C++ A hashed index is particularized according to a given
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf">Proposed
Draft Tecnhical Report on Standard Library Extensions</a>, also known as TR1. A hashed
index is particularized according to a given
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a> <a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
that retrieves keys from elements of <code>multi_index_container</code>, a <code>Hash</code> that retrieves keys from elements of <code>multi_index_container</code>, a <code>Hash</code>
function object which returns hash values for the keys and a binary predicate <code>Pred</code> function object which returns hash values for the keys and a binary predicate <code>Pred</code>
@ -190,13 +189,14 @@ together, with minor differences explicitly stated when they exist.
</p> </p>
<p> <p>
Except where noted, hashed indices (both unique and non-unique) are models of Except where noted or if the corresponding interface does not exist, hashed indices
<code>Unordered Associative Container</code>, in the spirit of (both unique and non-unique) satisfy the C++ requirements for undordered associative
<code>std::tr1::unordered_set</code>s. Validity of iterators and references to containers at <b>[unord.req]</b> (supporting unique and equivalent keys, respectively.)
Validity of iterators and references to
elements is preserved in all cases. Occasionally, the exception safety guarantees provided elements is preserved in all cases. Occasionally, the exception safety guarantees provided
are actually stronger than required by the extension draft. We only provide descriptions are actually stronger than required by the standard. We only provide descriptions of
of those types and operations that are either not present in the concepts modeled or those types and operations that do not exactly conform to or are not mandated by the standard
do not exactly conform to the requirements for unordered associative containers. requirements.
</p> </p>
<blockquote><pre> <blockquote><pre>
@ -236,6 +236,7 @@ do not exactly conform to the requirements for unordered associative containers.
<span class=comment>// construct/destroy/copy:</span> <span class=comment>// construct/destroy/copy:</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=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=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=special>;</span>
@ -259,16 +260,25 @@ do not exactly conform to the requirements for unordered associative containers.
<span class=comment>// modifiers:</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=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=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>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>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>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>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=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=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>&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>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>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>
@ -397,13 +407,11 @@ following types:
which determines the mechanism for extracting a key from <code>Value</code>, which determines the mechanism for extracting a key from <code>Value</code>,
must be a model of <a href="key_extraction.html#key_extractors"> must be a model of <a href="key_extraction.html#key_extractors">
<code>Key Extractor</code></a> from <code>Value</code>. <code>Hash</code> is a <code>Key Extractor</code></a> from <code>Value</code>. <code>Hash</code> is a
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"><code>Unary Function</code></a> <code>CopyConstructible</code>unary function object
taking a single argument of type <code>KeyFromValue::result_type</code> and returning a taking a single argument of type <code>KeyFromValue::result_type</code> and returning a
value of type <code>std::size_t</code> in the range value of type <code>std::size_t</code> in the range
<code>[0, std::numeric_limits&lt;std::size_t&gt;::max())</code>. <code>[0, std::numeric_limits&lt;std::size_t&gt;::max())</code>.
<code>Pred</code> is a <code>Pred</code> is a <code>CopyConstructible</code> binary predicate inducing an equivalence relation
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> inducing an equivalence relation
on elements of <code>KeyFromValue::result_type</code>. It is required that on elements of <code>KeyFromValue::result_type</code>. It is required that
the <code>Hash</code> object return the same value for keys the <code>Hash</code> object return the same value for keys
equivalent under <code>Pred</code>. equivalent under <code>Pred</code>.
@ -425,9 +433,7 @@ local_iterator<br>
const_local_iterator</code> const_local_iterator</code>
<blockquote> <blockquote>
These types are models of These types are forward iterators.
<a href="http://www.sgi.com/tech/stl/ForwardIterator.html"><code>Forward
Iterator</code></a>.
</blockquote> </blockquote>
<h4><a name="constructors">Constructors, copy and assignment</a></h4> <h4><a name="constructors">Constructors, copy and assignment</a></h4>
@ -451,6 +457,18 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br> <b>Returns:</b> <code>*this</code>.<br>
</blockquote> </blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<h4><a name="iterators">Iterators</a></h4> <h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br> <code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
@ -465,9 +483,64 @@ const_iterator iterator_to(const value_type&amp; x)const;</code>
<h4><a name="modifiers">Modifiers</a></h4> <h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code> <code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(Args&amp;&amp;... args);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
<li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful insertion,
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
points to an element that caused the insertion to be banned. Note that more than
one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
iterator emplace_hint(iterator position, Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
<li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<code>position</code> is used as a hint to improve the efficiency of the
operation.<br>
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
element. Otherwise, an iterator to an element that caused the insertion to be
banned. Note that more than one element can be causing insertion not to be
allowed.<br>
<b>Complexity:</b> <code>O(H(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which <b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if the index belongs if
<ul> <ul>
@ -485,10 +558,16 @@ one element can be causing insertion not to be allowed.<br>
<b>Exception safety:</b> Strong.<br> <b>Exception safety:</b> Strong.<br>
</blockquote> </blockquote>
<code>iterator insert(iterator position,const value_type&amp; x);</code> <code>iterator insert(iterator position,const value_type&amp; x);</code><br>
<code>iterator insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br> <b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which <b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if the index belongs if
<ul> <ul>
@ -511,24 +590,38 @@ allowed.<br>
void insert(InputIterator first,InputIterator last);</code> void insert(InputIterator first,InputIterator last);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of <b>Requires:</b> <code>InputIterator</code> is an input iterator.
<a href="http://www.sgi.com/tech/stl/InputIterator.html"> <code>value_type</code> is
<code>Input Iterator</code></a> over elements of type <code>EmplaceConstructible</code> into
<code>value_type</code> or a type convertible to <code>value_type</code>. <code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any <code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs. index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br> <code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> <b>Effects:</b>
<blockquote><pre> For each element of [<code>first</code>, <code>last</code>), in this
<span class=identifier>iterator</span> <span class=identifier>hint</span><span class=special>=</span><span class=identifier>end</span><span class=special>();</span> order, inserts it into the <code>multi_index_container</code>
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>hint</span><span class=special>=</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>hint</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span> to which this index belongs if
</pre></blockquote> <ul>
<b>Complexity:</b> <code>O(m*H(n+m))</code>, where <li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<b>Complexity:</b> <code>O(m*I(n+m))</code>, where
<code>m</code> is the number of elements in [<code>first</code>, <code>m</code> is the number of elements in [<code>first</code>,
<code>last</code>).<br> <code>last</code>).<br>
<b>Exception safety:</b> Basic.<br> <b>Exception safety:</b> Basic.<br>
</blockquote> </blockquote>
<code>void insert(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>())</span>
</pre></blockquote>
</blockquote>
<code>iterator erase(iterator position);</code> <code>iterator erase(iterator position);</code>
<blockquote> <blockquote>
@ -565,11 +658,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> <code>nothrow</code>.<br> <b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote> </blockquote>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a> <a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator <b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
of the index.<br> <code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed <b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if, for the value <code>x</code> the index belongs if, for the value <code>x</code>
@ -594,9 +690,8 @@ belongs remains in its original state.
<code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a> <code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
<blockquote> <blockquote>
<b>Requires:</b> <code>Modifier</code> is a model of <b>Requires:</b> <code>mod</code> is a unary function object
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br> iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element <b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
@ -610,8 +705,8 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
</ul> </ul>
If the rearrangement fails, the element is erased.<br> If the rearrangement fails, the element is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the <b>Postconditions:</b> Validity of <code>position</code> is preserved if the
operation succeeds. If the key of the modified value is equivalent to that of the original operation succeeds. If the key of the modified value is equivalent to that of the
value, the position of the element does not change.<br> original value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code> <b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br> otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br> <b>Complexity:</b> <code>O(M(n))</code>.<br>
@ -624,9 +719,8 @@ the element pointed to by <code>position</code> is erased.
bool modify(iterator position,Modifier mod,Rollback back);</code> bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of <b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> objects accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>, iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element <code>back(e)</code>, where <code>e</code> is the element
@ -644,8 +738,9 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
If the rearrangement fails, <code>back(e)</code> is invoked and the If the rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br> element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if <b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below. If the key of the modified value the element is erased under the conditions described below.
is equivalent to that of the original value, the position of the element does not change.<br> If the key of the modified value is equivalent to that of the
original value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code> <b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br> otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br> <b>Complexity:</b> <code>O(M(n))</code>.<br>
@ -662,9 +757,8 @@ is rethrown.
<blockquote> <blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write <b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a> <a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> is a model of from <code>value_type</code>. <code>mod</code> is a
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> unary function object accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br> iterator of the index.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod')</code>, <b>Effects:</b> Equivalent to <code>modify(position,mod')</code>,
@ -679,14 +773,13 @@ bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write <b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a> <a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> and <code>Rollback</code> from <code>value_type</code>. <code>mod</code> and <code>back</code>
are models of <a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> are unary function objects accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. iterator of the index.
The sequence of operations <code>mod(k)</code>, The sequence of operations <code>mod(k)</code>,
<code>back(k)</code>, where <code>k</code> is the key of the element <code>back(k)</code>, where <code>k</code> is the key of the element
pointed to by <code>position</code>, restores k to its original state.<br> pointed to by <code>position</code>, restores <code>k</code> to its original state.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>, <b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>,
with <code>mod'</code> and <code>back</code> defined in such a way that with <code>mod'</code> and <code>back</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and <code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
@ -713,7 +806,7 @@ the index.<br>
<p> <p>
Hashed indices provide the full lookup functionality required by Hashed indices provide the full lookup functionality required by
unordered associative containers, namely <code>find</code>, <b>[unord.req]</b>, namely <code>find</code>,
<code>count</code>, and <code>equal_range</code>. Additionally, <code>count</code>, and <code>equal_range</code>. Additionally,
these member functions are templatized to allow for non-standard these member functions are templatized to allow for non-standard
arguments, so extending the types of search operations allowed. arguments, so extending the types of search operations allowed.
@ -724,9 +817,8 @@ functions is defined by the following concept.
<p> <p>
Consider a pair (<code>Hash</code>, <code>Pred</code>) where Consider a pair (<code>Hash</code>, <code>Pred</code>) where
<code>Hash</code> is a hash functor over values of type <code>Key</code> <code>Hash</code> is a hash functor over values of type <code>Key</code>
and <code>Pred</code> is a and <code>Pred</code> is a binary predicate
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html"> inducing an equivalence relation
<code>Binary Predicate</code></a> inducing an equivalence relation
on <code>Key</code>, with the additional constraint that equivalent on <code>Key</code>, with the additional constraint that equivalent
keys have the same hash value. keys have the same hash value.
A triplet of types (<code>CompatibleKey</code>, <code>CompatibleHash</code>, A triplet of types (<code>CompatibleKey</code>, <code>CompatibleHash</code>,
@ -735,13 +827,9 @@ of (<code>Hash</code>, <code>Pred</code>) if
<ol> <ol>
<li><code>CompatibleHash</code> is a hash functor on values of <li><code>CompatibleHash</code> is a hash functor on values of
type <code>CompatibleKey</code>,</li> type <code>CompatibleKey</code>,</li>
<li><code>CompatiblePred</code> is a <li><code>CompatiblePred</code> is a binary predicate over (<code>Key</code>,
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> over (<code>Key</code>,
<code>CompatibleKey</code>),</li> <code>CompatibleKey</code>),</li>
<li><code>CompatiblePred</code> is a <li><code>CompatiblePred</code> is a binary predicate over (<code>CompatibleKey</code>,
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> over (<code>CompatibleKey</code>,
<code>Key</code>),</li> <code>Key</code>),</li>
<li>if <code>c_eq(ck,k1)</code> then <code>c_eq(k1,ck)</code>,</li> <li>if <code>c_eq(ck,k1)</code> then <code>c_eq(k1,ck)</code>,</li>
<li>if <code>c_eq(ck,k1)</code> and <code>eq(k1,k2)</code> then <li>if <code>c_eq(ck,k1)</code> and <code>eq(k1,k2)</code> then
@ -981,9 +1069,9 @@ Sequenced indices
<br> <br>
<p>Revised July 21st 2009</p> <p>Revised July 6th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -105,12 +105,13 @@ The last two primitives deserve some further explanation: in order to
guarantee the invariants associated to each index (e.g. some definite guarantee the invariants associated to each index (e.g. some definite
ordering,) elements of a <code>multi_index_container</code> are not mutable. ordering,) elements of a <code>multi_index_container</code> are not mutable.
To overcome this restriction, indices expose member functions To overcome this restriction, indices expose member functions
for updating and modifying, which allow for the mutation of elements for replacement and modification which allow for the mutation of elements
in a controlled fashion. Immutability of elements does not significantly in a controlled fashion. Immutability of elements does not significantly
impact the interface of ordered indices, as it is based upon that of impact the interfaces of ordered and hashed indices, as they are based upon
<code>std::set</code> and <code>std:multiset</code>, and these containers those of associative and unordered associative containers, respectively,
and these containers
also have non-mutable elements; but it may come as a surprise when dealing also have non-mutable elements; but it may come as a surprise when dealing
with sequenced indices, which are designed upon the functionality provided with sequenced and random access indices, which are designed upon the functionality provided
by <code>std::list</code>. by <code>std::list</code>.
</p> </p>
@ -120,11 +121,9 @@ they are wrapped as appropriate by each index (for instance, ordered indices
provide a set-like suite of insertion member functions, whereas sequenced provide a set-like suite of insertion member functions, whereas sequenced
and random access indices have <code>push_back</code> and <code>push_front</code> and random access indices have <code>push_back</code> and <code>push_front</code>
operations.) Boost.MultiIndex poses no particular conditions on operations.) Boost.MultiIndex poses no particular conditions on
the interface of indices, save that they must model the interface of indices, although each index provided satisfy the C++ requirements for
<a href="http://www.sgi.com/tech/stl/Container.html"> standard containers to the maximum extent possible within the conceptual framework
<code>Container</code></a> (without the requirement of being of the library.
<a href="http://www.sgi.com/tech/stl/Assignable.html">
<code>Assignable</code></a>.)
</p> </p>
<h2><a name="complexity_signature">Complexity signature</a></h2> <h2><a name="complexity_signature">Complexity signature</a></h2>
@ -333,10 +332,7 @@ reference</a>.
The following concept is used by the rearrange facilities of non key-based The following concept is used by the rearrange facilities of non key-based
indices. Given an index <code>i</code> of type <code>Index</code>, a <i>view indices. Given an index <code>i</code> of type <code>Index</code>, a <i>view
of <code>i</code></i> is any range [<code>first</code>,<code>last</code>) of <code>i</code></i> is any range [<code>first</code>,<code>last</code>)
where <code>first</code> and <code>last</code> are objects of a type where <code>first</code> and <code>last</code> are input iterators such that
<code>Iterator</code> modelling
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> such that
<ol> <ol>
<li>the associated value type of <code>Iterator</code> is convertible <li>the associated value type of <code>Iterator</code> is convertible
to <code>const Index::value_type&amp;</code> to <code>const Index::value_type&amp;</code>
@ -383,9 +379,9 @@ Ordered indices
<br> <br>
<p>Revised July 21st 2009</p> <p>Revised July 7th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -57,10 +57,8 @@ Compiler specifics
<ul> <ul>
<li><a href="#const_mem_fun">Class template <code>const_mem_fun</code></a></li> <li><a href="#const_mem_fun">Class template <code>const_mem_fun</code></a></li>
<li><a href="#mem_fun">Class template <code>mem_fun</code></a></li> <li><a href="#mem_fun">Class template <code>mem_fun</code></a></li>
<li><a href="#const_mem_fun_explicit">Class template <code>const_mem_fun_explicit</code></a></li> <li><a href="#const_mem_fun_explicit">Class templates <code>const_mem_fun_explicit</code> and <code>mem_fun_explicit</code></a></li>
<li><a href="#mem_fun_explicit">Class template <code>mem_fun_explicit</code></a></li> <li><a href="#boost_multi_index_const_mem_fun">Macros <code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code> and <code>BOOST_MULTI_INDEX_MEM_FUN</code></a></li>
<li><a href="#boost_multi_index_const_mem_fun">Macro <code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code></a></li>
<li><a href="#boost_multi_index_mem_fun">Macro <code>BOOST_MULTI_INDEX_MEM_FUN</code></a></li>
</ul> </ul>
</li> </li>
<li><a href="#global_fun_synopsis">Header <li><a href="#global_fun_synopsis">Header
@ -108,7 +106,7 @@ Compiler specifics
Key extraction classes are used by Key extraction classes are used by
<a href="indices.html#key_based_indices">key-based indices</a> to <a href="indices.html#key_based_indices">key-based indices</a> to
obtain the indexing keys from the elements of a <code>multi_index_container</code>. obtain the indexing keys from the elements of a <code>multi_index_container</code>.
An <a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a> A <code>CopyConstructible</code> and <code>CopyAssignable</code>
class <code>KeyFromValue</code> is said to be a key extractor from a class <code>KeyFromValue</code> is said to be a key extractor from a
type <code>Type</code> if type <code>Type</code> if
<ol> <ol>
@ -144,16 +142,8 @@ Boost.MultiIndex provides six general-purpose key extractors:
<li><a href="#const_mem_fun"><code>const_mem_fun</code></a>,</li> <li><a href="#const_mem_fun"><code>const_mem_fun</code></a>,</li>
<li><a href="#mem_fun"><code>mem_fun</code></a>,</li> <li><a href="#mem_fun"><code>mem_fun</code></a>,</li>
<li><a href="#global_fun"><code>global_fun</code></a> and</li> <li><a href="#global_fun"><code>global_fun</code></a> and</li>
<li><a href="#composite_key"><code>composite_key</code></a>,</li> <li><a href="#composite_key"><code>composite_key</code></a>.</li>
</ul> </ul>
plus replacements for some of them:
<ul>
<li><a href="#member_offset"><code>member_offset</code></a>,</li>
<li><a href="#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a> and</li>
<li><a href="#mem_fun_explicit"><code>mem_fun_explicit</code></a>,</li>
</ul>
that workaround some deficiencies in the support for non-type template parameters
by certain compilers.
</p> </p>
<h3><a name="chained_pointers">Chained pointers</a></h3> <h3><a name="chained_pointers">Chained pointers</a></h3>
@ -310,7 +300,7 @@ type to <code>Type</code>.<br>
<span class=keyword>struct</span> <span class=identifier>member</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>member</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>OffsetOfMember</span><span class=special>&gt;</span> <span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>OffsetOfMember</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>member_offset</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>member_offset</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_MEMBER</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberName</span><span class=special>)</span> <b>implementation defined</b> <span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_MEMBER</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberName</span><span class=special>)</span> <b>implementation defined</b>
@ -399,53 +389,10 @@ type to <code>Type</code>.<br>
<h3><a name="member_offset">Class template <code>member_offset</code></a></h3> <h3><a name="member_offset">Class template <code>member_offset</code></a></h3>
<p> <p>
Some compilers do not properly support pointers to members as non-type <code>member_offset</code> was designed to overcome limitations of some legacy
template arguments. The following have been confirmed to have bugs in compilers and its use is currently deprecated. Refer to a
this respect: <a href="http://www.boost.org/doc/libs/1_54_0/libs/multi_index/doc/reference/key_extraction.html#member_offset">former version</a>
<ul> of Boost.MultiIndex for further information.
<li>MSVC++ 6.0 (see
<a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045">Microsoft
Knowledge Base article #249045</a>),</li>
<li>MSVC++ 7.0 (not officially confirmed by Microsoft),</li>
<li>Intel C++ 7.0/7.1 for Windows (support issue #207321),</li>
<li>VisualAge 6.0 for AIX (internal defect #288539.)</li>
</ul>
In this situation, <code>member_offset</code> provides an
alternative to <a href="#member"><code>member</code></a> accepting offsets
instead of pointers to members. Please note that the use of
<code>offsetof</code> on non-POD types is forbidden by the standard;
luckily enough, most compilers accept it nevertheless, so
<code>member_offset</code> serves as a workaround for most practical purposes.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>OffsetOfMember</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>member_offset</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>Type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if const ChainedPtr&amp; is not convertible to const Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</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>const</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</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=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Class</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>// only provided if Type is non-const</span>
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>As an example of use, given the class</p>
<blockquote><pre>
<span class=keyword>class</span> <span class=identifier>A</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
the instantiation <code>member&lt;A,int,&amp;A::x></code> can be simulated then
as <code>member_offset&lt;A,int,offsetof(A,x)></code>.
</p> </p>
<h3><a name="boost_multi_index_member">Macro <code>BOOST_MULTI_INDEX_MEMBER</code></a></h3> <h3><a name="boost_multi_index_member">Macro <code>BOOST_MULTI_INDEX_MEMBER</code></a></h3>
@ -455,27 +402,10 @@ as <code>member_offset&lt;A,int,offsetof(A,x)></code>.
</pre></blockquote> </pre></blockquote>
<p> <p>
This macro is provided as an aid for using <code>member</code> and This macro was designed as a portability mechanism for legacy compilers where <code>member</code>
<code>member_offset</code> when writing cross-platform code. In the usual cases, could not be supported.
it expands to As such it is no longer needed in modern environments, though some users might still prefer it
</p> to plain <code>member</code> because it provides a slightly more concise syntax.
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberName</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
but it resolves to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member_offset</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>offsetof</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>MemberName</span><span class=special>)&gt;</span>
</pre></blockquote>
<p>
if the <a href="../../../../libs/config/config.htm">Boost Configuration Library</a>
defect macro <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code>
is defined.
</p> </p>
<h2> <h2>
@ -498,13 +428,13 @@ is defined.
<span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span> <span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span> <span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span>
<span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>const_mem_fun_explicit</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>const_mem_fun_explicit</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span> <span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span> <span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span>
<span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>mem_fun_explicit</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>mem_fun_explicit</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span> <span class=special>\</span> <span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span> <span class=special>\</span>
<b>implementation defined</b> <b>implementation defined</b>
@ -646,135 +576,28 @@ object chained-pointed to by <code>x</code>.
<b>Returns:</b> <code>(x.get().*PtrToMemberFunction)()</code>. <b>Returns:</b> <code>(x.get().*PtrToMemberFunction)()</code>.
</blockquote> </blockquote>
<h3><a name="const_mem_fun_explicit">Class template <code>const_mem_fun_explicit</code></a></h3> <h3><a name="const_mem_fun_explicit">Class templates <code>const_mem_fun_explicit</code> and <code>mem_fun_explicit</code></a></h3>
<p> <p>
MSVC++ 6.0 do not properly support pointers to constant member functions as non-type These extractors were provided as a workaround for MSVC++ 6.0 and are now deprecated.
template parameters, thus <a href="#const_mem_fun"><code>const_mem_fun</code></a> cannot be Refer to a
used in this compiler. A simple workaround consists in specifying the <i>type</i> of <a href="http://www.boost.org/doc/libs/1_54_0/libs/multi_index/doc/reference/key_extraction.html#const_mem_fun_explicit">former version</a>
these pointers as an additional template parameter. of Boost.MultiIndex for further information.
</p> </p>
<blockquote><pre> <h3><a name="boost_multi_index_const_mem_fun">Macros
<span class=keyword>template</span><span class=special>&lt;</span> <code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code>
<span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span> and <code>BOOST_MULTI_INDEX_MEM_FUN</code></a></h3>
<span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>const_mem_fun_explicit</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if const ChainedPtr&amp; is not convertible to const Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</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=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</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=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>const_mem_fun_explicit</code> provides the very same functionality as
its <code>const_mem_fun</code> analogous instantiation. For example, given the type
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>A</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>f</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
the extractor <code>const_mem_fun&lt;A,int,&amp;A::f></code> can be replaced by
<code>const_mem_fun_explicit&lt;A,int,int (A::*)()const,&amp;A::f></code>.
</p>
<h3><a name="mem_fun_explicit">Class template <code>mem_fun_explicit</code></a></h3>
<p>
For analogy with <a href="#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>,
a variation of <a href="#mem_fun"><code>mem_fun</code></a> is provided accepting
an additional parameter with the type of the pointer to non-constant member function
used for extraction.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>mem_fun_explicit</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if ChainedPtr&amp; is not convertible to Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</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=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Class</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=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<h3><a name="boost_multi_index_const_mem_fun">Macro
<code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code></a></h3>
<blockquote><pre> <blockquote><pre>
<span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span> <span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span>
</pre></blockquote>
<p>
Use this macro when writing cross-platform code selectively using
<code>const_mem_fun_explicit</code> in place of <code>const_mem_fun</code> for
compilers not supporting the latter. In the usual cases, the macro expands to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>const_mem_fun</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberFunName</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
but it resolves to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>const_mem_fun_explicit</span><span class=special>&lt;</span>
<span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>Type</span> <span class=special>(</span><span class=identifier>Class</span><span class=special>::*)()</span><span class=keyword>const</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberFunName</span>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
for MSVC++ 6.0 or lower.
</p>
<h3><a name="boost_multi_index_mem_fun">Macro
<code>BOOST_MULTI_INDEX_MEM_FUN</code></a></h3>
<blockquote><pre>
<span class=identifier>BOOST_MULTI_INDEX_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span> <span class=identifier>BOOST_MULTI_INDEX_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span>
</pre></blockquote> </pre></blockquote>
<p> <p>
By default, the macro expands to Portability macros for usage of <code>const_mem_fun</code> and <code>mem_fun</code>.
</p> Although no longer needed in modern compilers, some users might still decide to
resort to them as they provide a slightly more concise syntax.
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>mem_fun</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberFunName</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
but it resolves to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>mem_fun_explicit</span><span class=special>&lt;</span>
<span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>Type</span> <span class=special>(</span><span class=identifier>Class</span><span class=special>::*)()</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberFunName</span>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
for MSVC++ 6.0 or lower.
</p> </p>
<h2> <h2>
@ -959,7 +782,7 @@ Type operator()(<br>
<span class=keyword>struct</span> <span class=identifier>composite_key_equal_to</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>composite_key_equal_to</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span> <span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_equal_to</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>composite_key_result_equal_to</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=comment>// comparison functors:</span> <span class=comment>// comparison functors:</span>
@ -967,10 +790,10 @@ Type operator()(<br>
<span class=keyword>struct</span> <span class=identifier>composite_key_compare</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>composite_key_compare</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span> <span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_less</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>composite_key_result_less</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span> <span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_greater</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>composite_key_result_greater</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=comment>// hash functors:</span> <span class=comment>// hash functors:</span>
@ -978,7 +801,7 @@ Type operator()(<br>
<span class=keyword>struct</span> <span class=identifier>composite_key_hash</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>composite_key_hash</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span> <span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_hash</span><span class=special>;</span> <span class=keyword>struct</span> <span class=identifier>composite_key_result_hash</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span> <span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
@ -1176,10 +999,8 @@ instantiations as their extracted key.
which the <code>composite_key_result</code> type is associated. Objects of type which the <code>composite_key_result</code> type is associated. Objects of type
<code>composite_key_result</code> returned by a composite key must be always treated <code>composite_key_result</code> returned by a composite key must be always treated
as <i>temporary</i>, i.e. they should not be stored or copied. as <i>temporary</i>, i.e. they should not be stored or copied.
<code>composite_key_result</code> is <i>not</i> guaranteed to be a model of <code>composite_key_result</code> is <i>not</i> guaranteed to be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"> <code>DefaultConstructible</code> or <code>CopyAssignable</code>.
<code>Default Constructible</code></a> or
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
Every object of type <code>composite_key_result&lt;CompositeKey></code> is Every object of type <code>composite_key_result&lt;CompositeKey></code> is
internally associated to the <code>CompositeKey</code> from which it is returned internally associated to the <code>CompositeKey</code> from which it is returned
and the object of type <code>CompositeKey::value_type</code> to which the and the object of type <code>CompositeKey::value_type</code> to which the
@ -1351,19 +1172,14 @@ collection of elementary equality predicates.
<p> <p>
<code>Pred0</code>, ... , <code>Predn</code> are the types of the equality <code>Pred0</code>, ... , <code>Predn</code> are the types of the equality
predicates stored by <code>composite_key_equal_to</code>. Each of these types binary predicates stored by <code>composite_key_equal_to</code>. Each of these predicates
must be a <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html"> must be <code>CopyConstructible</code> and <code>CopyAssignable</code>. At least an
<code>Binary Predicate</code></a>. At least an
equality predicate must be provided. The maximum number of equality predicates of equality predicate must be provided. The maximum number of equality predicates of
a <code>composite_key_equal_to</code> instantiation is implementation defined. a <code>composite_key_equal_to</code> instantiation is implementation defined.
<code>composite_key_equal_to</code> is <code>composite_key_equal_to</code> is
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>. <code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also It is also <code>DefaultConstructible</code>
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"> if each <code>Predi</code> is <code>DefaultConstructible</code> in its turn.
<code>Default Constructible</code></a>
if each <code>Predi</code> is
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>.
</p> </p>
<p> <p>
@ -1451,66 +1267,18 @@ the result is determined to be <code>false</code>.
<code>composite_key_result_equal_to</code></a></h4> <code>composite_key_result_equal_to</code></a></h4>
<p> <p>
<code>composite_key_result_equal_to</code> acts as a particularization of Deprecated. Use <code>std::equal_to&lt;CompositeKeyResult&gt;</code> instead.
<code>composite_key_equal_to</code> where all the comparison predicates supplied
are instantiations of <code>std::equal_to</code>.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_equal_to</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>CompositeKeyResult</span> <span class=identifier>first_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>first_argument_type</span> <span class=identifier>second_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>bool</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey1</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey2</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>composite_key_result_equal_to&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_equal_to&lt;Pred0,...,Predn>::operator()</code>, taking
<blockquote>
<code>Predi = std::equal_to&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Predi</code> imposed by
<code>composite_key_equal_to</code>, each of these types must be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>. <code>composite_key_result_equal_to</code>
is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> and
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
</p> </p>
<h4><a name="equal_to_composite_key_result">Specialization of <h4><a name="equal_to_composite_key_result">Specialization of
<code>std::equal_to</code> for <code>composite_key</code> results</a></h4> <code>std::equal_to</code> for <code>composite_key</code> results</a></h4>
<p> <p>
<code>std::equal_to&lt;CompositeKeyResult></code>, for <code>CompositeKeyResult</code> <code>std::equal_to&lt;CompositeKeyResult></code>, with <code>CompositeKeyResult</code>
being an instantiation of <code>composite_key_result</code>, has the same interface an instantiation of <code>composite_key_result</code>,
and functionality as <code>composite_key_result_equal_to&lt;CompositeKeyResult></code>. behaves as a particularization of
<code>composite_key_equal_to</code> where all the comparison predicates supplied
are instantiations of <code>std::equal_to</code>.
</p> </p>
<blockquote><pre> <blockquote><pre>
@ -1544,6 +1312,27 @@ and functionality as <code>composite_key_result_equal_to&lt;CompositeKeyResult><
<span class=special>}</span> <span class=comment>// namespace std</span> <span class=special>}</span> <span class=comment>// namespace std</span>
</pre></blockquote> </pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>std::equal:to&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_equal_to&lt;Pred0,...,Predn>::operator()</code>, taking
<blockquote>
<code>Predi = std::equal_to&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Predi</code> imposed by
<code>composite_key_equal_to</code>, each of these types must be
<code>DefaultConstructible</code>. <code>std::equal_to&lt;CompositeKeyResult></code>
is <code>DefaultConstructible</code>, <code>CopyConstructible</code> and
<code>CopyAssignable</code>.
</p>
<h3><a name="ckey_result_comparison">Comparison</a></h3> <h3><a name="ckey_result_comparison">Comparison</a></h3>
<h4><a name="composite_key_compare">Class template <h4><a name="composite_key_compare">Class template
@ -1598,19 +1387,15 @@ collection of elementary comparison predicates.
<p> <p>
<code>Compare0</code>, ... , <code>Comparen</code> are the types of the comparison <code>Compare0</code>, ... , <code>Comparen</code> are the types of the comparison
predicates stored by <code>composite_key_compare</code>. Each of these types binary predicates stored by <code>composite_key_compare</code>. Each of these predicates must be
must be a <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html"> <code>CopyConstructible</code> and <code>CopyAssignable</code>. At least a
<code>Binary Predicate</code></a>. At least a
comparison predicate must be provided. The maximum number of comparison predicates of comparison predicate must be provided. The maximum number of comparison predicates of
a <code>composite_key_compare</code> instantiation is implementation defined. a <code>composite_key_compare</code> instantiation is implementation defined.
<code>composite_key_compare</code> is <code>composite_key_compare</code> is
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>. <code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also It is also
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"> <code>DefaultConstructible</code>
<code>Default Constructible</code></a> if each <code>Comparei</code> is <code>DefaultConstructible</code> in its turn.
if each <code>Comparei</code> is
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>.
</p> </p>
<p> <p>
@ -1728,139 +1513,24 @@ bool operator()(<br>
<code>composite_key_result_less</code></a></h4> <code>composite_key_result_less</code></a></h4>
<p> <p>
<code>composite_key_result_less</code> acts as a particularization of Deprecated. Use <code>std::less&lt;CompositeKeyResult&gt;</code> instead.
<code>composite_key_compare</code> where all the comparison predicates supplied
are instantiations of <code>std::less</code>.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_less</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>CompositeKeyResult</span> <span class=identifier>first_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>first_argument_type</span> <span class=identifier>second_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>bool</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey1</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey2</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>y</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>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>composite_key_result_less&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_compare&lt;Compare0,...,Comparen>::operator()</code>, taking
<blockquote>
<code>Comparei = std::less&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Comparei</code> imposed by
<code>composite_key_compare</code>, each of these types must be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>. <code>composite_key_result_less</code>
is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> and
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
</p> </p>
<h4><a name="composite_key_result_greater">Class template <h4><a name="composite_key_result_greater">Class template
<code>composite_key_result_greater</code></a></h4> <code>composite_key_result_greater</code></a></h4>
<p> <p>
<code>composite_key_result</code> acts as a particularization of Deprecated. Use <code>std::greater&lt;CompositeKeyResult&gt;</code> instead.
<code>composite_key_compare</code> where all the comparison predicates supplied
are instantiations of <code>std::greater</code>.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_greater</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>CompositeKeyResult</span> <span class=identifier>first_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>first_argument_type</span> <span class=identifier>second_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>bool</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey1</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey2</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</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>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>y</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>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>composite_key_result_greater&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_compare&lt;Compare0,...,Comparen>::operator()</code>, taking
<blockquote>
<code>Comparei = std::greater&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Comparei</code> imposed by
<code>composite_key_compare</code>, each of these types must be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>. <code>composite_key_result_greater</code>
is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> and
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
</p> </p>
<h4><a name="less_composite_key_result">Specialization of <code>std::less</code> for <h4><a name="less_composite_key_result">Specialization of <code>std::less</code> for
<code>composite_key</code> results</a></h4> <code>composite_key</code> results</a></h4>
<p> <p>
<code>std::less&lt;CompositeKeyResult></code>, for <code>CompositeKeyResult</code> <code>std::less&lt;CompositeKeyResult></code>, with <code>CompositeKeyResult</code>
being an instantiation of <code>composite_key_result</code>, has the same interface an instantiation of <code>composite_key_result</code>, behaves as a particularization of
and functionality as <code>composite_key_result_less&lt;CompositeKeyResult></code>. <code>composite_key_compare</code> where all the comparison predicates supplied are
instantiations of <code>std::less</code>.
</p> </p>
<blockquote><pre> <blockquote><pre>
@ -1904,15 +1574,38 @@ and functionality as <code>composite_key_result_less&lt;CompositeKeyResult></cod
<span class=special>}</span> <span class=comment>// namespace std</span> <span class=special>}</span> <span class=comment>// namespace std</span>
</pre></blockquote> </pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>std::less&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_compare&lt;Compare0,...,Comparen>::operator()</code>, taking
<blockquote>
<code>Comparei = std::less&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Comparei</code> imposed by
<code>composite_key_compare</code>, each of these types must be
<code>DefaultConstructible</code>. <code>std::less&lt;CompositeKeyResult></code>
is <code>CopyConstructible</code>, <code>CopyConstructible</code>
and <code>CopyAssignable</code>.
</p>
<h4><a name="greater_composite_key_result">Specialization of <code>std::greater</code> for <h4><a name="greater_composite_key_result">Specialization of <code>std::greater</code> for
<code>composite_key</code> results</a></h4> <code>composite_key</code> results</a></h4>
<p> <p>
<code>std::greater&lt;CompositeKeyResult></code>, for <code>CompositeKeyResult</code> <code>std::greater&lt;CompositeKeyResult></code>, with <code>CompositeKeyResult</code>
being an instantiation of <code>composite_key_result</code>, has the same interface an instantiation of <code>composite_key_result</code>, behaves as a particularization of
and functionality as <code>composite_key_result_greater&lt;CompositeKeyResult></code>. <code>composite_key_compare</code> where all the comparison predicates supplied
are instantiations of <code>std::greater</code>.
</p> </p>
<blockquote><pre> <blockquote><pre>
<span class=keyword>namespace</span> <span class=identifier>std</span><span class=special>{</span> <span class=keyword>namespace</span> <span class=identifier>std</span><span class=special>{</span>
@ -1954,6 +1647,27 @@ and functionality as <code>composite_key_result_greater&lt;CompositeKeyResult></
<span class=special>}</span> <span class=comment>// namespace std</span> <span class=special>}</span> <span class=comment>// namespace std</span>
</pre></blockquote> </pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>std::greater&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_compare&lt;Compare0,...,Comparen>::operator()</code>, taking
<blockquote>
<code>Comparei = std::greater&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Comparei</code> imposed by
<code>composite_key_compare</code>, each of these types must be
<code>DefaultConstructible</code>. <code>std::greater&lt;CompositeKeyResult></code>
is <code>CopyConstructible</code>, <code>CopyConstructible</code>
and <code>CopyAssignable</code>.
</p>
<h3><a name="ckey_result_hashing">Hashing</a></h3> <h3><a name="ckey_result_hashing">Hashing</a></h3>
<h4><a name="composite_key_hash">Class template <h4><a name="composite_key_hash">Class template
@ -1991,23 +1705,17 @@ instantiations based on a collection of elementary hash functors.
</pre></blockquote> </pre></blockquote>
<p> <p>
<code>Hash0</code>, ... , <code>Hashn</code> are the types of the hash functors <code>Hash0</code>, ... , <code>Hashn</code> are the types of the hash unary function objects
stored by <code>composite_key_hash</code>. Each of these types stored by <code>composite_key_hash</code>. Each of these objects
must be a must be <code>CopyConstructible</code> and <code>CopyAssignable</code>
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"><code>Unary Function</code></a> and return a value of type <code>std::size_t</code> in the range
returning a value of type <code>std::size_t</code> in the range [0, <code>std::numeric_limits&lt;std::size_t&gt;::max())</code>).
<code>[0, std::numeric_limits&lt;std::size_t&gt;::max())</code>. At least a hash functor must be provided. The maximum number of hash functors of
At least a
hash functor must be provided. The maximum number of hash functors of
a <code>composite_key_hash</code> instantiation is implementation defined. a <code>composite_key_hash</code> instantiation is implementation defined.
<code>composite_key_hash</code> is <code>composite_key_hash</code> is
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>. <code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also It is also <code>DefaultConstructible</code>
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"> if each <code>Hashi</code> is <code>DefaultConstructible</code> in its turn.
<code>Default Constructible</code></a>
if each <code>Hashi</code> is
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>.
</p> </p>
<h4>Notation</h4> <h4>Notation</h4>
@ -2081,50 +1789,7 @@ with <code>N=length(x)-1</code>.
<code>composite_key_result_hash</code></a></h4> <code>composite_key_result_hash</code></a></h4>
<p> <p>
<code>composite_key_result_hash</code> acts as a particularization of Deprecated. Use <code>boost::hash&lt;CompositeKeyResult&gt;</code> instead.
<code>composite_key_hash</code> where all the hash functors supplied
are instantiations of
<a href="../../../functional/hash/index.html"><code>boost::hash</code></a>.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_hash</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>CompositeKeyResult</span> <span class=identifier>argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;</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>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>composite_key_result_hash&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_hash&lt;Hash0,...,Hashn>::operator()</code>, taking
<blockquote>
<code>Hashi = boost::hash&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Hashi</code> imposed by
<code>composite_key_hash</code>, each of these types must be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>. <code>composite_key_result_hash</code>
is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> and
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
</p> </p>
<h4><a name="hash_composite_key_result">Specialization of <h4><a name="hash_composite_key_result">Specialization of
@ -2132,9 +1797,11 @@ is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
for <code>composite_key</code> results</a></h4> for <code>composite_key</code> results</a></h4>
<p> <p>
<code>boost::hash&lt;CompositeKeyResult></code>, for <code>CompositeKeyResult</code> <code>boost::hash&lt;CompositeKeyResult></code>, with <code>CompositeKeyResult</code>
being an instantiation of <code>composite_key_result</code>, has the same interface an instantiation of <code>composite_key_result</code>, behaves as a particularization of
and functionality as <code>composite_key_result_hash&lt;CompositeKeyResult></code>. <code>composite_key_hash</code> where all the hash functors supplied
are instantiations of
<a href="../../../functional/hash/index.html"><code>boost::hash</code></a>.
</p> </p>
<blockquote><pre> <blockquote><pre>
@ -2158,6 +1825,27 @@ and functionality as <code>composite_key_result_hash&lt;CompositeKeyResult></cod
<span class=special>}</span> <span class=comment>// namespace boost</span> <span class=special>}</span> <span class=comment>// namespace boost</span>
</pre></blockquote> </pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>boost::hash&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_hash&lt;Hash0,...,Hashn>::operator()</code>, taking
<blockquote>
<code>Hashi = boost::hash&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Hashi</code> imposed by
<code>composite_key_hash</code>, each of these types must be
<code>DefaultConstructible</code>. <code>boost::hash&lt;CompositeKeyResult></code> is
<code>DefaultConstructible</code>, <code>CopyConstructible</code>
and <code>CopyAssignable</code>.
</p>
<h3><a name="ckey_result_semantics">Semantics of <h3><a name="ckey_result_semantics">Semantics of
<code>composite_key_result</code></a></h3> <code>composite_key_result</code></a></h3>
@ -2204,13 +1892,10 @@ of (<code>Hashi</code>, <code>Predi</code>).</p>
<p> <p>
As for comparison, consider an instantiation of <code>composite_key_compare</code> As for comparison, consider an instantiation of <code>composite_key_compare</code>
with types <code>Compare0</code>, ... , <code>Comparen</code> such that each with types <code>Compare0</code>, ... , <code>Comparen</code> such that each
<code>Comparei</code> is a <code>Comparei</code> induces a strict weak ordering
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"><code>Strict on the type <code>Ti</code>. Then, for a
Weak Ordering</code></a> on the type <code>Ti</code>. Then, for a
<code>CompositeKey</code> type defined in the same manner as above, <code>CompositeKey</code> type defined in the same manner as above,
<code>composite_key_compare</code> is a <code>composite_key_compare</code> induces a strict weak ordering on elements of type
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"><code>Strict
Weak Ordering</code></a> on elements of type
<code>composite_key_result&lt;CompositeKey></code>, and the order induced <code>composite_key_result&lt;CompositeKey></code>, and the order induced
is lexicographical. Also, the following types are is lexicographical. Also, the following types are
<a href="ord_indices.html#set_operations"><code>Compatible Keys</code></a> of <a href="ord_indices.html#set_operations"><code>Compatible Keys</code></a> of
@ -2263,9 +1948,9 @@ Compiler specifics
<br> <br>
<p>Revised June 25th 2008</p> <p>Revised July 7th 2013</p>
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -88,6 +88,8 @@ synopsis</a>
</h2> </h2>
<blockquote><pre> <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>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span> <span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -269,7 +271,6 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>struct</span> <span class=identifier>nth_index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span> <span class=keyword>struct</span> <span class=identifier>nth_index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span> <span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span> <span class=keyword>struct</span> <span class=identifier>index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span> <span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
@ -295,13 +296,23 @@ operators and functions associated with the index (vg. comparison and
<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=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>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(), <span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span> </span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
<span class=identifier>multi_index_container</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</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
<span class=identifier>multi_index_container</span><span class=special>(</span> <span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span> <span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=special>~</span><span class=identifier>multi_index_container</span><span class=special>();</span> <span class=special>~</span><span class=identifier>multi_index_container</span><span class=special>();</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span> <span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&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</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=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=special>;</span>
@ -507,9 +518,8 @@ scheme outlined in the
<p> <p>
<code>multi_index_container</code> is instantiated with the following types: <code>multi_index_container</code> is instantiated with the following types:
<ol> <ol>
<li><code>Value</code> is the <li><code>Value</code> is the type of the elements contained. <code>Value</code> must be
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a> <code>Erasable</code> from <code>multi_index_container</code>.
type of the elements contained.
</li> </li>
<li><code>IndexSpecifierList</code> specifies the indices that the <li><code>IndexSpecifierList</code> specifies the indices that the
<code>multi_index_container</code> is composed of. It must be a non-empty <code>multi_index_container</code> is composed of. It must be a non-empty
@ -522,17 +532,15 @@ scheme outlined in the
MPL sequence can be used. MPL sequence can be used.
</li> </li>
<li><code>Allocator</code> must be an allocator of <code>Value</code> objects <li><code>Allocator</code> must be an allocator of <code>Value</code> objects
satisfying the associated C++ requirements at <b>[lib.allocator.requirements]</b>. satisfying the associated C++ requirements at <b>[allocator.requirements]</b>.
The following relaxations to the standard requirements are allowed: The following relaxations to the standard requirements are allowed:
<ul> <ul>
<li>Non-equal allocator instances are supported: swapping two non-equal <li>Non-equal allocator instances are supported: swapping two non-equal
instances must not throw any exception. instances must not throw any exception.
</li> </li>s
<li>For every type <code>T</code>, <li>For every type <code>T</code>,
the type <code>Allocator::rebind&lt;T&gt;::other::pointer</code> can be any the type <code>Allocator::rebind&lt;T&gt;::other::pointer</code> can be any
kind of kind of random access iterator, provided that it is explicitly constructible from
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html"><code>Random
Access Iterator</code></a>, provided that it is explicitly constructible from
the literal <code>0</code> (standing here as the null pointer) or from any the literal <code>0</code> (standing here as the null pointer) or from any
<code>p</code> of type <code>T*</code> pointing into an area allocated by <code>p</code> of type <code>T*</code> pointing into an area allocated by
some instance of <code>Allocator</code> or some other allocator type rebound some instance of <code>Allocator</code> or some other allocator type rebound
@ -564,9 +572,8 @@ implicit conversion from
to <code>const ctor_args_list&amp;</code>. This type is used for to <code>const ctor_args_list&amp;</code>. This type is used for
providing the construction arguments of the indices of the providing the construction arguments of the indices of the
<code>multi_index_container</code>. <code>ctor_args_list</code> is <code>multi_index_container</code>. <code>ctor_args_list</code> is
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"><code>Default <code>DefaultConstructible</code>, provided that all <code>ctor_args</code> types
Constructible</code></a>, provided that all <code>ctor_args</code> types involved are <code>DefaultConstructible</code>.
involved are default constructible.
</blockquote> </blockquote>
<code>index_specifier_type_list</code> <code>index_specifier_type_list</code>
@ -685,14 +692,14 @@ specified allocator and the default value of <code>ctor_args_list</code>.<br>
<code>template&lt;typename InputIterator><br> <code>template&lt;typename InputIterator><br>
multi_index_container(<br> multi_index_container(<br>
&nbsp;&nbsp;InputIterator first,InputIterator last,<br> &nbsp;&nbsp;InputIterator first,InputIterator last,<br>
&nbsp;&nbsp;const ctor_args_list&amp; comp=ctor_args_list(),<br> &nbsp;&nbsp;const ctor_args_list&amp; args_list=ctor_args_list(),<br>
&nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code> &nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of <b>Requires:</b> <code>InputIterator</code> is an input iterator.
<a href="http://www.sgi.com/tech/stl/InputIterator.html"> <code>Value</code> is
<code>Input Iterator</code></a> over elements of type <code>EmplaceConstructible</code> into <code>multi_index_container</code>
<code>Value</code> or a type convertible to <code>Value</code>. from <code>*first</code>.
<code>last</code> is reachable from <code>first</code>.<br> <code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> Constructs and empty <code>multi_index_container</code> using the <b>Effects:</b> Constructs and empty <code>multi_index_container</code> using the
specified argument list and allocator and fills it with specified argument list and allocator and fills it with
@ -703,18 +710,43 @@ on the acceptance by all the indices of the <code>multi_index_container</code>.<
the number of elements in [<code>first</code>,<code>last</code>).<br> the number of elements in [<code>first</code>,<code>last</code>).<br>
</blockquote> </blockquote>
<code>multi_index_container(<br>
&nbsp;&nbsp;std::initializer_list&lt;Value&gt; list,<br>
&nbsp;&nbsp;const ctor_args_list&amp; args_list=ctor_args_list(),<br>
&nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code>
<blockquote>
<b>Effects:</b> Equivalent to
<code>multi_index_container(list.begin(),list.end(),args_list,al)</code>.
</blockquote>
<code>multi_index_container(<br> <code>multi_index_container(<br>
&nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x);</code> &nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Constructs a copy of <code>x</code>, copying its <b>Effects:</b> Constructs a copy of <code>x</code>, copying its
elements as well as its internal objects (key extractors, comparison objects, elements as well as its internal objects (those specified
allocator.)<br> in <code>ctor_args_list</code> and the allocator.)<br>
<b>Postconditions:</b> <code>*this==x</code>. The order on every index <b>Postconditions:</b> <code>*this==x</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br> of the <code>multi_index_container</code> is preserved as well.<br>
<b>Complexity:</b> <code>O(x.size()*log(x.size()) + C(x.size()))</code>. <b>Complexity:</b> <code>O(x.size()*log(x.size()) + C(x.size()))</code>.
</blockquote> </blockquote>
<code>multi_index_container(<br>
&nbsp;&nbsp;multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b> Constructs a <code>multi_index_container</code> by moving the
elements of <code>x</code> and copying its internal objects (those specified
in <code>ctor_args_list</code> and the allocator.)<br>
<b>Postconditions:</b> If <code>x==y</code> just
before the movement, <code>*this==y</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
<b>Complexity:</b> Constant.
</blockquote>
<code>~multi_index_container()</code> <code>~multi_index_container()</code>
<blockquote> <blockquote>
<b>Effects:</b> Destroys the <code>multi_index_container</code> and all the elements <b>Effects:</b> Destroys the <code>multi_index_container</code> and all the elements
@ -726,7 +758,9 @@ contained. The order in which the elements are destroyed is not specified.<br>
&nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x);</code> &nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x);</code>
<blockquote> <blockquote>
Replaces the elements and internal objects of the <code>multi_index_container</code> <b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Replaces the elements and internal objects of the <code>multi_index_container</code>
with copies from <code>x</code>.<br> with copies from <code>x</code>.<br>
<b>Postconditions:</b> <code>*this==x</code>. The order on every index <b>Postconditions:</b> <code>*this==x</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br> of the <code>multi_index_container</code> is preserved as well.<br>
@ -737,6 +771,39 @@ C(x.size()))</code>.<br>
of the types of <code>ctor_args_list</code> do not throw. of the types of <code>ctor_args_list</code> do not throw.
</blockquote> </blockquote>
<code>multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; operator=(<br>
&nbsp;&nbsp;multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b> Replaces the elements of <code>multi_index_container</code>
with those of <code>x</code> and its internal objects with copies from the
corresponding objects in <code>x</code>.<br>
<b>Postconditions:</b> If <code>x==y</code> just
before the movement, <code>*this==y</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
<b>Returns:</b> <code>*this</code>.<br>
<b>Complexity:</b> <code>O(n)</code>.<br>
<b>Exception safety:</b> Strong, provided the copy and assignment operations
of the types of <code>ctor_args_list</code> do not throw.
</blockquote>
<code>multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; operator=(<br>
&nbsp;&nbsp;std::initializer_list&lt;Value&gt; list);</code>
<blockquote>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Replaces the elements the <code>multi_index_container</code>
with copies of the elements of <code>list</code>, inserted in the specified order.
Insertion of each element may or may not succeed depending
on the acceptance by all the indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> <code>*this</code>.<br>
<b>Complexity:</b> <code>O(n + I(m))</code>, where <code>m</code> is the
number of elements of <code>list</code>.<br>
<b>Exception safety:</b> Strong, provided the copy and assignment operations
of the types of <code>ctor_args_list</code> do not throw.
</blockquote>
<code>allocator_type get_allocator()const;</code> <code>allocator_type get_allocator()const;</code>
<blockquote> <blockquote>
@ -883,8 +950,7 @@ these, the following concepts are used. A type <code>T</code> is <i>serializable
archive (XML archive) and later retrieved from an input archive (XML archive) associated to archive (XML archive) and later retrieved from an input archive (XML archive) associated to
the same storage. If <code>x'</code> of type <code>T</code> is loaded from the the same storage. If <code>x'</code> of type <code>T</code> is loaded from the
serialization information saved from another object <code>x</code>, we say that serialization information saved from another object <code>x</code>, we say that
<code>x'</code> is a <i>restored copy</i> of <code>x</code>. Given a <code>x'</code> is a <i>restored copy</i> of <code>x</code>. Given a binary predicate
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html"><code>Binary Predicate</code></a>
<code>Pred</code> over (<code>T</code>, <code>T</code>), and objects <code>p</code> <code>Pred</code> over (<code>T</code>, <code>T</code>), and objects <code>p</code>
and <code>q</code> of type <code>Pred</code>, we say that <code>q</code> and <code>q</code> of type <code>Pred</code>, we say that <code>q</code>
is <i>serialization-compatible</i> with <code>p</code> if is <i>serialization-compatible</i> with <code>p</code> if
@ -930,9 +996,9 @@ Index reference
<br> <br>
<p>Revised November 6th 2008</p> <p>Revised July 3rd 2013</p>
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -97,6 +97,8 @@ their associated <a href="#ord_indices">ordered index</a> classes.
<code>"boost/multi_index/ordered_index.hpp"</code></a> synopsis</a></h2> <code>"boost/multi_index/ordered_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre> <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>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span> <span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -190,15 +192,13 @@ together, with minor differences explicitly stated when they exist.
</p> </p>
<p> <p>
Except where noted, ordered indices (both unique and non-unique) are models of Except where noted or if the corresponding interface does not exist,
<a href="http://www.sgi.com/tech/stl/SortedAssociativeContainer.html"> ordered indices (both unique and non-unique) satisfy the C++ requirements
<code>Sorted Associative Container</code></a> and for associative containers at <b>[associative.reqmts]</b>
<a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html"> (supporting unique and equivalent keys, respectively.)
<code>Unique Associative Container</code></a>, much as <code>std::set</code>s Accordingly, validity of iterators and references to elements is
are. Accordingly, validity of iterators and references to elements is preserved. We only provide descriptions of those types and operations that
preserved. We only provide descriptions of those types and operations that are do not exactly conform to or are not mandated by the standard requirements.
either not present in the concepts modeled or do not exactly conform to the
requirements for these types of containers.
</p> </p>
<blockquote><pre> <blockquote><pre>
@ -241,6 +241,7 @@ requirements for these types of containers.
<span class=comment>// construct/copy/destroy:</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=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=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=special>;</span>
@ -270,16 +271,24 @@ requirements for these types of containers.
<span class=comment>// modifiers:</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=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=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>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>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>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>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=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=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>&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>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>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>
@ -436,9 +445,8 @@ following types:
which determines the mechanism for extracting a key from <code>Value</code>, which determines the mechanism for extracting a key from <code>Value</code>,
must be a model of <a href="key_extraction.html#key_extractors"> must be a model of <a href="key_extraction.html#key_extractors">
<code>Key Extractor</code></a> from <code>Value</code>. <code>Compare</code> is a <code>Key Extractor</code></a> from <code>Value</code>. <code>Compare</code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> <code>CopyConstructible</code> binary predicate inducing a strict weak order
<code>Strict Weak Ordering</code></a> on elements of on elements of <code>KeyFromValue::result_type</code>.
<code>KeyFromValue::result_type</code>.
</p> </p>
<h4><a name="constructors">Constructors, copy and assignment</a></h4> <h4><a name="constructors">Constructors, copy and assignment</a></h4>
@ -461,6 +469,18 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br> <b>Returns:</b> <code>*this</code>.<br>
</blockquote> </blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<h4><a name="iterators">Iterators</a></h4> <h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br> <code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
@ -475,9 +495,65 @@ const_iterator iterator_to(const value_type&amp; x)const;</code>
<h4><a name="modifiers">Modifiers</a></h4> <h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code> <code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(Args&amp;&amp;... args);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
<li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful insertion,
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
points to an element that caused the insertion to be banned. Note that more than
one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
iterator emplace_hint(iterator position, Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
<li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<code>position</code> is used as a hint to improve the efficiency of the
operation. If succesful, insertion happens as close as possible to the
location just prior to <code>position</code>.<br>
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
element. Otherwise, an iterator to an element that caused the insertion to be
banned. Note that more than one element can be causing insertion not to be
allowed.<br>
<b>Complexity:</b> <code>O(H(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which <b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if the index belongs if
<ul> <ul>
@ -495,10 +571,16 @@ one element can be causing insertion not to be allowed.<br>
<b>Exception safety:</b> Strong.<br> <b>Exception safety:</b> Strong.<br>
</blockquote> </blockquote>
<code>iterator insert(iterator position,const value_type&amp; x);</code> <code>iterator insert(iterator position,const value_type&amp; x);</code><br>
<code>iterator insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br> <b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which <b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if the index belongs if
<ul> <ul>
@ -522,24 +604,37 @@ allowed.<br>
void insert(InputIterator first,InputIterator last);</code> void insert(InputIterator first,InputIterator last);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of <b>Requires:</b> <code>InputIterator</code> is an input iterator.
<a href="http://www.sgi.com/tech/stl/InputIterator.html"> <code>value_type</code> is <code>EmplaceConstructible</code> into
<code>Input Iterator</code></a> over elements of type <code>multi_index_container</code> from <code>*first</code>.
<code>value_type</code> or a type convertible to <code>value_type</code>.
<code>first</code> and <code>last</code> are not iterators into any <code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs. index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br> <code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> <b>Effects:</b>
<blockquote><pre> For each element of [<code>first</code>, <code>last</code>), in this
<span class=identifier>iterator</span> <span class=identifier>hint</span><span class=special>=</span><span class=identifier>end</span><span class=special>();</span> order, inserts it into the <code>multi_index_container</code>
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>hint</span><span class=special>=</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>hint</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span> to which this index belongs if
</pre></blockquote> <ul>
<li>the index is non-unique OR no other element exists with
equivalent key,</li>
<li>AND insertion is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
<b>Complexity:</b> <code>O(m*H(n+m))</code>, where <b>Complexity:</b> <code>O(m*H(n+m))</code>, where
<code>m</code> is the number of elements in [<code>first</code>, <code>m</code> is the number of elements in [<code>first</code>,
<code>last</code>).<br> <code>last</code>).<br>
<b>Exception safety:</b> Basic.<br> <b>Exception safety:</b> Basic.<br>
</blockquote> </blockquote>
<code>void insert(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>())</span>
</pre></blockquote>
</blockquote>
<code>iterator erase(iterator position);</code> <code>iterator erase(iterator position);</code>
<blockquote> <blockquote>
@ -575,11 +670,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> <code>nothrow</code>.<br> <b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote> </blockquote>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a> <a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator <b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
of the index.<br> <code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed <b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if, for the value <code>x</code> the index belongs if, for the value <code>x</code>
@ -604,9 +702,8 @@ belongs remains in its original state.
<code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a> <code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
<blockquote> <blockquote>
<b>Requires:</b> <code>Modifier</code> is a model of <b>Requires:</b> <code>mod</code> is a unary function object
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br> iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element <b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
@ -634,9 +731,8 @@ the element pointed to by <code>position</code> is erased.
bool modify(iterator position,Modifier mod,Rollback back);</code> bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of <b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> objects accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>, iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element <code>back(e)</code>, where <code>e</code> is the element
@ -673,9 +769,8 @@ is rethrown.
<blockquote> <blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write <b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a> <a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> is a model of from <code>value_type</code>. <code>mod</code> is a
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> unary function object accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br> iterator of the index.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod')</code>, <b>Effects:</b> Equivalent to <code>modify(position,mod')</code>,
@ -690,14 +785,13 @@ bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write <b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a> <a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> and <code>Rollback</code> from <code>value_type</code>. <code>mod</code> and <code>back</code>
are models of <a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> are unary function objects accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. iterator of the index.
The sequence of operations <code>mod(k)</code>, The sequence of operations <code>mod(k)</code>,
<code>back(k)</code>, where <code>k</code> is the key of the element <code>back(k)</code>, where <code>k</code> is the key of the element
pointed to by <code>position</code>, restores k to its original state.<br> pointed to by <code>position</code>, restores <code>k</code> to its original state.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>, <b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>,
with <code>mod'</code> and <code>back</code> defined in such a way that with <code>mod'</code> and <code>back</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and <code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
@ -724,10 +818,7 @@ the index.<br>
<p> <p>
Ordered indices provide the full lookup functionality required by Ordered indices provide the full lookup functionality required by
<a href="http://www.sgi.com/tech/stl/SortedAssociativeContainer.html"> <b>[associative.reqmts]</b>, namely <code>find</code>,
<code>Sorted Associative Containers</code></a> and
<a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html">
<code>Unique Associative Containers</code></a>, namely <code>find</code>,
<code>count</code>, <code>lower_bound</code>, <code>upper_bound</code> <code>count</code>, <code>lower_bound</code>, <code>upper_bound</code>
and <code>equal_range</code>. Additionally, these member functions are and <code>equal_range</code>. Additionally, these member functions are
templatized to allow for non-standard arguments, so extending templatized to allow for non-standard arguments, so extending
@ -737,20 +828,14 @@ concept.
</p> </p>
<p> <p>
Consider a Consider a binary predicate <code>Compare</code> inducing a strict
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> weak order over values of type <code>Key</code>. A pair of types (<code>CompatibleKey</code>,
<code>Strict Weak Ordering</code></a> <code>Compare</code> over values
of type <code>Key</code>. A pair of types (<code>CompatibleKey</code>,
<code>CompatibleCompare</code>) is said to be a <i>compatible extension</i> <code>CompatibleCompare</code>) is said to be a <i>compatible extension</i>
of <code>Compare</code> if of <code>Compare</code> if
<ol> <ol>
<li><code>CompatibleCompare</code> is a <li><code>CompatibleCompare</code> is a binary predicate over (<code>Key</code>,
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> over (<code>Key</code>,
<code>CompatibleKey</code>),</li> <code>CompatibleKey</code>),</li>
<li><code>CompatibleCompare</code> is a <li><code>CompatibleCompare</code> is a binary predicate over (<code>CompatibleKey</code>,
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> over (<code>CompatibleKey</code>,
<code>Key</code>),</li> <code>Key</code>),</li>
<li>if <code>c_comp(ck,k1)</code> then <code>!c_comp(k1,ck)</code>,</li> <li>if <code>c_comp(ck,k1)</code> then <code>!c_comp(k1,ck)</code>,</li>
<li>if <code>!c_comp(ck,k1)</code> and <code>!comp(k1,k2)</code> then <li>if <code>!c_comp(ck,k1)</code> and <code>!comp(k1,k2)</code> then
@ -913,15 +998,11 @@ are modeled after the following concepts.
</p> </p>
<p> <p>
Consider a Consider a binary predicate <code>Compare</code> inducing a strict
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> weak order over values of type <code>Key</code>. A type <code>LowerBounder</code> is said to be
<code>Strict Weak Ordering</code></a> <code>Compare</code> over values
of type <code>Key</code>. A type <code>LowerBounder</code> is said to be
a <i>lower bounder</i> of <code>Compare</code> if a <i>lower bounder</i> of <code>Compare</code> if
<ol> <ol>
<li><code>LowerBounder</code> is a <li><code>LowerBounder</code> is a predicate over <code>Key</code>,</li>
<a href="http://www.sgi.com/tech/stl/Predicate.html">
<code>Predicate</code></a> over <code>Key</code>,</li>
<li>if <code>lower(k1)</code> and <code>!comp(k2,k1)</code> then <li>if <code>lower(k1)</code> and <code>!comp(k2,k1)</code> then
<code>lower(k2)</code>,</li> <code>lower(k2)</code>,</li>
</ol> </ol>
@ -930,9 +1011,7 @@ for every <code>lower</code> of type <code>LowerBounder</code>,
<code>k2</code> of type <code>Key</code>. Similarly, an <i>upper bounder</i> <code>k2</code> of type <code>Key</code>. Similarly, an <i>upper bounder</i>
is a type <code>UpperBounder</code> such that is a type <code>UpperBounder</code> such that
<ol> <ol>
<li><code>UpperBounder</code> is a <li><code>UpperBounder</code> is a predcate over <code>Key</code>,</li>
<a href="http://www.sgi.com/tech/stl/Predicate.html">
<code>Predicate</code></a> over <code>Key</code>,</li>
<li>if <code>upper(k1)</code> and <code>!comp(k1,k2)</code> then <li>if <code>upper(k1)</code> and <code>!comp(k1,k2)</code> then
<code>upper(k2)</code>,</li> <code>upper(k2)</code>,</li>
</ol> </ol>
@ -1024,9 +1103,9 @@ Hashed indices
<br> <br>
<p>Revised December 21st 2009</p> <p>Revised July 6th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -92,6 +92,8 @@ its associated <a href="#rnd_indices">random access index</a> class.
<code>"boost/multi_index/random_access_index.hpp"</code></a> synopsis</a></h2> <code>"boost/multi_index/random_access_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre> <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>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span> <span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -161,33 +163,31 @@ is preserved in all operations, regardless of the capacity status.
</p> </p>
<p> <p>
As is the case with sequenced indices, random access indices have the Except where noted or if the corresponding interface does not exist, random access
following limitations with respect to STL sequence containers: indices verify the same container requirements as <code>std::vector</code>
plus the requirements for <code>std::list</code> specific list operations at
<b>[list.ops]</b>. Some of the most important differences with respect to
<code>std::vector</code> are:
<ul> <ul>
<li>Random access indices are not <a href="http://www.sgi.com/tech/stl/Assignable.html"> <li>Random access indices do not provide memory contiguity, and hence do not
<code>Assignable</code></a> (like any other index.)</li> have <code>data</code> member functions.
<li>Insertions into a random access index may fail due to clashings
with other indices. This alters the semantics of the operations
provided with respect to their analogues in STL sequence containers.
</li> </li>
<li>Elements in a random access index are not mutable, and can only be changed
<li>The complexity of some operations, notably insertion and deletion, differ
from those of <code>std::vector</code>.
</li>
<li>Unlike as in <code>std::vector</code>, insertions into a random access index
may fail due to clashings with other indices. This alters the semantics
of the operations provided with respect to their analogues in
<code>std::vector</code>.
</li>
<li>Elements in a randon access index are not mutable, and can only be changed
by means of <a href="#replace"><code>replace</code></a> and by means of <a href="#replace"><code>replace</code></a> and
<a href="#modify"><code>modify</code></a> member functions. <a href="#modify"><code>modify</code></a> member functions.
</li> </li>
</ul> <li><code>push_front</code> and <code>pop_front</code> are provided for
Having these restrictions into account, random access indices are models compatibility with sequenced indices, even though they take linear time to execute.
of <a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html"> </li></ul>
<code>Random Access Container</code></a> and
<a href="http://www.sgi.com/tech/stl/BackInsertionSequence.html">
<code>Back Insertion Sequence</code></a>. Although these indices do
not model
<a href="http://www.sgi.com/tech/stl/FrontInsertionSequence.html">
<code>Front Insertion Sequence</code></a>, because front insertion
and deletion take linear time, front operations are nonetheless provided
to match the interface of sequenced indices.
We only describe those types and operations that are
either not present in the concepts modeled or do not exactly conform
to the requirements for these types of containers.
</p> </p>
<blockquote><pre> <blockquote><pre>
@ -203,7 +203,7 @@ to the requirements for these types of containers.
<span class=keyword>public</span><span class=special>:</span> <span class=keyword>public</span><span class=special>:</span>
<span class=comment>// types:</span> <span class=comment>// types:</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>node_type</span><span class=special>::</span><span class=identifier>value_type</span> <span class=identifier>value_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>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span> <span class=keyword>typedef</span> <span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</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>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=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
@ -223,9 +223,11 @@ to the requirements for these types of containers.
<span class=comment>// construct/copy/destroy:</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=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=keyword>template</span> <span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span> <span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>assign</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>assign</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>assign</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=keyword>void</span> <span class=identifier>assign</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=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>value</span><span class=special>);</span> <span class=keyword>void</span> <span class=identifier>assign</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=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>value</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=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=special>;</span>
@ -255,8 +257,10 @@ to the requirements for these types of containers.
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</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=special>;</span>
<span class=identifier>size_type</span> <span class=identifier>capacity</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span> <span class=identifier>size_type</span> <span class=identifier>capacity</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>void</span> <span class=identifier>reserve</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>m</span><span class=special>);</span> <span class=keyword>void</span> <span class=identifier>reserve</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>m</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>shrink_to_fit</span><span class=special>();</span>
<span class=keyword>void</span> <span class=identifier>resize</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=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>value_type</span><span class=special>());</span> <span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>resize</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=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// access:</span> <span class=comment>// access:</span>
@ -267,20 +271,32 @@ to the requirements for these types of containers.
<span class=comment>// modifiers:</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_front</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>push_front</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>push_front</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>push_front</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>void</span> <span class=identifier>pop_front</span><span class=special>();</span> <span class=keyword>void</span> <span class=identifier>pop_front</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>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_back</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>push_back</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>push_back</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>push_back</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>void</span> <span class=identifier>pop_back</span><span class=special>();</span> <span class=keyword>void</span> <span class=identifier>pop_back</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>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>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=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>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>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>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>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>void</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>size_type</span> <span class=identifier>m</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>void</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>size_type</span> <span class=identifier>m</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>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>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>iterator</span> <span class=identifier>position</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>iterator</span> <span class=identifier>position</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>iterator</span> <span class=identifier>position</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>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>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=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=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>&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>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>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>
@ -445,17 +461,22 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br> <b>Returns:</b> <code>*this</code>.<br>
</blockquote> </blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code>template &lt;class InputIterator><br> <code>template &lt;class InputIterator><br>
void assign(InputIterator first,InputIterator last);</code> void assign(InputIterator first,InputIterator last);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>value_type</code> or a type convertible to <code>value_type</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> <b>Effects:</b>
<blockquote><pre> <blockquote><pre>
<span class=identifier>clear</span><span class=special>();</span> <span class=identifier>clear</span><span class=special>();</span>
@ -463,6 +484,15 @@ index of the <code>multi_index_container</code> to which this index belongs.
</pre></blockquote> </pre></blockquote>
</blockquote> </blockquote>
<code>void assign(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>assign</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>void assign(size_type n,const value_type&amp; value);</code> <code>void assign(size_type n,const value_type&amp; value);</code>
<blockquote> <blockquote>
@ -500,6 +530,7 @@ is preserved in all insertions, regardless of the capacity status.
</blockquote> </blockquote>
<a name="reserve"><code>void reserve(size_type m);</code></a> <a name="reserve"><code>void reserve(size_type m);</code></a>
<blockquote> <blockquote>
<b>Effects:</b> If the previous value of <code>capacity()</code> <b>Effects:</b> If the previous value of <code>capacity()</code>
was greater than or equal to <code>m</code>, nothing is done; was greater than or equal to <code>m</code>, nothing is done;
@ -511,52 +542,123 @@ otherwise <code>O(n)</code>.<br>
otherwise, strong.<br> otherwise, strong.<br>
</blockquote> </blockquote>
<code>void resize(size_type n,const value_type&amp; x=value_type());</code> <code>void shrink_to_fit();</code>
<blockquote> <blockquote>
<b>Effects:</b> <b>Effects:</b> Reduces <code>capacity()</code> to <code>size()</code>.<br>
<blockquote><pre> <b>Complexity:</b> If the capacity is not changed, constant;
<span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&gt;</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>n</span><span class=special>-</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> otherwise <code>O(n)</code>.<br>
<span class=keyword>else</span> <span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&lt;</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>n</span><span class=special>,</span><span class=identifier>end</span><span class=special>());</span> <b>Exception safety:</b> If the capacity is not changed, <code>nothrow</code>;
</pre></blockquote> otherwise, strong.<br>
</blockquote>
<code>void resize(size_type n);<br>
void resize(size_type n,const value_type&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>DefaultInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> If <code>size()&lt;n</code>, tries to append <code>n-size()</code> default-inserted
elements (first version) or copies of <code>x</code> (second version) at the end of
the index. If <code>n&lt;size()</code>, erases the last <code>size()-n</code> elements.<br>
<b>Note:</b> If an expansion is requested, the size of the index is not guaranteed <b>Note:</b> If an expansion is requested, the size of the index is not guaranteed
to be <code>n</code> after this operation (other indices may ban insertions.) to be <code>n</code> after this operation (other indices may ban insertions.)
</blockquote> </blockquote>
<h4><a name="modifiers">Modifiers</a></h4> <h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code> <code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_front(Args&amp;&amp;... args);</code>
<blockquote> <blockquote>
<b>Effects:</b> Inserts <code>x</code> at the beginning of the sequence if <b>Effects:</b>
no other index of the <code>multi_index_container</code> bans the insertion.<br> <blockquote><pre>
<span class=identifier>emplace</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>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code> <b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise, insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned. <code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br> Note that more than one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(n+I(n))</code>.<br>
<b>Exception safety:</b> Strong.
</blockquote> </blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code> <code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_front(value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Effects:</b> Inserts <code>x</code> at the end of the sequence if <b>Effects:</b>
no other index of the <code>multi_index_container</code> bans the insertion.<br> <blockquote><pre>
<span class=identifier>insert</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=comment>// lvalue ref version</span>
<span class=identifier>insert</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>move</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code> <b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise, insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned. <code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br> Note that more than one element can be causing insertion not to be allowed.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_back(Args&amp;&amp;... args);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>emplace</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>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_back(value_type&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <span class=comment>// lvalue ref version</span>
<span class=identifier>insert</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>move</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(iterator position,Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful insertion,
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
points to an element that caused the insertion to be banned. Note that more than
one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br> <b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong. <b>Exception safety:</b> Strong.<br>
</blockquote> </blockquote>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code> <code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br> <b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion <b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<br> is allowed by all other indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code> <b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
@ -564,7 +666,7 @@ is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise, insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned. <code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br> Note that more than one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(shl(end()-position,1) + I(n))</code>.<br> <b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong. <b>Exception safety:</b> Strong.
</blockquote> </blockquote>
@ -584,23 +686,32 @@ void insert(iterator position,InputIterator first,InputIterator last);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index. <b>Requires:</b> <code>position</code> is a valid iterator of the index.
<code>InputIterator</code> is a model of <code>InputIterator</code> is an input iterator.
<a href="http://www.sgi.com/tech/stl/InputIterator.html"> <code>value_type</code> is
<code>Input Iterator</code></a> over elements of type <code>EmplaceConstructible</code> into
<code>value_type</code> or a type convertible to <code>value_type</code>. <code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any <code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs. index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br> <code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> <b>Effects:</b>
<blockquote><pre> For each element of [<code>first</code>, <code>last</code>), in this
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span> order, inserts it before <code>position</code> if insertion is allowed by all
</pre></blockquote> other indices of the <code>multi_index_container</code>.<br>
<b>Complexity:</b> <code>O(shl(end()-position,m) + m*I(n+m))</code>, <b>Complexity:</b> <code>O(shl(end()-position,m) + m*I(n+m))</code>,
where <code>m</code> is the number of elements in where <code>m</code> is the number of elements in
[<code>first</code>,<code>last</code>).<br> [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> Basic. <b>Exception safety:</b> Basic.
</blockquote> </blockquote>
<code>void insert(iterator position,std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>iterator erase(iterator position);</code> <code>iterator erase(iterator position);</code>
<blockquote> <blockquote>
@ -626,11 +737,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> <code>nothrow</code>.<br> <b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote> </blockquote>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a> <a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator <b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
of the index.<br> <code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed <b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if replacing is allowed by all other indices of the the index belongs if replacing is allowed by all other indices of the
@ -649,17 +763,16 @@ belongs remains in its original state.
<code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a> <code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
<blockquote> <blockquote>
<b>Requires:</b> <code>Modifier</code> is a model of <b>Requires:</b> <code>mod</code> is a unary function object
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br> iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element <b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and rearranges <code>*position</code> into pointed to by <code>position</code> and rearranges <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
random access indices does not change the position of the element with respect indices does not change the position of the element with respect to the index;
to the index; rearrangement on other indices may or might not succeed. If the rearrangement on other indices may or might not succeed. If the rearrangement
rearrangement fails, the element is erased.<br> fails, the element is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the <b>Postconditions:</b> Validity of <code>position</code> is preserved if the
operation succeeds.<br> operation succeeds.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code> <b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
@ -674,9 +787,8 @@ the element pointed to by <code>position</code> is erased.
bool modify(iterator position,Modifier mod,Rollback back);</code> bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of <b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> objects accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>, iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element <code>back(e)</code>, where <code>e</code> is the element
@ -684,10 +796,10 @@ pointed to by <code>position</code>, restores all keys of the element
to their original state.<br> to their original state.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element <b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
random access indices does not change the position of the element with respect indices does not change the position of the element with respect to the index;
to the index; rearrangement on other indices may or might not succeed. If the rearrangement on other indices may or might not succeed. If the rearrangement
rearrangement fails, <code>back(e)</code> is invoked and the fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br> element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if <b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br> the element is erased under the conditions described below.<br>
@ -808,11 +920,10 @@ is the number of elements erased.<br>
<code>void merge(index class name&amp; x);</code> <code>void merge(index class name&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>std::less&lt;value_type></code> is a <b>Requires:</b> <code>std::less&lt;value_type&gt;</code> induces a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> strict weak ordering over <code>value_type</code>.
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
Both the index and <code>x</code> are sorted according to Both the index and <code>x</code> are sorted according to
<code>std::less&lt;value_type></code>.<br> <code>std::less&lt;value_type&gt;</code>.<br>
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the <b>Effects:</b> Attempts to insert every element of <code>x</code> into the
corresponding position of the index (according to the order). Elements corresponding position of the index (according to the order). Elements
successfully inserted are erased from <code>x</code>. The resulting sequence successfully inserted are erased from <code>x</code>. The resulting sequence
@ -832,9 +943,8 @@ otherwise, basic.<br>
<code>template &lt;typename Compare> void merge(index class name&amp; x,Compare comp);</code> <code>template &lt;typename Compare> void merge(index class name&amp; x,Compare comp);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Compare</code> is a <b>Requires:</b> <code>Compare</code> induces a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> strict weak ordering over <code>value_type</code>.
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
Both the index and <code>x</code> are sorted according to <code>comp</code>.<br> Both the index and <code>x</code> are sorted according to <code>comp</code>.<br>
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the <b>Effects:</b> Attempts to insert every element of <code>x</code> into the
corresponding position of the index (according to <code>comp</code>). corresponding position of the index (according to <code>comp</code>).
@ -855,9 +965,8 @@ otherwise, basic.<br>
<code>void sort();</code> <code>void sort();</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>std::less&lt;value_type></code> is a <b>Requires:</b> <code>std::less&lt;value_type&gt;</code> induces a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> strict weark ordering over <code>value_type</code>.<br>
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to <b>Effects:</b> Sorts the index according to
<code>std::less&lt;value_type></code>. The sorting is stable, i.e. <code>std::less&lt;value_type></code>. The sorting is stable, i.e.
equivalent elements preserve their relative position.<br> equivalent elements preserve their relative position.<br>
@ -869,9 +978,8 @@ equivalent elements preserve their relative position.<br>
<code>template &lt;typename Compare> void sort(Compare comp);</code> <code>template &lt;typename Compare> void sort(Compare comp);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Compare</code> is a <b>Requires:</b> <code>Compare</code> induces a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> strict weak ordering over <code>value_type</code>.<br>
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to <code>comp</code>. The sorting <b>Effects:</b> Sorts the index according to <code>comp</code>. The sorting
is stable, i.e. equivalent elements preserve their relative position.<br> is stable, i.e. equivalent elements preserve their relative position.<br>
<b>Postconditions:</b> Validity of iterators and references is preserved.<br> <b>Postconditions:</b> Validity of iterators and references is preserved.<br>
@ -1000,9 +1108,9 @@ Key extraction
<br> <br>
<p>Revised July 21st 2009</p> <p>Revised July 14th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -92,6 +92,8 @@ its associated <a href="#seq_indices">sequenced index</a> class.
<code>"boost/multi_index/sequenced_index.hpp"</code></a> synopsis</a></h2> <code>"boost/multi_index/sequenced_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre> <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>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span> <span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -155,10 +157,15 @@ of iterators and references to elements is preserved in all operations.
</p> </p>
<p> <p>
There are a number of differences with respect to <code>std::lists</code>: Except where noted or if the corresponding interface does not exist, sequenced
indices verify the same container requirements as <code>std::list</code>:
we only provide descriptions of those types and operations that are either not
present in <code>std::list</code> or behave differently. Some of the
most important differences are:
<ul> <ul>
<li>Sequenced indices are not <a href="http://www.sgi.com/tech/stl/Assignable.html"> <li>The complexity of some operations, notably insertion and deletion, differ
<code>Assignable</code></a> (like any other index.)</li> from those of <code>std::list</code>.
</li>
<li>Unlike as in <code>std::list</code>, insertions into a sequenced index <li>Unlike as in <code>std::list</code>, insertions into a sequenced index
may fail due to clashings with other indices. This alters the semantics may fail due to clashings with other indices. This alters the semantics
of the operations provided with respect to their analogues in of the operations provided with respect to their analogues in
@ -169,16 +176,6 @@ There are a number of differences with respect to <code>std::lists</code>:
<a href="#modify"><code>modify</code></a> member functions. <a href="#modify"><code>modify</code></a> member functions.
</li> </li>
</ul> </ul>
Having these restrictions into account, sequenced indices are models
of <a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">
<code>Reversible Container</code></a>,
<a href="http://www.sgi.com/tech/stl/FrontInsertionSequence.html">
<code>Front Insertion Sequence</code></a> and
<a href="http://www.sgi.com/tech/stl/BackInsertionSequence.html">
<code>Back Insertion Sequence</code></a>. We only provide descriptions
of those types and operations that are either not present in the
concepts modeled or do not exactly conform to the requirements for these
types of containers.
</p> </p>
<blockquote><pre> <blockquote><pre>
@ -194,7 +191,7 @@ types of containers.
<span class=keyword>public</span><span class=special>:</span> <span class=keyword>public</span><span class=special>:</span>
<span class=comment>// types:</span> <span class=comment>// types:</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>node_type</span><span class=special>::</span><span class=identifier>value_type</span> <span class=identifier>value_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>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span> <span class=keyword>typedef</span> <span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</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>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=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
@ -214,9 +211,11 @@ types of containers.
<span class=comment>// construct/copy/destroy:</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=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=keyword>template</span> <span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span> <span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>assign</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>assign</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>assign</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=keyword>void</span> <span class=identifier>assign</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=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>value</span><span class=special>);</span> <span class=keyword>void</span> <span class=identifier>assign</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=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>value</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=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=special>;</span>
@ -245,7 +244,8 @@ types of containers.
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</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=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=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=special>;</span>
<span class=keyword>void</span> <span class=identifier>resize</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=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>value_type</span><span class=special>());</span> <span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>resize</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=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// access:</span> <span class=comment>// access:</span>
@ -254,20 +254,32 @@ types of containers.
<span class=comment>// modifiers:</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_front</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>push_front</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>push_front</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>push_front</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>void</span> <span class=identifier>pop_front</span><span class=special>();</span> <span class=keyword>void</span> <span class=identifier>pop_front</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>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_back</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>push_back</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>push_back</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>push_back</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>void</span> <span class=identifier>pop_back</span><span class=special>();</span> <span class=keyword>void</span> <span class=identifier>pop_back</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>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>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=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>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>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>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>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>void</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>size_type</span> <span class=identifier>n</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>void</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>size_type</span> <span class=identifier>n</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>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>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>iterator</span> <span class=identifier>position</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>iterator</span> <span class=identifier>position</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>iterator</span> <span class=identifier>position</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>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>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=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=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>&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>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>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>
@ -419,17 +431,22 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br> <b>Returns:</b> <code>*this</code>.<br>
</blockquote> </blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code>template &lt;class InputIterator><br> <code>template &lt;class InputIterator><br>
void assign(InputIterator first,InputIterator last);</code> void assign(InputIterator first,InputIterator last);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>value_type</code> or a type convertible to <code>value_type</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> <b>Effects:</b>
<blockquote><pre> <blockquote><pre>
<span class=identifier>clear</span><span class=special>();</span> <span class=identifier>clear</span><span class=special>();</span>
@ -437,6 +454,15 @@ index of the <code>multi_index_container</code> to which this index belongs.
</pre></blockquote> </pre></blockquote>
</blockquote> </blockquote>
<code>void assign(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>assign</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>void assign(size_type n,const value_type&amp; value);</code> <code>void assign(size_type n,const value_type&amp; value);</code>
<blockquote> <blockquote>
@ -461,56 +487,113 @@ const_iterator iterator_to(const value_type&amp; x)const;</code>
<h4><a name="capacity">Capacity operations</a></h4> <h4><a name="capacity">Capacity operations</a></h4>
<code>void resize(size_type n,const value_type&amp; x=value_type());</code> <code>void resize(size_type n);<br>
void resize(size_type n,const value_type&amp; x);</code>
<blockquote> <blockquote>
<b>Effects:</b> <b>Requires (first version):</b> <code>value_type</code> is <code>DefaultInsertable</code>
<blockquote><pre> into <code>multi_index_container</code>.<br>
<span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&gt;</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>n</span><span class=special>-</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <b>Requires (second version):</b> <code>value_type</code> is <code>CopyInsertable</code>
<span class=keyword>else</span> <span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&lt;</span><span class=identifier>size</span><span class=special>()){</span> into <code>multi_index_container</code>.<br>
<span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>begin</span><span class=special>();</span> <b>Effects:</b> If <code>size()&lt;n</code>, tries to append <code>n-size()</code> default-inserted
<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>n</span><span class=special>);</span> elements (first version) or copies of <code>x</code> (second version) at the end of
<span class=identifier>erase</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>end</span><span class=special>());</span> the index. If <code>n&lt;size()</code>, erases the last <code>size()-n</code> elements.<br>
<span class=special>}</span>
</pre></blockquote>
<b>Note:</b> If an expansion is requested, the size of the index is not guaranteed <b>Note:</b> If an expansion is requested, the size of the index is not guaranteed
to be <code>n</code> after this operation (other indices may ban insertions.) to be <code>n</code> after this operation (other indices may ban insertions.)
</blockquote> </blockquote>
<h4><a name="modifiers">Modifiers</a></h4> <h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code> <code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_front(Args&amp;&amp;... args);</code>
<blockquote> <blockquote>
<b>Effects:</b> Inserts <code>x</code> at the beginning of the sequence if <b>Effects:</b>
no other index of the <code>multi_index_container</code> bans the insertion.<br> <blockquote><pre>
<span class=identifier>emplace</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>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code> <b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise, insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned. <code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br> Note that more than one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.
</blockquote> </blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code> <code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_front(value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Effects:</b> Inserts <code>x</code> at the end of the sequence if <b>Effects:</b>
no other index of the <code>multi_index_container</code> bans the insertion.<br> <blockquote><pre>
<span class=identifier>insert</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=comment>// lvalue ref version</span>
<span class=identifier>insert</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>move</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code> <b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise, insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned. <code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br> Note that more than one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.
</blockquote> </blockquote>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code> <code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_back(Args&amp;&amp;... args);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br> <b>Effects:</b>
<blockquote><pre>
<span class=identifier>emplace</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>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_back(value_type&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <span class=comment>// lvalue ref version</span>
<span class=identifier>insert</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>move</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; otherwise,
<code>p.first</code> points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(iterator position,Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
is <code>true</code> if and only if insertion took place. On successful insertion,
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
points to an element that caused the insertion to be banned. Note that more than
one element can be causing insertion not to be allowed.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion <b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<br> is allowed by all other indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code> <b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
@ -525,7 +608,6 @@ Note that more than one element can be causing insertion not to be allowed.<br>
<code>void insert(iterator position,size_type n,const value_type&amp; x);</code> <code>void insert(iterator position,size_type n,const value_type&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> <b>Effects:</b>
<blockquote><pre> <blockquote><pre>
<span class=keyword>for</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>i</span><span class=special>=</span><span class=number>0</span><span class=special>;</span><span class=identifier>i</span><span class=special>&lt;</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span> <span class=keyword>for</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>i</span><span class=special>=</span><span class=number>0</span><span class=special>;</span><span class=identifier>i</span><span class=special>&lt;</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span>
@ -537,22 +619,31 @@ void insert(iterator position,InputIterator first,InputIterator last);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index. <b>Requires:</b> <code>position</code> is a valid iterator of the index.
<code>InputIterator</code> is a model of <code>InputIterator</code> is an input iterator.
<a href="http://www.sgi.com/tech/stl/InputIterator.html"> <code>value_type</code> is
<code>Input Iterator</code></a> over elements of type <code>EmplaceConstructible</code> into
<code>value_type</code> or a type convertible to <code>value_type</code>. <code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any <code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs. index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br> <code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> <b>Effects:</b>
<blockquote><pre> For each element of [<code>first</code>, <code>last</code>), in this
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span> order, inserts it before <code>position</code> if insertion is allowed by all
</pre></blockquote> other indices of the <code>multi_index_container</code>.<br>
<b>Complexity:</b> <code>O(m*I(n+m))</code>, where <code>m</code> is the <b>Complexity:</b> <code>O(m*I(n+m))</code>, where <code>m</code> is the
number of elements in [<code>first</code>,<code>last</code>).<br> number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> Basic. <b>Exception safety:</b> Basic.
</blockquote> </blockquote>
<code>void insert(iterator position,std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>iterator erase(iterator position);</code> <code>iterator erase(iterator position);</code>
<blockquote> <blockquote>
@ -578,11 +669,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> <code>nothrow</code>.<br> <b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote> </blockquote>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a> <a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator <b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
of the index.<br> <code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed <b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if replacing is allowed by all other indices of the the index belongs if replacing is allowed by all other indices of the
@ -601,9 +695,8 @@ belongs remains in its original state.
<code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a> <code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
<blockquote> <blockquote>
<b>Requires:</b> <code>Modifier</code> is a model of <b>Requires:</b> <code>mod</code> is a unary function object
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br> iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element <b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
@ -626,9 +719,8 @@ the element pointed to by <code>position</code> is erased.
bool modify(iterator position,Modifier mod,Rollback back);</code> bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of <b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"> objects accepting arguments of type
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable <code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>, iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element <code>back(e)</code>, where <code>e</code> is the element
@ -761,11 +853,10 @@ is the number of elements erased.<br>
<code>void merge(index class name&amp; x);</code> <code>void merge(index class name&amp; x);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>std::less&lt;value_type></code> is a <b>Requires:</b> <code>std::less&lt;value_type&gt;</code> induces a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> strict weak ordering over <code>value_type</code>.
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
Both the index and <code>x</code> are sorted according to Both the index and <code>x</code> are sorted according to
<code>std::less&lt;value_type></code>.<br> <code>std::less&lt;value_type&gt;</code>.<br>
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the <b>Effects:</b> Attempts to insert every element of <code>x</code> into the
corresponding position of the index (according to the order). Elements corresponding position of the index (according to the order). Elements
successfully inserted are erased from <code>x</code>. The resulting sequence successfully inserted are erased from <code>x</code>. The resulting sequence
@ -782,12 +873,11 @@ references is preserved.<br>
otherwise, basic.<br> otherwise, basic.<br>
</blockquote> </blockquote>
<code>template &lt;typename Compare> void merge(index class name&amp; x,Compare comp);</code> <code>template &lt;typename Compare&gt; void merge(index class name&amp; x,Compare comp);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Compare</code> is a <b>Requires:</b> <code>Compare</code> induces a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> strict weak ordering over <code>value_type</code>.
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
Both the index and <code>x</code> are sorted according to <code>comp</code>.<br> Both the index and <code>x</code> are sorted according to <code>comp</code>.<br>
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the <b>Effects:</b> Attempts to insert every element of <code>x</code> into the
corresponding position of the index (according to <code>comp</code>). corresponding position of the index (according to <code>comp</code>).
@ -808,24 +898,22 @@ otherwise, basic.<br>
<code>void sort();</code> <code>void sort();</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>std::less&lt;value_type></code> is a <b>Requires:</b> <code>std::less&lt;value_type&gt;</code> induces a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> strict weark ordering over <code>value_type</code>.<br>
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to <b>Effects:</b> Sorts the index according to
<code>std::less&lt;value_type></code>. The sorting is stable, i.e. <code>std::less&lt;value_type&gt;</code>. The sorting is stable, i.e.
equivalent elements preserve their relative position.<br> equivalent elements preserve their relative position.<br>
<b>Postconditions:</b> Validity of iterators and references is preserved.<br> <b>Postconditions:</b> Validity of iterators and references is preserved.<br>
<b>Complexity:</b> <code>O(n*log(n))</code>.<br> <b>Complexity:</b> <code>O(n*log(n))</code>.<br>
<b>Exception safety:</b> <code>nothrow</code> if <b>Exception safety:</b> <code>nothrow</code> if
<code>std::less&lt;value_type></code> does not throw; otherwise, basic. <code>std::less&lt;value_type&gt;</code> does not throw; otherwise, basic.
</blockquote> </blockquote>
<code>template &lt;typename Compare> void sort(Compare comp);</code> <code>template &lt;typename Compare&gt; void sort(Compare comp);</code>
<blockquote> <blockquote>
<b>Requires:</b> <code>Compare</code> is a <b>Requires:</b> <code>Compare</code> induces a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"> strict weak ordering over <code>value_type</code>.<br>
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to <code>comp</code>. The sorting <b>Effects:</b> Sorts the index according to <code>comp</code>. The sorting
is stable, i.e. equivalent elements preserve their relative position.<br> is stable, i.e. equivalent elements preserve their relative position.<br>
<b>Postconditions:</b> Validity of iterators and references is preserved.<br> <b>Postconditions:</b> Validity of iterators and references is preserved.<br>
@ -955,9 +1043,9 @@ Random access indices
<br> <br>
<p>Revised July 21st 2009</p> <p>Revised July 8th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -27,10 +27,10 @@ Acknowledgements
<hr> <hr>
<h2>Contents</h2> <h2>Contents</h2>
<ul> <ul>
<li><a href="#boost_1_55">Boost 1.55 release</a></li>
<li><a href="#boost_1_54">Boost 1.54 release</a></li> <li><a href="#boost_1_54">Boost 1.54 release</a></li>
<li><a href="#boost_1_49">Boost 1.49 release</a></li> <li><a href="#boost_1_49">Boost 1.49 release</a></li>
<li><a href="#boost_1_48">Boost 1.48 release</a></li> <li><a href="#boost_1_48">Boost 1.48 release</a></li>
@ -48,6 +48,39 @@ Acknowledgements
<li><a href="#boost_1_33">Boost 1.33 release</a></li> <li><a href="#boost_1_33">Boost 1.33 release</a></li>
</ul> </ul>
<h2><a name="boost_1_55">Boost 1.55 release</a></h2>
<p>
<ul>
<li>Boost.MultiIndex has been brought to a higher level of compliance
with C++11.
<ul>
<li><code>multi_index_container</code> is now efficiently movable.</li>
<li>Initializer lists supported.</li>
<li>Emplace functions provided.</li>
<li>Non-copyable elements (such as <code>std::unique_ptr&lt;T&gt;</code>) supported. This includes
insertion of a range [<code>first</code>,<code>last</code>) where the iterators point to a type that is
convertible to that of the element: no copy construction happens in the process.
</li>
<li>Random access indices provide <code>shrink_to_fit()</code>.</li>
</ul>
Refer to the <a href="compiler_specifics.html">compiler specifics</a> section for limitations
on pre-C++11 compilers.
</li>
<li>The following classes are deprecated:
<ul>
<li><a href="reference/key_extraction.html#member_offset"><code>member_offset</code></a>,</li>
<li><a href="reference/key_extraction.html#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>,</li>
<li><a href="reference/key_extraction.html#const_mem_fun_explicit"><code>mem_fun_explicit</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_equal_to"><code>composite_key_result_equal_to</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_less"><code>composite_key_result_less</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_greater"><code>composite_key_result_greater</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_hash"><code>composite_key_result_hash</code></a>.</li>
</ul>
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_54">Boost 1.54 release</a></h2> <h2><a name="boost_1_54">Boost 1.54 release</a></h2>
<p> <p>
@ -371,7 +404,7 @@ Acknowledgements
<br> <br>
<p>Revised February 21st 2013</p> <p>Revised July 9st 2013</p>
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software

View File

@ -222,9 +222,8 @@ element.
<p> <p>
The hash function is the very core of the fast lookup capabilities of this type of The hash function is the very core of the fast lookup capabilities of this type of
indices: a hasher indices: a hasher is just a unary function object
is just a <a href="http://www.sgi.com/tech/stl/UnaryFunction.html"><code>Unary returning an <code>std::size_t</code> value for any given
Function</code></a> returning an <code>std::size_t</code> value for any given
key. In general, it is impossible that every key map to a different hash value, for key. In general, it is impossible that every key map to a different hash value, for
the space of keys can be greater than the number of permissible hash codes: what the space of keys can be greater than the number of permissible hash codes: what
makes for a good hasher is that the probability of a collision (two different makes for a good hasher is that the probability of a collision (two different
@ -561,7 +560,7 @@ container:
<span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>v</span><span class=special>;</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>v</span><span class=special>;</span>
<span class=identifier>BOOST_FOREACH</span><span class=special>(</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&amp;</span> <span class=identifier>i</span><span class=special>,</span><span class=identifier>c</span><span class=special>)</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>push_back</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>cref</span><span class=special>(</span><span class=identifier>i</span><span class=special>));</span> <span class=identifier>BOOST_FOREACH</span><span class=special>(</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&amp;</span> <span class=identifier>i</span><span class=special>,</span><span class=identifier>c</span><span class=special>)</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>push_back</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>cref</span><span class=special>(</span><span class=identifier>i</span><span class=special>));</span>
<span class=comment>// this compiles OK, as reference_wrappers are assignable</span> <span class=comment>// this compiles OK, as reference_wrappers are swappable</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>random_shuffle</span><span class=special>(</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>v</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>random_shuffle</span><span class=special>(</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote> </pre></blockquote>
@ -569,9 +568,8 @@ container:
Elements of <code>v</code> are <code>reference_wrapper</code>s (from Elements of <code>v</code> are <code>reference_wrapper</code>s (from
<a href="../../../../doc/html/ref.html">Boost.Ref</a>) to the actual elements <a href="../../../../doc/html/ref.html">Boost.Ref</a>) to the actual elements
in the multi-index container. These objects still do not allow modification in the multi-index container. These objects still do not allow modification
of the referenced entities, but they are of the referenced entities, but they are swappable,
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>, which is the only requirement <code>std::random_shuffle</code> imposes. Once
which is the only requirement <code>std::random_suffle</code> imposes. Once
we have our desired rearrange stored in the view, we can transfer it to we have our desired rearrange stored in the view, we can transfer it to
the container with the container with
</p> </p>
@ -718,9 +716,9 @@ Key extraction
<br> <br>
<p>Revised October 15th 2007</p> <p>Revised July 7th 2013</p>
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz. <p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 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"> LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -0,0 +1,34 @@
/* 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.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP
#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* Used to mark a special ctor variant that copies the internal objects of
* a container but not its elements.
*/
struct do_not_copy_elements_tag{};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2008 Joaquin M Lopez Munoz. /* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
@ -14,11 +14,15 @@
#endif #endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/call_traits.hpp> #include <boost/detail/allocator_utilities.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/mpl/vector.hpp> #include <boost/mpl/vector.hpp>
#include <boost/multi_index/detail/copy_map.hpp> #include <boost/multi_index/detail/copy_map.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/node_type.hpp> #include <boost/multi_index/detail/node_type.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index_container_fwd.hpp> #include <boost/multi_index_container_fwd.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <utility> #include <utility>
@ -42,6 +46,10 @@ namespace detail{
* cannot be called directly from the index classes.) * cannot be called directly from the index classes.)
*/ */
struct lvalue_tag{};
struct rvalue_tag{};
struct emplaced_tag{};
template<typename Value,typename IndexSpecifierList,typename Allocator> template<typename Value,typename IndexSpecifierList,typename Allocator>
class index_base class index_base
{ {
@ -74,27 +82,61 @@ protected:
#endif #endif
private: private:
typedef typename call_traits<Value>::param_type value_param_type; typedef Value value_type;
protected: protected:
explicit index_base(const ctor_args_list&,const Allocator&){} explicit index_base(const ctor_args_list&,const Allocator&){}
index_base(
const index_base<Value,IndexSpecifierList,Allocator>&,
do_not_copy_elements_tag)
{}
void copy_( void copy_(
const index_base<Value,IndexSpecifierList,Allocator>&,const copy_map_type&) const index_base<Value,IndexSpecifierList,Allocator>&,const copy_map_type&)
{} {}
node_type* insert_(value_param_type v,node_type* x) node_type* insert_(const value_type& v,node_type* x,lvalue_tag)
{ {
boost::detail::allocator::construct(&x->value(),v); boost::detail::allocator::construct(&x->value(),v);
return x; return x;
} }
node_type* insert_(value_param_type v,node_type*,node_type* x) node_type* insert_(const value_type& v,node_type* x,rvalue_tag)
{
/* This shoud have used a modified, T&&-compatible version of
* boost::detail::allocator::construct, but
* <boost/detail/allocator_utilities.hpp> is too old and venerable to mess
* with; besides, it is a general internal utility and the imperfect
* perfect forwarding emulation of Boost.Move might break other libs.
*/
new (&x->value()) value_type(boost::move(const_cast<value_type&>(v)));
return x;
}
node_type* insert_(const value_type&,node_type* x,emplaced_tag)
{
return x;
}
node_type* insert_(const value_type& v,node_type*,node_type* x,lvalue_tag)
{ {
boost::detail::allocator::construct(&x->value(),v); boost::detail::allocator::construct(&x->value(),v);
return x; return x;
} }
node_type* insert_(const value_type& v,node_type*,node_type* x,rvalue_tag)
{
new (&x->value()) value_type(boost::move(const_cast<value_type&>(v)));
return x;
}
node_type* insert_(const value_type&,node_type*,node_type* x,emplaced_tag)
{
return x;
}
void erase_(node_type* x) void erase_(node_type* x)
{ {
boost::detail::allocator::destroy(&x->value()); boost::detail::allocator::destroy(&x->value());
@ -109,12 +151,20 @@ protected:
void swap_(index_base<Value,IndexSpecifierList,Allocator>&){} void swap_(index_base<Value,IndexSpecifierList,Allocator>&){}
bool replace_(value_param_type v,node_type* x) void swap_elements_(index_base<Value,IndexSpecifierList,Allocator>&){}
bool replace_(const value_type& v,node_type* x,lvalue_tag)
{ {
x->value()=v; x->value()=v;
return true; return true;
} }
bool replace_(const value_type& v,node_type* x,rvalue_tag)
{
x->value()=boost::move(const_cast<value_type&>(v));
return true;
}
bool modify_(node_type*){return true;} bool modify_(node_type*){return true;}
bool modify_rollback_(node_type*){return true;} bool modify_rollback_(node_type*){return true;}
@ -146,11 +196,39 @@ protected:
std::size_t final_size_()const{return final().size_();} std::size_t final_size_()const{return final().size_();}
std::size_t final_max_size_()const{return final().max_size_();} std::size_t final_max_size_()const{return final().max_size_();}
std::pair<final_node_type*,bool> final_insert_(value_param_type x) std::pair<final_node_type*,bool> final_insert_(const value_type& x)
{return final().insert_(x);} {return final().insert_(x);}
std::pair<final_node_type*,bool> final_insert_rv_(const value_type& x)
{return final().insert_rv_(x);}
template<typename T>
std::pair<final_node_type*,bool> final_insert_ref_(T& t)
{return final().insert_ref_(t);}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<final_node_type*,bool> final_emplace_(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
std::pair<final_node_type*,bool> final_insert_( std::pair<final_node_type*,bool> final_insert_(
value_param_type x,final_node_type* position) const value_type& x,final_node_type* position)
{return final().insert_(x,position);} {return final().insert_(x,position);}
std::pair<final_node_type*,bool> final_insert_rv_(
const value_type& x,final_node_type* position)
{return final().insert_rv_(x,position);}
template<typename T>
std::pair<final_node_type*,bool> final_insert_ref_(
T& t,final_node_type* position)
{return final().insert_ref_(t,position);}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<final_node_type*,bool> final_emplace_hint_(
final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return final().emplace_hint_(
position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
void final_erase_(final_node_type* x){final().erase_(x);} void final_erase_(final_node_type* x){final().erase_(x);}
@ -159,9 +237,13 @@ protected:
void final_clear_(){final().clear_();} void final_clear_(){final().clear_();}
void final_swap_(final_type& x){final().swap_(x);} void final_swap_(final_type& x){final().swap_(x);}
bool final_replace_( bool final_replace_(
value_param_type k,final_node_type* x) const value_type& k,final_node_type* x)
{return final().replace_(k,x);} {return final().replace_(k,x);}
bool final_replace_rv_(
const value_type& k,final_node_type* x)
{return final().replace_rv_(k,x);}
template<typename Modifier> template<typename Modifier>
bool final_modify_(Modifier& mod,final_node_type* x) bool final_modify_(Modifier& mod,final_node_type* x)

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2008 Joaquin M Lopez Munoz. /* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
@ -74,12 +74,12 @@ public:
void reserve(std::size_t c) void reserve(std::size_t c)
{ {
if(c>capacity_){ if(c>capacity_)set_capacity(c);
auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1);
node_impl_type::transfer(begin(),end()+1,spc1.data());
spc.swap(spc1);
capacity_=c;
} }
void shrink_to_fit()
{
if(capacity_>size_)set_capacity(size_);
} }
pointer begin()const{return ptrs();} pointer begin()const{return ptrs();}
@ -124,6 +124,14 @@ private:
{ {
return spc.data(); return spc.data();
} }
void set_capacity(std::size_t c)
{
auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1);
node_impl_type::transfer(begin(),end()+1,spc1.data());
spc.swap(spc1);
capacity_=c;
}
}; };
template<typename Allocator> template<typename Allocator>

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2011 Joaquin M Lopez Munoz. /* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
@ -14,6 +14,7 @@
#endif #endif
#include <boost/detail/no_exceptions_support.hpp> #include <boost/detail/no_exceptions_support.hpp>
#include <boost/mpl/if.hpp>
namespace boost{ namespace boost{

View File

@ -0,0 +1,247 @@
/* 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.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP
#define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
/* Utilities for emulation of variadic template functions. Variadic packs are
* replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters:
*
* - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK
* - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK
* - std::forward<Args>(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK
*
* Forwarding emulated with Boost.Move. A template functions foo_imp
* defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS
* arguments: variable number of arguments is emulated by providing a set of
* overloads foo forwarding to foo_impl with
*
* BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg)
*
* which fill the extra args with boost::multi_index::detail::noarg's.
* boost::multi_index::detail::vartempl_placement_new works the opposite
* way: it acceps a full a pointer x to Value and a
* BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to
* new(x) Value(args) where args is the argument pack after discarding
* noarg's.
*
* Emulation decays to the real thing when the compiler supports variadic
* templates and move semantics natively.
*/
#include <boost/config.hpp>
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\
defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/logical/and.hpp>
#include <boost/preprocessor/punctuation/comma.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS)
#define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5
#endif
#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \
BOOST_PP_ENUM_PARAMS( \
BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T)
#define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \
BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n)
#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \
BOOST_PP_ENUM( \
BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
BOOST_MULTI_INDEX_VARTEMPL_ARG,~)
#define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \
boost::forward<BOOST_PP_CAT(T,n)>(BOOST_PP_CAT(t,n))
#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \
BOOST_PP_ENUM( \
BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)
namespace boost{namespace multi_index{namespace detail{
struct noarg{};
}}}
/* call vartempl function without args */
#define BOOST_MULTI_INDEX_NULL_PARAM_PACK \
BOOST_PP_ENUM_PARAMS( \
BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT)
#define BOOST_MULTI_INDEX_TEMPLATE_N(n) \
template<BOOST_PP_ENUM_PARAMS(n,typename T)>
#define BOOST_MULTI_INDEX_TEMPLATE_0(n)
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \
BOOST_PP_IF(n, \
BOOST_MULTI_INDEX_TEMPLATE_N, \
BOOST_MULTI_INDEX_TEMPLATE_0)(n) \
BOOST_PP_SEQ_ELEM(0,data) /* ret */ \
BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \
{ \
return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \
BOOST_PP_COMMA_IF( \
BOOST_PP_AND( \
n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \
BOOST_PP_ENUM_PARAMS( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \
); \
}
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \
ret,name_from,name_to) \
BOOST_PP_REPEAT_FROM_TO( \
0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \
(ret)(name_from)(name_to))
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \
z,n,data) \
BOOST_PP_IF(n, \
BOOST_MULTI_INDEX_TEMPLATE_N, \
BOOST_MULTI_INDEX_TEMPLATE_0)(n) \
BOOST_PP_SEQ_ELEM(0,data) /* ret */ \
BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \
BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \
{ \
return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \
BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \
BOOST_PP_COMMA_IF( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \
BOOST_PP_ENUM_PARAMS( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \
); \
}
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \
ret,name_from,name_to,extra_arg_type,extra_arg_name) \
BOOST_PP_REPEAT_FROM_TO( \
0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \
(ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name))
namespace boost{
namespace multi_index{
namespace detail{
#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \
template< \
typename Value \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM_PARAMS(n,typename T) \
> \
Value* name( \
Value* x \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \
BOOST_PP_COMMA_IF( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \
BOOST_PP_ENUM_PARAMS( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \
{ \
return new(x) Value( \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \
}
#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \
BOOST_PP_REPEAT_FROM_TO( \
0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \
name)
BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new)
#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX
#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#else
/* native variadic templates support */
#include <utility>
#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args
#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args
#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward<Args>(args)...
#define BOOST_MULTI_INDEX_NULL_PARAM_PACK
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \
ret,name_from,name_to) \
template<typename... Args> ret name_from(Args&&... args) \
{ \
return name_to(std::forward<Args>(args)...); \
}
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \
ret,name_from,name_to,extra_arg_type,extra_arg_name) \
template<typename... Args> ret name_from( \
extra_arg_type extra_arg_name,Args&&... args) \
{ \
return name_to(extra_arg_name,std::forward<Args>(args)...); \
}
namespace boost{
namespace multi_index{
namespace detail{
template<typename Value,typename... Args>
Value* vartempl_placement_new(Value*x,Args&&... args)
{
return new(x) Value(std::forward<Args>(args)...);
}
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
#endif

View File

@ -21,33 +21,43 @@
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp> #include <boost/foreach_fwd.hpp>
#include <boost/limits.hpp> #include <boost/limits.hpp>
#include <boost/move/core.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/push_front.hpp> #include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/auto_space.hpp> #include <boost/multi_index/detail/auto_space.hpp>
#include <boost/multi_index/detail/bucket_array.hpp> #include <boost/multi_index/detail/bucket_array.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/hash_index_iterator.hpp> #include <boost/multi_index/detail/hash_index_iterator.hpp>
#include <boost/multi_index/detail/index_node_base.hpp> #include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/modify_key_adaptor.hpp> #include <boost/multi_index/detail/modify_key_adaptor.hpp>
#include <boost/multi_index/detail/safe_ctr_proxy.hpp> #include <boost/multi_index/detail/safe_ctr_proxy.hpp>
#include <boost/multi_index/detail/safe_mode.hpp> #include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp> #include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/hashed_index_fwd.hpp> #include <boost/multi_index/hashed_index_fwd.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <cstddef> #include <cstddef>
#include <functional> #include <functional>
#include <utility> #include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/serialization/nvp.hpp> #include <boost/serialization/nvp.hpp>
#endif #endif
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ #define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&hashed_index::check_invariant_); \ detail::make_obj_guard(x,&hashed_index::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch(); BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this)
#else #else
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT #define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT
#endif #endif
@ -191,6 +201,12 @@ private:
typedef typename call_traits< typedef typename call_traits<
key_type>::param_type key_param_type; key_type>::param_type key_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
typedef std::pair<iterator,bool> emplace_return_type;
public: public:
/* construct/destroy/copy /* construct/destroy/copy
@ -205,6 +221,15 @@ public:
return *this; return *this;
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& operator=(
std::initializer_list<value_type> list)
{
this->final()=list;
return *this;
}
#endif
allocator_type get_allocator()const allocator_type get_allocator()const
{ {
return this->final().get_allocator(); return this->final().get_allocator();
@ -248,14 +273,27 @@ public:
/* modifiers */ /* modifiers */
std::pair<iterator,bool> insert(value_param_type x) BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace,emplace_impl)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
iterator,emplace_hint,emplace_hint_impl,iterator,position)
std::pair<iterator,bool> insert(const value_type& x)
{ {
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_(x); std::pair<final_node_type*,bool> p=this->final_insert_(x);
return std::pair<iterator,bool>(make_iterator(p.first),p.second); return std::pair<iterator,bool>(make_iterator(p.first),p.second);
} }
iterator insert(iterator position,value_param_type x) std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
iterator insert(iterator position,const value_type& x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@ -265,14 +303,30 @@ public:
return make_iterator(p.first); return make_iterator(p.first);
} }
iterator insert(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(
x,static_cast<final_node_type*>(position.get_node()));
return make_iterator(p.first);
}
template<typename InputIterator> template<typename InputIterator>
void insert(InputIterator first,InputIterator last) void insert(InputIterator first,InputIterator last)
{ {
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
iterator hint=end(); for(;first!=last;++first)this->final_insert_ref_(*first);
for(;first!=last;++first)hint=insert(hint,*first);
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(std::initializer_list<value_type> list)
{
insert(list.begin(),list.end());
}
#endif
iterator erase(iterator position) iterator erase(iterator position)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -325,7 +379,7 @@ public:
return first; return first;
} }
bool replace(iterator position,value_param_type x) bool replace(iterator position,const value_type& x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@ -335,6 +389,16 @@ public:
x,static_cast<final_node_type*>(position.get_node())); x,static_cast<final_node_type*>(position.get_node()));
} }
bool replace(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
return this->final_replace_rv_(
x,static_cast<final_node_type*>(position.get_node()));
}
template<typename Modifier> template<typename Modifier>
bool modify(iterator position,Modifier mod) bool modify(iterator position,Modifier mod)
{ {
@ -410,6 +474,7 @@ public:
void swap(hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x) void swap(hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x)
{ {
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x);
this->final_swap_(x.final()); this->final_swap_(x.final());
} }
@ -634,6 +699,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
*/ */
} }
hashed_index(
const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x,
do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()),
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super(),
#endif
key(x.key),
hash_(x.hash_),
eq_(x.eq_),
buckets(x.get_allocator(),header()->impl(),0),
mlf(1.0f),
first_bucket(buckets.size())
{
calculate_max_load();
}
~hashed_index() ~hashed_index()
{ {
/* the container is guaranteed to be empty by now */ /* the container is guaranteed to be empty by now */
@ -690,7 +774,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::copy_(x,map); super::copy_(x,map);
} }
node_type* insert_(value_param_type v,node_type* x) template<typename Variant>
node_type* insert_(value_param_type v,node_type* x,Variant variant)
{ {
reserve(size()+1); reserve(size()+1);
@ -698,7 +783,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
node_impl_pointer pos=buckets.at(buc); node_impl_pointer pos=buckets.at(buc);
if(!link_point(v,pos,Category()))return node_type::from_impl(pos); if(!link_point(v,pos,Category()))return node_type::from_impl(pos);
node_type* res=static_cast<node_type*>(super::insert_(v,x)); node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
if(res==x){ if(res==x){
link(x,pos); link(x,pos);
if(first_bucket>buc)first_bucket=buc; if(first_bucket>buc)first_bucket=buc;
@ -706,7 +791,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
return res; return res;
} }
node_type* insert_(value_param_type v,node_type* position,node_type* x) template<typename Variant>
node_type* insert_(
value_param_type v,node_type* position,node_type* x,Variant variant)
{ {
reserve(size()+1); reserve(size()+1);
@ -714,7 +801,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
node_impl_pointer pos=buckets.at(buc); node_impl_pointer pos=buckets.at(buc);
if(!link_point(v,pos,Category()))return node_type::from_impl(pos); if(!link_point(v,pos,Category()))return node_type::from_impl(pos);
node_type* res=static_cast<node_type*>(super::insert_(v,position,x)); node_type* res=
static_cast<node_type*>(super::insert_(v,position,x,variant));
if(res==x){ if(res==x){
link(x,pos); link(x,pos);
if(first_bucket>buc)first_bucket=buc; if(first_bucket>buc)first_bucket=buc;
@ -776,10 +864,26 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::swap_(x); super::swap_(x);
} }
bool replace_(value_param_type v,node_type* x) void swap_elements_(
hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x)
{
buckets.swap(x.buckets);
std::swap(mlf,x.mlf);
std::swap(max_load,x.max_load);
std::swap(first_bucket,x.first_bucket);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
#endif
super::swap_elements_(x);
}
template<typename Variant>
bool replace_(value_param_type v,node_type* x,Variant variant)
{ {
if(eq_(key(v),key(x->value()))){ if(eq_(key(v),key(x->value()))){
return super::replace_(v,x); return super::replace_(v,x,variant);
} }
node_impl_pointer y=prev(x); node_impl_pointer y=prev(x);
@ -788,7 +892,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
BOOST_TRY{ BOOST_TRY{
std::size_t buc=find_bucket(v); std::size_t buc=find_bucket(v);
node_impl_pointer pos=buckets.at(buc); node_impl_pointer pos=buckets.at(buc);
if(link_point(v,pos,Category())&&super::replace_(v,x)){ if(link_point(v,pos,Category())&&super::replace_(v,x,variant)){
link(x,pos); link(x,pos);
if(first_bucket>buc){ if(first_bucket>buc){
first_bucket=buc; first_bucket=buc;
@ -1157,6 +1261,29 @@ private:
} }
#endif #endif
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
iterator emplace_hint_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_hint_(
static_cast<final_node_type*>(position.get_node()),
BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return make_iterator(p.first);
}
key_from_value key; key_from_value key;
hasher hash_; hasher hash_;
key_equal eq_; key_equal eq_;
@ -1257,5 +1384,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable(
} }
#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT #undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF
#endif #endif

View File

@ -47,11 +47,13 @@
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp> #include <boost/foreach_fwd.hpp>
#include <boost/iterator/reverse_iterator.hpp> #include <boost/iterator/reverse_iterator.hpp>
#include <boost/move/core.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <boost/mpl/push_front.hpp> #include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/bidir_node_iterator.hpp> #include <boost/multi_index/detail/bidir_node_iterator.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/index_node_base.hpp> #include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/modify_key_adaptor.hpp> #include <boost/multi_index/detail/modify_key_adaptor.hpp>
#include <boost/multi_index/detail/ord_index_node.hpp> #include <boost/multi_index/detail/ord_index_node.hpp>
@ -61,12 +63,17 @@
#include <boost/multi_index/detail/scope_guard.hpp> #include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/unbounded.hpp> #include <boost/multi_index/detail/unbounded.hpp>
#include <boost/multi_index/detail/value_compare.hpp> #include <boost/multi_index/detail/value_compare.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/ordered_index_fwd.hpp> #include <boost/multi_index/ordered_index_fwd.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <utility> #include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/archive/archive_exception.hpp> #include <boost/archive/archive_exception.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
@ -75,11 +82,14 @@
#endif #endif
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&ordered_index::check_invariant_); \ detail::make_obj_guard(x,&ordered_index::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch(); BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
#else #else
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
#endif #endif
@ -217,6 +227,12 @@ private:
typedef typename call_traits< typedef typename call_traits<
key_type>::param_type key_param_type; key_type>::param_type key_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
typedef std::pair<iterator,bool> emplace_return_type;
public: public:
/* construct/copy/destroy /* construct/copy/destroy
@ -231,6 +247,15 @@ public:
return *this; return *this;
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=(
std::initializer_list<value_type> list)
{
this->final()=list;
return *this;
}
#endif
allocator_type get_allocator()const allocator_type get_allocator()const
{ {
return this->final().get_allocator(); return this->final().get_allocator();
@ -269,14 +294,27 @@ public:
/* modifiers */ /* modifiers */
std::pair<iterator,bool> insert(value_param_type x) BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace,emplace_impl)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
iterator,emplace_hint,emplace_hint_impl,iterator,position)
std::pair<iterator,bool> insert(const value_type& x)
{ {
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_(x); std::pair<final_node_type*,bool> p=this->final_insert_(x);
return std::pair<iterator,bool>(make_iterator(p.first),p.second); return std::pair<iterator,bool>(make_iterator(p.first),p.second);
} }
iterator insert(iterator position,value_param_type x) std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
iterator insert(iterator position,const value_type& x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@ -286,13 +324,34 @@ public:
return make_iterator(p.first); return make_iterator(p.first);
} }
iterator insert(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(
x,static_cast<final_node_type*>(position.get_node()));
return make_iterator(p.first);
}
template<typename InputIterator> template<typename InputIterator>
void insert(InputIterator first,InputIterator last) void insert(InputIterator first,InputIterator last)
{ {
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
iterator hint=end(); node_type* hint=header(); /* end() */
for(;first!=last;++first)hint=insert(hint,*first); for(;first!=last;++first){
hint=this->final_insert_ref_(
*first,static_cast<final_node_type*>(hint)).first;
node_type::increment(hint);
} }
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(std::initializer_list<value_type> list)
{
insert(list.begin(),list.end());
}
#endif
iterator erase(iterator position) iterator erase(iterator position)
{ {
@ -330,7 +389,7 @@ public:
return first; return first;
} }
bool replace(iterator position,value_param_type x) bool replace(iterator position,const value_type& x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@ -340,6 +399,16 @@ public:
x,static_cast<final_node_type*>(position.get_node())); x,static_cast<final_node_type*>(position.get_node()));
} }
bool replace(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
return this->final_replace_rv_(
x,static_cast<final_node_type*>(position.get_node()));
}
template<typename Modifier> template<typename Modifier>
bool modify(iterator position,Modifier mod) bool modify(iterator position,Modifier mod)
{ {
@ -409,6 +478,7 @@ public:
void swap(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x) void swap(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
{ {
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
this->final_swap_(x.final()); this->final_swap_(x.final());
} }
@ -551,10 +621,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
comp_(x.comp_) comp_(x.comp_)
{ {
/* Copy ctor just takes the key and compare objects from x. The rest is /* Copy ctor just takes the key and compare objects from x. The rest is
* done in subsequent call to copy_(). * done in a subsequent call to copy_().
*/ */
} }
ordered_index(
const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()),
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super(),
#endif
key(x.key),
comp_(x.comp_)
{
empty_initialize();
}
~ordered_index() ~ordered_index()
{ {
/* the container is guaranteed to be empty by now */ /* the container is guaranteed to be empty by now */
@ -623,28 +708,31 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::copy_(x,map); super::copy_(x,map);
} }
node_type* insert_(value_param_type v,node_type* x) template<typename Variant>
node_type* insert_(value_param_type v,node_type* x,Variant variant)
{ {
link_info inf; link_info inf;
if(!link_point(key(v),inf,Category())){ if(!link_point(key(v),inf,Category())){
return node_type::from_impl(inf.pos); return node_type::from_impl(inf.pos);
} }
node_type* res=static_cast<node_type*>(super::insert_(v,x)); node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
if(res==x){ if(res==x){
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
} }
return res; return res;
} }
node_type* insert_(value_param_type v,node_type* position,node_type* x) template<typename Variant>
node_type* insert_(
value_param_type v,node_type* position,node_type* x,Variant variant)
{ {
link_info inf; link_info inf;
if(!hinted_link_point(key(v),position,inf,Category())){ if(!hinted_link_point(key(v),position,inf,Category())){
return node_type::from_impl(inf.pos); return node_type::from_impl(inf.pos);
} }
node_type* res=static_cast<node_type*>(super::insert_(v,position,x)); node_type* res=static_cast<node_type*>(super::insert_(v,position,x,variant));
if(res==x){ if(res==x){
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
} }
@ -689,10 +777,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::swap_(x); super::swap_(x);
} }
bool replace_(value_param_type v,node_type* x) void swap_elements_(
ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
{
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
#endif
super::swap_elements_(x);
}
template<typename Variant>
bool replace_(value_param_type v,node_type* x,Variant variant)
{ {
if(in_place(v,x,Category())){ if(in_place(v,x,Category())){
return super::replace_(v,x); return super::replace_(v,x,variant);
} }
node_type* next=x; node_type* next=x;
@ -703,7 +802,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
BOOST_TRY{ BOOST_TRY{
link_info inf; link_info inf;
if(link_point(key(v),inf,Category())&&super::replace_(v,x)){ if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
return true; return true;
} }
@ -1085,6 +1184,29 @@ private:
} }
#endif #endif
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
iterator emplace_hint_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_hint_(
static_cast<final_node_type*>(position.get_node()),
BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return make_iterator(p.first);
}
template<typename LowerBounder,typename UpperBounder> template<typename LowerBounder,typename UpperBounder>
std::pair<iterator,iterator> std::pair<iterator,iterator>
range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
@ -1402,5 +1524,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable(
} }
#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
#endif #endif

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2011 Joaquin M Lopez Munoz. /* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
@ -20,10 +20,13 @@
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp> #include <boost/foreach_fwd.hpp>
#include <boost/iterator/reverse_iterator.hpp> #include <boost/iterator/reverse_iterator.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp> #include <boost/mpl/not.hpp>
#include <boost/mpl/push_front.hpp> #include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/index_node_base.hpp> #include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/rnd_node_iterator.hpp> #include <boost/multi_index/detail/rnd_node_iterator.hpp>
#include <boost/multi_index/detail/rnd_index_node.hpp> #include <boost/multi_index/detail/rnd_index_node.hpp>
@ -32,6 +35,7 @@
#include <boost/multi_index/detail/safe_ctr_proxy.hpp> #include <boost/multi_index/detail/safe_ctr_proxy.hpp>
#include <boost/multi_index/detail/safe_mode.hpp> #include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp> #include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/random_access_index_fwd.hpp> #include <boost/multi_index/random_access_index_fwd.hpp>
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
@ -41,17 +45,24 @@
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include<initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/multi_index/detail/rnd_index_loader.hpp> #include <boost/multi_index/detail/rnd_index_loader.hpp>
#endif #endif
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \ #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&random_access_index::check_invariant_); \ detail::make_obj_guard(x,&random_access_index::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch(); BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this)
#else #else
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
#endif #endif
@ -176,6 +187,12 @@ private:
typedef typename call_traits< typedef typename call_traits<
value_type>::param_type value_param_type; value_type>::param_type value_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
typedef std::pair<iterator,bool> emplace_return_type;
public: public:
/* construct/copy/destroy /* construct/copy/destroy
@ -190,12 +207,28 @@ public:
return *this; return *this;
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
random_access_index<SuperMeta,TagList>& operator=(
std::initializer_list<value_type> list)
{
this->final()=list;
return *this;
}
#endif
template <class InputIterator> template <class InputIterator>
void assign(InputIterator first,InputIterator last) void assign(InputIterator first,InputIterator last)
{ {
assign_iter(first,last,mpl::not_<is_integral<InputIterator> >()); assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void assign(std::initializer_list<value_type> list)
{
assign(list.begin(),list.end());
}
#endif
void assign(size_type n,value_param_type value) void assign(size_type n,value_param_type value)
{ {
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
@ -241,12 +274,32 @@ public:
size_type size()const{return this->final_size_();} size_type size()const{return this->final_size_();}
size_type max_size()const{return this->final_max_size_();} size_type max_size()const{return this->final_max_size_();}
size_type capacity()const{return ptrs.capacity();} size_type capacity()const{return ptrs.capacity();}
void reserve(size_type n){ptrs.reserve(n);}
void resize(size_type n,value_param_type x=value_type()) void reserve(size_type n)
{ {
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
if(n>size())insert(end(),n-size(),x); ptrs.reserve(n);
}
void shrink_to_fit()
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
ptrs.shrink_to_fit();
}
void resize(size_type n)
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
if(n>size())
for(size_type m=n-size();m--;)
this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK);
else if(n<size())erase(begin()+n,end());
}
void resize(size_type n,value_param_type x)
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
if(n>size())for(size_type m=n-size();m--;)this->final_insert_(x);
else if(n<size())erase(begin()+n,end()); else if(n<size())erase(begin()+n,end());
} }
@ -271,14 +324,28 @@ public:
/* modifiers */ /* modifiers */
std::pair<iterator,bool> push_front(value_param_type x) BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace_front,emplace_front_impl)
std::pair<iterator,bool> push_front(const value_type& x)
{return insert(begin(),x);} {return insert(begin(),x);}
std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x)
{return insert(begin(),boost::move(x));}
void pop_front(){erase(begin());} void pop_front(){erase(begin());}
std::pair<iterator,bool> push_back(value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace_back,emplace_back_impl)
std::pair<iterator,bool> push_back(const value_type& x)
{return insert(end(),x);} {return insert(end(),x);}
std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x)
{return insert(end(),boost::move(x));}
void pop_back(){erase(--end());} void pop_back(){erase(--end());}
std::pair<iterator,bool> insert(iterator position,value_param_type x) BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
emplace_return_type,emplace,emplace_impl,iterator,position)
std::pair<iterator,bool> insert(iterator position,const value_type& x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@ -290,6 +357,18 @@ public:
return std::pair<iterator,bool>(make_iterator(p.first),p.second); return std::pair<iterator,bool>(make_iterator(p.first),p.second);
} }
std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
if(p.second&&position.get_node()!=header()){
relocate(position.get_node(),p.first);
}
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
void insert(iterator position,size_type n,value_param_type x) void insert(iterator position,size_type n,value_param_type x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -315,6 +394,13 @@ public:
insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >()); insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(iterator position,std::initializer_list<value_type> list)
{
insert(position,list.begin(),list.end());
}
#endif
iterator erase(iterator position) iterator erase(iterator position)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -339,7 +425,7 @@ public:
return last; return last;
} }
bool replace(iterator position,value_param_type x) bool replace(iterator position,const value_type& x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@ -349,6 +435,16 @@ public:
x,static_cast<final_node_type*>(position.get_node())); x,static_cast<final_node_type*>(position.get_node()));
} }
bool replace(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
return this->final_replace_rv_(
x,static_cast<final_node_type*>(position.get_node()));
}
template<typename Modifier> template<typename Modifier>
bool modify(iterator position,Modifier mod) bool modify(iterator position,Modifier mod)
{ {
@ -394,6 +490,7 @@ public:
void swap(random_access_index<SuperMeta,TagList>& x) void swap(random_access_index<SuperMeta,TagList>& x)
{ {
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x);
this->final_swap_(x.final()); this->final_swap_(x.final());
} }
@ -638,6 +735,18 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
*/ */
} }
random_access_index(
const random_access_index<SuperMeta,TagList>& x,do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()),
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super(),
#endif
ptrs(x.get_allocator(),header()->impl(),0)
{
}
~random_access_index() ~random_access_index()
{ {
/* the container is guaranteed to be empty by now */ /* the container is guaranteed to be empty by now */
@ -671,18 +780,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::copy_(x,map); super::copy_(x,map);
} }
node_type* insert_(value_param_type v,node_type* x) template<typename Variant>
node_type* insert_(value_param_type v,node_type* x,Variant variant)
{ {
ptrs.room_for_one(); ptrs.room_for_one();
node_type* res=static_cast<node_type*>(super::insert_(v,x)); node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
if(res==x)ptrs.push_back(x->impl()); if(res==x)ptrs.push_back(x->impl());
return res; return res;
} }
node_type* insert_(value_param_type v,node_type* position,node_type* x) template<typename Variant>
node_type* insert_(
value_param_type v,node_type* position,node_type* x,Variant variant)
{ {
ptrs.room_for_one(); ptrs.room_for_one();
node_type* res=static_cast<node_type*>(super::insert_(v,position,x)); node_type* res=
static_cast<node_type*>(super::insert_(v,position,x,variant));
if(res==x)ptrs.push_back(x->impl()); if(res==x)ptrs.push_back(x->impl());
return res; return res;
} }
@ -726,9 +839,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::swap_(x); super::swap_(x);
} }
bool replace_(value_param_type v,node_type* x) void swap_elements_(random_access_index<SuperMeta,TagList>& x)
{ {
return super::replace_(v,x); ptrs.swap(x.ptrs);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
#endif
super::swap_elements_(x);
}
template<typename Variant>
bool replace_(value_param_type v,node_type* x,Variant variant)
{
return super::replace_(v,x,variant);
} }
bool modify_(node_type* x) bool modify_(node_type* x)
@ -842,7 +967,7 @@ private:
{ {
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
clear(); clear();
for(;first!=last;++first)push_back(*first); for(;first!=last;++first)this->final_insert_ref_(*first);
} }
void assign_iter(size_type n,value_param_type value,mpl::false_) void assign_iter(size_type n,value_param_type value,mpl::false_)
@ -860,7 +985,7 @@ private:
size_type s=0; size_type s=0;
BOOST_TRY{ BOOST_TRY{
for(;first!=last;++first){ for(;first!=last;++first){
if(push_back(*first).second)++s; if(this->final_insert_ref_(*first).second)++s;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
@ -891,6 +1016,35 @@ private:
relocate(position,end()-s,end()); relocate(position,end()-s,end());
} }
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_front_impl(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_back_impl(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
if(p.second&&position.get_node()!=header()){
relocate(position.get_node(),p.first);
}
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
ptr_array ptrs; ptr_array ptrs;
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
@ -1015,5 +1169,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable(
} }
#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT #undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF
#endif #endif

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2011 Joaquin M Lopez Munoz. /* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
@ -20,17 +20,21 @@
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp> #include <boost/foreach_fwd.hpp>
#include <boost/iterator/reverse_iterator.hpp> #include <boost/iterator/reverse_iterator.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp> #include <boost/mpl/not.hpp>
#include <boost/mpl/push_front.hpp> #include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/bidir_node_iterator.hpp> #include <boost/multi_index/detail/bidir_node_iterator.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/index_node_base.hpp> #include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/safe_ctr_proxy.hpp> #include <boost/multi_index/detail/safe_ctr_proxy.hpp>
#include <boost/multi_index/detail/safe_mode.hpp> #include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp> #include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/seq_index_node.hpp> #include <boost/multi_index/detail/seq_index_node.hpp>
#include <boost/multi_index/detail/seq_index_ops.hpp> #include <boost/multi_index/detail/seq_index_ops.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/sequenced_index_fwd.hpp> #include <boost/multi_index/sequenced_index_fwd.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/is_integral.hpp>
@ -38,16 +42,23 @@
#include <functional> #include <functional>
#include <utility> #include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include<initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/bind.hpp> #include <boost/bind.hpp>
#endif #endif
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&sequenced_index::check_invariant_); \ detail::make_obj_guard(x,&sequenced_index::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch(); BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this)
#else #else
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
#endif #endif
@ -166,6 +177,12 @@ private:
typedef typename call_traits<value_type>::param_type value_param_type; typedef typename call_traits<value_type>::param_type value_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
typedef std::pair<iterator,bool> emplace_return_type;
public: public:
/* construct/copy/destroy /* construct/copy/destroy
@ -180,12 +197,28 @@ public:
return *this; return *this;
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
sequenced_index<SuperMeta,TagList>& operator=(
std::initializer_list<value_type> list)
{
this->final()=list;
return *this;
}
#endif
template <class InputIterator> template <class InputIterator>
void assign(InputIterator first,InputIterator last) void assign(InputIterator first,InputIterator last)
{ {
assign_iter(first,last,mpl::not_<is_integral<InputIterator> >()); assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void assign(std::initializer_list<value_type> list)
{
assign(list.begin(),list.end());
}
#endif
void assign(size_type n,value_param_type value) void assign(size_type n,value_param_type value)
{ {
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
@ -231,22 +264,21 @@ public:
size_type size()const{return this->final_size_();} size_type size()const{return this->final_size_();}
size_type max_size()const{return this->final_max_size_();} size_type max_size()const{return this->final_max_size_();}
void resize(size_type n,value_param_type x=value_type()) void resize(size_type n)
{
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
if(n>size()){
for(size_type m=n-size();m--;)
this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK);
}
else if(n<size()){for(size_type m=size()-n;m--;)pop_back();}
}
void resize(size_type n,value_param_type x)
{ {
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
if(n>size())insert(end(),n-size(),x); if(n>size())insert(end(),n-size(),x);
else if(n<size()){ else if(n<size())for(size_type m=size()-n;m--;)pop_back();
iterator it;
if(n<=size()/2){
it=begin();
std::advance(it,n);
}
else{
it=end();
for(size_type m=size()-n;m--;--it){}
}
erase(it,end());
}
} }
/* access: no non-const versions provided as sequenced_index /* access: no non-const versions provided as sequenced_index
@ -258,14 +290,28 @@ public:
/* modifiers */ /* modifiers */
std::pair<iterator,bool> push_front(value_param_type x) BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace_front,emplace_front_impl)
std::pair<iterator,bool> push_front(const value_type& x)
{return insert(begin(),x);} {return insert(begin(),x);}
std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x)
{return insert(begin(),boost::move(x));}
void pop_front(){erase(begin());} void pop_front(){erase(begin());}
std::pair<iterator,bool> push_back(value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace_back,emplace_back_impl)
std::pair<iterator,bool> push_back(const value_type& x)
{return insert(end(),x);} {return insert(end(),x);}
std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x)
{return insert(end(),boost::move(x));}
void pop_back(){erase(--end());} void pop_back(){erase(--end());}
std::pair<iterator,bool> insert(iterator position,value_param_type x) BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
emplace_return_type,emplace,emplace_impl,iterator,position)
std::pair<iterator,bool> insert(iterator position,const value_type& x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@ -277,6 +323,18 @@ public:
return std::pair<iterator,bool>(make_iterator(p.first),p.second); return std::pair<iterator,bool>(make_iterator(p.first),p.second);
} }
std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
if(p.second&&position.get_node()!=header()){
relink(position.get_node(),p.first);
}
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
void insert(iterator position,size_type n,value_param_type x) void insert(iterator position,size_type n,value_param_type x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -291,6 +349,13 @@ public:
insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >()); insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(iterator position,std::initializer_list<value_type> list)
{
insert(position,list.begin(),list.end());
}
#endif
iterator erase(iterator position) iterator erase(iterator position)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -315,7 +380,7 @@ public:
return first; return first;
} }
bool replace(iterator position,value_param_type x) bool replace(iterator position,const value_type& x)
{ {
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@ -325,6 +390,16 @@ public:
x,static_cast<final_node_type*>(position.get_node())); x,static_cast<final_node_type*>(position.get_node()));
} }
bool replace(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
return this->final_replace_rv_(
x,static_cast<final_node_type*>(position.get_node()));
}
template<typename Modifier> template<typename Modifier>
bool modify(iterator position,Modifier mod) bool modify(iterator position,Modifier mod)
{ {
@ -370,6 +445,7 @@ public:
void swap(sequenced_index<SuperMeta,TagList>& x) void swap(sequenced_index<SuperMeta,TagList>& x)
{ {
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x);
this->final_swap_(x.final()); this->final_swap_(x.final());
} }
@ -555,8 +631,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
#endif #endif
{ {
/* The actual copying takes place in subsequent call to copy_(). /* the actual copying takes place in subsequent call to copy_() */
*/ }
sequenced_index(
const sequenced_index<SuperMeta,TagList>& x,do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag())
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
,safe_super()
#endif
{
empty_initialize();
} }
~sequenced_index() ~sequenced_index()
@ -591,16 +678,20 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::copy_(x,map); super::copy_(x,map);
} }
node_type* insert_(value_param_type v,node_type* x) template<typename Variant>
node_type* insert_(value_param_type v,node_type* x,Variant variant)
{ {
node_type* res=static_cast<node_type*>(super::insert_(v,x)); node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
if(res==x)link(x); if(res==x)link(x);
return res; return res;
} }
node_type* insert_(value_param_type v,node_type* position,node_type* x) template<typename Variant>
node_type* insert_(
value_param_type v,node_type* position,node_type* x,Variant variant)
{ {
node_type* res=static_cast<node_type*>(super::insert_(v,position,x)); node_type* res=
static_cast<node_type*>(super::insert_(v,position,x,variant));
if(res==x)link(x); if(res==x)link(x);
return res; return res;
} }
@ -643,9 +734,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::swap_(x); super::swap_(x);
} }
bool replace_(value_param_type v,node_type* x) void swap_elements_(sequenced_index<SuperMeta,TagList>& x)
{ {
return super::replace_(v,x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
#endif
super::swap_elements_(x);
}
template<typename Variant>
bool replace_(value_param_type v,node_type* x,Variant variant)
{
return super::replace_(v,x,variant);
} }
bool modify_(node_type* x) bool modify_(node_type* x)
@ -781,7 +882,7 @@ private:
{ {
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
clear(); clear();
for(;first!=last;++first)push_back(*first); for(;first!=last;++first)this->final_insert_ref_(*first);
} }
void assign_iter(size_type n,value_param_type value,mpl::false_) void assign_iter(size_type n,value_param_type value,mpl::false_)
@ -796,7 +897,13 @@ private:
iterator position,InputIterator first,InputIterator last,mpl::true_) iterator position,InputIterator first,InputIterator last,mpl::true_)
{ {
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
for(;first!=last;++first)insert(position,*first); for(;first!=last;++first){
std::pair<final_node_type*,bool> p=
this->final_insert_ref_(*first);
if(p.second&&position.get_node()!=header()){
relink(position.get_node(),p.first);
}
}
} }
void insert_iter( void insert_iter(
@ -808,6 +915,35 @@ private:
for(size_type i=0;i<n;++i)insert(position,x); for(size_type i=0;i<n;++i)insert(position,x);
} }
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_front_impl(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_back_impl(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
if(p.second&&position.get_node()!=header()){
relink(position.get_node(),p.first);
}
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
BOOST_WORKAROUND(__MWERKS__,<=0x3003) BOOST_WORKAROUND(__MWERKS__,<=0x3003)
#pragma parse_mfunc_templ reset #pragma parse_mfunc_templ reset
@ -929,5 +1065,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable(
} }
#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF
#endif #endif

View File

@ -1,6 +1,6 @@
/* Multiply indexed container. /* Multiply indexed container.
* *
* Copyright 2003-2011 Joaquin M Lopez Munoz. * Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
@ -20,6 +20,7 @@
#include <boost/detail/allocator_utilities.hpp> #include <boost/detail/allocator_utilities.hpp>
#include <boost/detail/no_exceptions_support.hpp> #include <boost/detail/no_exceptions_support.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/move/core.hpp>
#include <boost/mpl/at.hpp> #include <boost/mpl/at.hpp>
#include <boost/mpl/contains.hpp> #include <boost/mpl/contains.hpp>
#include <boost/mpl/find_if.hpp> #include <boost/mpl/find_if.hpp>
@ -31,6 +32,7 @@
#include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/adl_swap.hpp> #include <boost/multi_index/detail/adl_swap.hpp>
#include <boost/multi_index/detail/base_type.hpp> #include <boost/multi_index/detail/base_type.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/converter.hpp> #include <boost/multi_index/detail/converter.hpp>
#include <boost/multi_index/detail/header_holder.hpp> #include <boost/multi_index/detail/header_holder.hpp>
#include <boost/multi_index/detail/has_tag.hpp> #include <boost/multi_index/detail/has_tag.hpp>
@ -38,10 +40,15 @@
#include <boost/multi_index/detail/prevent_eti.hpp> #include <boost/multi_index/detail/prevent_eti.hpp>
#include <boost/multi_index/detail/safe_mode.hpp> #include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp> #include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <boost/utility/base_from_member.hpp> #include <boost/utility/base_from_member.hpp>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/multi_index/detail/archive_constructed.hpp> #include <boost/multi_index/detail/archive_constructed.hpp>
#include <boost/multi_index/detail/serialization_version.hpp> #include <boost/multi_index/detail/serialization_version.hpp>
@ -54,11 +61,14 @@
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#include <boost/multi_index/detail/invariant_assert.hpp> #include <boost/multi_index/detail/invariant_assert.hpp>
#define BOOST_MULTI_INDEX_CHECK_INVARIANT \ #define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&multi_index_container::check_invariant_); \ detail::make_obj_guard(x,&multi_index_container::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch(); BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this)
#else #else
#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_CHECK_INVARIANT #define BOOST_MULTI_INDEX_CHECK_INVARIANT
#endif #endif
@ -66,6 +76,11 @@ namespace boost{
namespace multi_index{ namespace multi_index{
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
#pragma warning(push)
#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */
#endif
template<typename Value,typename IndexSpecifierList,typename Allocator> template<typename Value,typename IndexSpecifierList,typename Allocator>
class multi_index_container: class multi_index_container:
private ::boost::base_from_member< private ::boost::base_from_member<
@ -98,6 +113,8 @@ class multi_index_container:
#endif #endif
private: private:
BOOST_COPYABLE_AND_MOVABLE(multi_index_container)
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template <typename,typename,typename> friend class detail::index_base; template <typename,typename,typename> friend class detail::index_base;
template <typename,typename> friend struct detail::header_holder; template <typename,typename> friend struct detail::header_holder;
@ -171,21 +188,28 @@ public:
/* construct/copy/destroy */ /* construct/copy/destroy */
explicit multi_index_container( /* Do not merge this ctor with the following waiting for resolution of
* EWG issue 2193.
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
/* VisualAge seems to have an ETI issue with the default values
* for arguments args_list and al.
*/ */
const ctor_args_list& args_list= multi_index_container():
typename mpl::identity<multi_index_container>::type:: bfm_allocator(allocator_type()),
ctor_args_list(), super(ctor_args_list(),bfm_allocator::member),
node_count(0)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
}
explicit multi_index_container(
const ctor_args_list& args_list,
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
/* VisualAge seems to have an ETI issue with the default value of al */
const allocator_type& al= const allocator_type& al=
typename mpl::identity<multi_index_container>::type:: typename mpl::identity<multi_index_container>::type::
allocator_type()): allocator_type()):
#else #else
const ctor_args_list& args_list=ctor_args_list(),
const allocator_type& al=allocator_type()): const allocator_type& al=allocator_type()):
#endif #endif
@ -232,7 +256,9 @@ public:
BOOST_TRY{ BOOST_TRY{
iterator hint=super::end(); iterator hint=super::end();
for(;first!=last;++first){ for(;first!=last;++first){
hint=super::make_iterator(insert_(*first,hint.get_node()).first); hint=super::make_iterator(
insert_ref_(*first,hint.get_node()).first);
++hint;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
@ -242,6 +268,34 @@ public:
BOOST_CATCH_END BOOST_CATCH_END
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
multi_index_container(
std::initializer_list<Value> list,
const ctor_args_list& args_list=ctor_args_list(),
const allocator_type& al=allocator_type()):
bfm_allocator(al),
super(args_list,bfm_allocator::member),
node_count(0)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
BOOST_TRY{
typedef typename std::initializer_list<Value>::iterator init_iterator;
iterator hint=super::end();
for(init_iterator first=list.begin(),last=list.end();
first!=last;++first){
hint=super::make_iterator(insert_(*first,hint.get_node()).first);
++hint;
}
}
BOOST_CATCH(...){
clear_();
BOOST_RETHROW;
}
BOOST_CATCH_END
}
#endif
multi_index_container( multi_index_container(
const multi_index_container<Value,IndexSpecifierList,Allocator>& x): const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
bfm_allocator(x.bfm_allocator::member), bfm_allocator(x.bfm_allocator::member),
@ -264,19 +318,70 @@ public:
BOOST_MULTI_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_CHECK_INVARIANT;
} }
multi_index_container(BOOST_RV_REF(multi_index_container) x):
bfm_allocator(x.bfm_allocator::member),
bfm_header(),
super(x,detail::do_not_copy_elements_tag()),
node_count(0)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
swap_elements_(x);
}
~multi_index_container() ~multi_index_container()
{ {
delete_all_nodes_(); delete_all_nodes_();
} }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
/* As per http://www.boost.org/doc/html/move/emulation_limitations.html
* #move.emulation_limitations.assignment_operator
*/
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=( multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
multi_index_container<Value,IndexSpecifierList,Allocator> x) const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
{
multi_index_container y(x);
this->swap(y);
return *this;
}
#endif
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
BOOST_COPY_ASSIGN_REF(multi_index_container) x)
{
multi_index_container y(x);
this->swap(y);
return *this;
}
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
BOOST_RV_REF(multi_index_container) x)
{ {
BOOST_MULTI_INDEX_CHECK_INVARIANT;
this->swap(x); this->swap(x);
return *this; return *this;
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
std::initializer_list<Value> list)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
typedef typename std::initializer_list<Value>::iterator init_iterator;
multi_index_container x(*this,detail::do_not_copy_elements_tag());
iterator hint=x.end();
for(init_iterator first=list.begin(),last=list.end();
first!=last;++first){
hint=x.make_iterator(x.insert_(*first,hint.get_node()).first);
++hint;
}
x.swap_elements_(*this);
return*this;
}
#endif
allocator_type get_allocator()const allocator_type get_allocator()const
{ {
return allocator_type(bfm_allocator::member); return allocator_type(bfm_allocator::member);
@ -450,6 +555,19 @@ public:
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
typedef typename super::copy_map_type copy_map_type; typedef typename super::copy_map_type copy_map_type;
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
multi_index_container(
const multi_index_container<Value,IndexSpecifierList,Allocator>& x,
detail::do_not_copy_elements_tag):
bfm_allocator(x.bfm_allocator::member),
bfm_header(),
super(x,detail::do_not_copy_elements_tag()),
node_count(0)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
}
#endif
node_type* header()const node_type* header()const
{ {
return &*bfm_header::member; return &*bfm_header::member;
@ -481,11 +599,119 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
return static_cast<std::size_t >(-1); return static_cast<std::size_t >(-1);
} }
std::pair<node_type*,bool> insert_(const Value& v) template<typename Variant>
std::pair<node_type*,bool> insert_(const Value& v,Variant variant)
{ {
node_type* x=allocate_node(); node_type* x=allocate_node();
BOOST_TRY{ BOOST_TRY{
node_type* res=super::insert_(v,x); node_type* res=super::insert_(v,x,variant);
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
BOOST_CATCH(...){
deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
std::pair<node_type*,bool> insert_(const Value& v)
{
return insert_(v,detail::lvalue_tag());
}
std::pair<node_type*,bool> insert_rv_(const Value& v)
{
return insert_(v,detail::rvalue_tag());
}
template<typename T>
std::pair<node_type*,bool> insert_ref_(T& t)
{
node_type* x=allocate_node();
BOOST_TRY{
new(&x->value()) value_type(t);
BOOST_TRY{
node_type* res=super::insert_(x->value(),x,detail::emplaced_tag());
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
boost::detail::allocator::destroy(&x->value());
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
BOOST_CATCH(...){
boost::detail::allocator::destroy(&x->value());
BOOST_RETHROW;
}
BOOST_CATCH_END
}
BOOST_CATCH(...){
deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
std::pair<node_type*,bool> insert_ref_(const value_type& x)
{
return insert_(x);
}
std::pair<node_type*,bool> insert_ref_(value_type& x)
{
return insert_(x);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<node_type*,bool> emplace_(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
node_type* x=allocate_node();
BOOST_TRY{
detail::vartempl_placement_new(
&x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
BOOST_TRY{
node_type* res=super::insert_(x->value(),x,detail::emplaced_tag());
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
boost::detail::allocator::destroy(&x->value());
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
BOOST_CATCH(...){
boost::detail::allocator::destroy(&x->value());
BOOST_RETHROW;
}
BOOST_CATCH_END
}
BOOST_CATCH(...){
deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
template<typename Variant>
std::pair<node_type*,bool> insert_(
const Value& v,node_type* position,Variant variant)
{
node_type* x=allocate_node();
BOOST_TRY{
node_type* res=super::insert_(v,position,x,variant);
if(res==x){ if(res==x){
++node_count; ++node_count;
return std::pair<node_type*,bool>(res,true); return std::pair<node_type*,bool>(res,true);
@ -503,19 +729,88 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
} }
std::pair<node_type*,bool> insert_(const Value& v,node_type* position) std::pair<node_type*,bool> insert_(const Value& v,node_type* position)
{
return insert_(v,position,detail::lvalue_tag());
}
std::pair<node_type*,bool> insert_rv_(const Value& v,node_type* position)
{
return insert_(v,position,detail::rvalue_tag());
}
template<typename T>
std::pair<node_type*,bool> insert_ref_(
T& t,node_type* position)
{ {
node_type* x=allocate_node(); node_type* x=allocate_node();
BOOST_TRY{ BOOST_TRY{
node_type* res=super::insert_(v,position,x); new(&x->value()) value_type(t);
BOOST_TRY{
node_type* res=super::insert_(
x->value(),position,x,detail::emplaced_tag());
if(res==x){ if(res==x){
++node_count; ++node_count;
return std::pair<node_type*,bool>(res,true); return std::pair<node_type*,bool>(res,true);
} }
else{ else{
boost::detail::allocator::destroy(&x->value());
deallocate_node(x); deallocate_node(x);
return std::pair<node_type*,bool>(res,false); return std::pair<node_type*,bool>(res,false);
} }
} }
BOOST_CATCH(...){
boost::detail::allocator::destroy(&x->value());
BOOST_RETHROW;
}
BOOST_CATCH_END
}
BOOST_CATCH(...){
deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
std::pair<node_type*,bool> insert_ref_(
const value_type& x,node_type* position)
{
return insert_(x,position);
}
std::pair<node_type*,bool> insert_ref_(
value_type& x,node_type* position)
{
return insert_(x,position);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<node_type*,bool> emplace_hint_(
node_type* position,
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
node_type* x=allocate_node();
BOOST_TRY{
detail::vartempl_placement_new(
&x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
BOOST_TRY{
node_type* res=super::insert_(
x->value(),position,x,detail::emplaced_tag());
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
boost::detail::allocator::destroy(&x->value());
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
BOOST_CATCH(...){
boost::detail::allocator::destroy(&x->value());
BOOST_RETHROW;
}
BOOST_CATCH_END
}
BOOST_CATCH(...){ BOOST_CATCH(...){
deallocate_node(x); deallocate_node(x);
BOOST_RETHROW; BOOST_RETHROW;
@ -558,9 +853,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
std::swap(node_count,x.node_count); std::swap(node_count,x.node_count);
} }
void swap_elements_(
multi_index_container<Value,IndexSpecifierList,Allocator>& x)
{
std::swap(bfm_header::member,x.bfm_header::member);
super::swap_elements_(x);
std::swap(node_count,x.node_count);
}
bool replace_(const Value& k,node_type* x) bool replace_(const Value& k,node_type* x)
{ {
return super::replace_(k,x); return super::replace_(k,x,detail::lvalue_tag());
}
bool replace_rv_(const Value& k,node_type* x)
{
return super::replace_(k,x,detail::rvalue_tag());
} }
template<typename Modifier> template<typename Modifier>
@ -728,6 +1036,10 @@ private:
#endif #endif
}; };
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
#pragma warning(pop) /* C4522 */
#endif
/* retrieval of indices by number */ /* retrieval of indices by number */
template<typename MultiIndexContainer,int N> template<typename MultiIndexContainer,int N>
@ -1139,5 +1451,6 @@ using multi_index::project;
} /* namespace boost */ } /* namespace boost */
#undef BOOST_MULTI_INDEX_CHECK_INVARIANT #undef BOOST_MULTI_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF
#endif #endif

View File

@ -1,6 +1,6 @@
/* Used in Boost.MultiIndex tests. /* Used in Boost.MultiIndex tests.
* *
* Copyright 2003-2008 Joaquin M Lopez Munoz. * Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
@ -12,6 +12,8 @@
#define BOOST_MULTI_INDEX_TEST_EMPLOYEE_HPP #define BOOST_MULTI_INDEX_TEST_EMPLOYEE_HPP
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/mpl/vector.hpp> #include <boost/mpl/vector.hpp>
#include <boost/multi_index_container.hpp> #include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/hashed_index.hpp>
@ -36,6 +38,32 @@ struct employee
id(id_),name(name_),age(age_),ssn(ssn_) id(id_),name(name_),age(age_),ssn(ssn_)
{} {}
employee(const employee& x):
id(x.id),name(x.name),age(x.age),ssn(x.ssn)
{}
employee(BOOST_RV_REF(employee) x):
id(x.id),name(boost::move(x.name)),age(x.age),ssn(x.ssn)
{}
employee& operator=(BOOST_COPY_ASSIGN_REF(employee) x)
{
id=x.id;
name=x.name;
age=x.age;
ssn=x.ssn;
return *this;
};
employee& operator=(BOOST_RV_REF(employee) x)
{
id=x.id;
name=boost::move(x.name);
age=x.age;
ssn=x.ssn;
return *this;
}
bool operator==(const employee& x)const bool operator==(const employee& x)const
{ {
return id==x.id&&name==x.name&&age==x.age; return id==x.id&&name==x.name&&age==x.age;
@ -62,6 +90,9 @@ struct employee
os<<e.id<<" "<<e.name<<" "<<e.age<<std::endl; os<<e.id<<" "<<e.name<<" "<<e.age<<std::endl;
return os; return os;
} }
private:
BOOST_COPYABLE_AND_MOVABLE(employee)
}; };
struct name{}; struct name{};

View File

@ -47,10 +47,11 @@ void test_capacity()
BOOST_TEST(ss.size()==10); BOOST_TEST(ss.size()==10);
BOOST_TEST(ss.size()<=ss.max_size()); BOOST_TEST(ss.size()<=ss.max_size());
ss.resize(20); ss.resize(20,666);
BOOST_TEST(ss.size()==20); BOOST_TEST(ss.size()==20);
BOOST_TEST(ss.back()==666);
ss.resize(5); ss.resize(5,10);
BOOST_TEST(ss.size()==5); BOOST_TEST(ss.size()==5);
ss.resize(4); ss.resize(4);
@ -63,11 +64,16 @@ void test_capacity()
BOOST_TEST(rs.size()<=rs.max_size()); BOOST_TEST(rs.size()<=rs.max_size());
BOOST_TEST(rs.size()<=rs.capacity()); BOOST_TEST(rs.size()<=rs.capacity());
rs.resize(20); rs.resize(20,666);
BOOST_TEST(rs.size()==20); BOOST_TEST(rs.size()==20);
BOOST_TEST(rs.back()==666);
BOOST_TEST(rs.size()<=rs.capacity()); BOOST_TEST(rs.size()<=rs.capacity());
unsigned int c=rs.capacity(); unsigned int c=rs.capacity();
rs.resize(10,20);
BOOST_TEST(rs.size()==10);
BOOST_TEST(rs.capacity()==c);
rs.resize(5); rs.resize(5);
BOOST_TEST(rs.size()==5); BOOST_TEST(rs.size()==5);
BOOST_TEST(rs.capacity()==c); BOOST_TEST(rs.capacity()==c);
@ -80,4 +86,12 @@ void test_capacity()
rs.reserve(99); rs.reserve(99);
BOOST_TEST(rs.size()==5); BOOST_TEST(rs.size()==5);
BOOST_TEST(rs.capacity()==c); BOOST_TEST(rs.capacity()==c);
rs.shrink_to_fit();
BOOST_TEST(rs.size()==5);
BOOST_TEST(rs.capacity()==rs.size());
rs.clear();
rs.shrink_to_fit();
BOOST_TEST(rs.capacity()==0);
} }

View File

@ -12,6 +12,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm> #include <algorithm>
#include <boost/move/utility.hpp>
#include <list> #include <list>
#include <numeric> #include <numeric>
#include <vector> #include <vector>
@ -30,6 +31,13 @@ using namespace boost::multi_index;
#pragma parse_func_templ off #pragma parse_func_templ off
#endif #endif
typedef multi_index_container<int> copyable_and_movable;
struct holder
{
copyable_and_movable c;
};
template<typename Sequence> template<typename Sequence>
static void test_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence)) static void test_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
{ {
@ -39,10 +47,16 @@ static void test_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
std::size_t sa=sizeof(a)/sizeof(a[0]); std::size_t sa=sizeof(a)/sizeof(a[0]);
s.assign(&a[0],&a[sa]); s.assign(&a[0],&a[sa]);
BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0])); BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
s.assign((const int*)(&a[0]),(const int*)(&a[sa]));
BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
s.assign({0,1,2,3,4,5});
#else
s.assign(&a[0],&a[sa]); s.assign(&a[0],&a[sa]);
#endif
BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0])); BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
@ -78,6 +92,16 @@ static void test_integral_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
BOOST_TEST(s.size()==7&&std::accumulate(s.begin(),s.end(),0)==60); BOOST_TEST(s.size()==7&&std::accumulate(s.begin(),s.end(),0)==60);
} }
employee_set produce_employee_set()
{
employee_set es;
es.insert(employee(0,"Petr",60,2837));
es.insert(employee(1,"Jiri",25,2143));
es.insert(employee(2,"Radka",40,4875));
es.insert(employee(3,"Milan",38,3474));
return es;
}
void test_copy_assignment() void test_copy_assignment()
{ {
employee_set es; employee_set es;
@ -113,7 +137,7 @@ void test_copy_assignment()
BOOST_TEST(es4==es2); BOOST_TEST(es4==es2);
employee_set es5; employee_set es5=employee_set(employee_set::ctor_args_list());
employee_set_by_age& i2=get<age>(es5); employee_set_by_age& i2=get<age>(es5);
i2=get<2>(es2); i2=get<2>(es2);
@ -131,22 +155,75 @@ void test_copy_assignment()
BOOST_TEST(i5==get<5>(es2)); BOOST_TEST(i5==get<5>(es2));
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
employee_set es8({{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102}});
employee_set es9;
es9={{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102},
{0,"Rose",40,4512}};
BOOST_TEST(es8.size()==3);
BOOST_TEST(es9==es8);
es9.clear();
get<0>(es9)={{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102},
{0,"Rose",40,4512}};
BOOST_TEST(es9==es8);
es9.clear();
get<0>(es9)={{0,"Rose",40,4512},{2,"Jo",25,7102},{1,"Mary",38,3345}};
BOOST_TEST(es9==es8);
es9.clear();
get<1>(es9)={{1,"Mary",38,3345},{0,"Rose",40,4512},{2,"Jo",25,7102},
{0,"Rose",40,4512}};
BOOST_TEST(es9==es8);
es9.clear();
get<2>(es9)={{2,"Jo",25,7102},{0,"Rose",40,4512},{1,"Mary",38,3345}};
BOOST_TEST(es9==es8);
es9.clear();
get<3>(es9)={{0,"Rose",40,4512},{1,"Mary",38,3345},{1,"Mary",38,3345},
{2,"Jo",25,7102}};
BOOST_TEST(es9==es8);
es9.clear();
get<4>(es9)={{1,"Mary",38,3345},{2,"Jo",25,7102},{0,"Rose",40,4512}};
BOOST_TEST(es9==es8);
es9.clear();
get<5>(es9)={{1,"Mary",38,3345},{2,"Jo",25,7102},{0,"Rose",40,4512},
{2,"Jo",25,7102}};
BOOST_TEST(es9==es8);
#endif
employee_set es10(produce_employee_set()),es11(produce_employee_set());
BOOST_TEST(es10==es11);
employee_set es12(boost::move(es10));
BOOST_TEST(es10.empty());
BOOST_TEST(es11==es12);
es10=boost::move(es12);
BOOST_TEST(es12.empty());
BOOST_TEST(es11==es10);
std::list<employee> l; std::list<employee> l;
l.push_back(employee(3,"Anna",31,5388)); l.push_back(employee(3,"Anna",31,5388));
l.push_back(employee(1,"Rachel",27,9012)); l.push_back(employee(1,"Rachel",27,9012));
l.push_back(employee(2,"Agatha",40,1520)); l.push_back(employee(2,"Agatha",40,1520));
#if BOOST_WORKAROUND(BOOST_MSVC,<1300) #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
employee_set es8; employee_set es13;
es8.insert(l.begin(),l.end()); es13.insert(l.begin(),l.end());
#else #else
employee_set es8(l.begin(),l.end()); employee_set es13(l.begin(),l.end());
#endif #endif
l.sort(); l.sort();
BOOST_TEST(es8.size()==l.size()&& BOOST_TEST(es13.size()==l.size()&&
std::equal(es8.begin(),es8.end(),l.begin())); std::equal(es13.begin(),es13.end(),l.begin()));
/* MSVC++ 6.0 chokes on test_assign without this explicit instantiation */ /* MSVC++ 6.0 chokes on test_assign without this explicit instantiation */
multi_index_container<int,indexed_by<sequenced<> > > s1; multi_index_container<int,indexed_by<sequenced<> > > s1;
@ -158,4 +235,11 @@ void test_copy_assignment()
test_assign<multi_index_container<int,indexed_by<random_access<> > > >(); test_assign<multi_index_container<int,indexed_by<random_access<> > > >();
test_integral_assign< test_integral_assign<
multi_index_container<int,indexed_by<random_access<> > > >(); multi_index_container<int,indexed_by<random_access<> > > >();
/* Testcase for problem described at http://www.boost.org/doc/html/move/
* emulation_limitations.html#move.emulation_limitations.assignment_operator
*/
holder h((holder()));
h=holder();
} }

View File

@ -13,6 +13,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/lightweight_test.hpp> #include <boost/detail/lightweight_test.hpp>
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
#include <boost/move/core.hpp>
#include <boost/next_prior.hpp> #include <boost/next_prior.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <iterator> #include <iterator>
@ -22,6 +23,22 @@
using namespace boost::multi_index; using namespace boost::multi_index;
struct non_copyable_int
{
explicit non_copyable_int(int n_):n(n_){}
non_copyable_int(BOOST_RV_REF(non_copyable_int) x):n(x.n){x.n=0;}
non_copyable_int& operator=(BOOST_RV_REF(non_copyable_int) x)
{
n=x.n;
x.n=0;
return *this;
}
int n;
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(non_copyable_int)
};
class always_one class always_one
{ {
public: public:
@ -115,13 +132,15 @@ void test_modifiers()
employee_set_randomly& i5=get<randomly>(es); employee_set_randomly& i5=get<randomly>(es);
es.insert(employee(0,"Joe",31,1123)); es.insert(employee(0,"Joe",31,1123));
BOOST_TEST(es.insert(employee(0,"Joe",31,1123)).second==false); BOOST_TEST(es.emplace(0,"Joe",31,1123).second==false);
BOOST_TEST(i1.insert(employee(0,"Joe Jr.",5,2563)).second==false); BOOST_TEST(i1.insert(employee(0,"Joe Jr.",5,2563)).second==false);
BOOST_TEST(i2.insert(employee(1,"Victor",5,1123)).second==false); BOOST_TEST(i2.emplace_hint(i2.end(),1,"Victor",5,1123)->name!="Victor");
BOOST_TEST(i3.insert(i3.begin(),employee(1,"Victor",5,1123)).second BOOST_TEST(i3.insert(i3.begin(),employee(1,"Victor",5,1123)).second
==false); ==false);
BOOST_TEST(i3.push_front(employee(0,"Joe Jr.",5,2563)).second==false); BOOST_TEST(i3.push_front(employee(0,"Joe Jr.",5,2563)).second==false);
BOOST_TEST(i3.push_back(employee(0,"Joe Jr.",5,2563)).second==false); BOOST_TEST(i3.push_back(employee(0,"Joe Jr.",5,2563)).second==false);
BOOST_TEST(i5.emplace_front(1,"Victor",5,1123).second==false);
BOOST_TEST(i5.emplace_back(1,"Victor",5,1123).second==false);
employee_set_by_name::iterator it1=i1.find("Joe"); employee_set_by_name::iterator it1=i1.find("Joe");
i1.insert(it1,employee(1,"Joe Jr.",5,2563)); i1.insert(it1,employee(1,"Joe Jr.",5,2563));
@ -156,17 +175,18 @@ void test_modifiers()
i5.erase(i5.begin(),i5.end()); i5.erase(i5.begin(),i5.end());
BOOST_TEST(es.size()==0&&i3.size()==0); BOOST_TEST(es.size()==0&&i3.size()==0);
es.insert(employee(0,"Joe",31,1123)); i5.emplace(i5.end(),0,"Joe",31,1123);
BOOST_TEST(i1.erase(i1.begin())==i1.end()); BOOST_TEST(i1.erase(i1.begin())==i1.end());
BOOST_TEST(i1.size()==0); BOOST_TEST(i1.size()==0);
es.insert(employee(0,"Joe",31,1123)); i1.emplace(0,"Joe",31,1123);
es.insert(employee(1,"Jack",31,5032)); i3.emplace(i3.begin(),1,"Jack",31,5032);
BOOST_TEST(i2.erase(31)==2); i4.emplace_hint(i4.end(),2,"James",31,3847);
BOOST_TEST(i2.erase(31)==3);
BOOST_TEST(i2.size()==0); BOOST_TEST(i2.size()==0);
i3.push_front(employee(1,"Jack",31,5032)); i3.emplace_front(1,"Jack",31,5032);
i3.push_back(employee(0,"Joe",31,1123)); i3.emplace_back(0,"Joe",31,1123);
BOOST_TEST(i3.front()==employee(1,"Jack",31,5032)); BOOST_TEST(i3.front()==employee(1,"Jack",31,5032));
BOOST_TEST(i3.back()==employee(0,"Joe",31,1123)); BOOST_TEST(i3.back()==employee(0,"Joe",31,1123));
@ -206,12 +226,22 @@ void test_modifiers()
i1.insert(ve.begin(),ve.end()); i1.insert(ve.begin(),ve.end());
BOOST_TEST(i2.size()==3); BOOST_TEST(i2.size()==3);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
i1.insert({{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
BOOST_TEST(i2.size()==5);
#endif
BOOST_TEST(i2.erase(i2.begin(),i2.end())==i2.end()); BOOST_TEST(i2.erase(i2.begin(),i2.end())==i2.end());
BOOST_TEST(es.size()==0); BOOST_TEST(es.size()==0);
i2.insert(ve.begin(),ve.end()); i2.insert(ve.begin(),ve.end());
BOOST_TEST(i3.size()==3); BOOST_TEST(i3.size()==3);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
i2.insert({{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
BOOST_TEST(i3.size()==5);
#endif
BOOST_TEST(*(i3.erase(i3.begin()))==employee(1,"Rachel",27,9012)); BOOST_TEST(*(i3.erase(i3.begin()))==employee(1,"Rachel",27,9012));
BOOST_TEST(i3.erase(i3.begin(),i3.end())==i3.end()); BOOST_TEST(i3.erase(i3.begin(),i3.end())==i3.end());
BOOST_TEST(es.size()==0); BOOST_TEST(es.size()==0);
@ -219,6 +249,12 @@ void test_modifiers()
i3.insert(i3.end(),ve.begin(),ve.end()); i3.insert(i3.end(),ve.begin(),ve.end());
BOOST_TEST(es.size()==3); BOOST_TEST(es.size()==3);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
i3.insert(i3.begin(),{{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
BOOST_TEST(i3.front().name=="Vanessa");
BOOST_TEST(i4.size()==5);
#endif
BOOST_TEST(i4.erase(9012)==1); BOOST_TEST(i4.erase(9012)==1);
i4.erase(i4.begin()); i4.erase(i4.begin());
BOOST_TEST(i4.erase(i4.begin(),i4.end())==i4.end()); BOOST_TEST(i4.erase(i4.begin(),i4.end())==i4.end());
@ -232,6 +268,12 @@ void test_modifiers()
i5.insert(i5.begin(),ve.begin(),ve.end()); i5.insert(i5.begin(),ve.begin(),ve.end());
BOOST_TEST(i1.size()==3); BOOST_TEST(i1.size()==3);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
i5.insert(i5.end(),{{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
BOOST_TEST(i5.back().name=="Penelope");
BOOST_TEST(i1.size()==5);
#endif
BOOST_TEST(es.erase(es.begin(),es.end())==es.end()); BOOST_TEST(es.erase(es.begin(),es.end())==es.end());
BOOST_TEST(i2.size()==0); BOOST_TEST(i2.size()==0);
@ -324,6 +366,52 @@ void test_modifiers()
es2.clear(); es2.clear();
BOOST_TEST(es2.size()==0); BOOST_TEST(es2.size()==0);
/* non-copyable elements */
multi_index_container<
non_copyable_int,
indexed_by<
ordered_non_unique<member<non_copyable_int,int,&non_copyable_int::n> >,
hashed_non_unique<member<non_copyable_int,int,&non_copyable_int::n> >,
sequenced<>,
random_access<>
>
> ncic,ncic2;
ncic.emplace(1);
get<1>(ncic).emplace(1);
get<2>(ncic).emplace_back(1);
get<3>(ncic).emplace_back(1);
non_copyable_int nci(1);
ncic.insert(boost::move(nci));
BOOST_TEST(nci.n==0);
nci.n=1;
get<1>(ncic).insert(boost::move(nci));
BOOST_TEST(nci.n==0);
nci.n=1;
get<2>(ncic).push_back(boost::move(nci));
BOOST_TEST(nci.n==0);
nci.n=1;
get<3>(ncic).push_back(boost::move(nci));
BOOST_TEST(nci.n==0);
std::vector<int> vi(4,1);
const std::vector<int>& cvi=vi;
ncic.insert(vi.begin(),vi.end());
ncic.insert(cvi.begin(),cvi.end());
get<2>(ncic).insert(get<2>(ncic).begin(),vi.begin(),vi.end());
get<2>(ncic).insert(get<2>(ncic).begin(),cvi.begin(),cvi.end());
BOOST_TEST(ncic.count(1)==24);
ncic.swap(ncic2);
BOOST_TEST(ncic.empty());
BOOST_TEST(ncic2.count(1)==24);
/* testcase for problem reported at /* testcase for problem reported at
* http://lists.boost.org/boost-users/2006/12/24215.php * http://lists.boost.org/boost-users/2006/12/24215.php
*/ */

View File

@ -78,6 +78,8 @@ void test_update()
project<randomly>(es,get<age>(es).find(57)); project<randomly>(es,get<age>(es).find(57));
BOOST_TEST(es.replace(it,*it)); BOOST_TEST(es.replace(it,*it));
BOOST_TEST(i.replace(it1,*it1));
BOOST_TEST(r.replace(it2,*it2));
BOOST_TEST(!es.replace(it,employee(3,"Joe",31,1123))&&it->id==0); BOOST_TEST(!es.replace(it,employee(3,"Joe",31,1123))&&it->id==0);
BOOST_TEST(es.replace(it,employee(0,"Joe",32,1123))&&it->age==32); BOOST_TEST(es.replace(it,employee(0,"Joe",32,1123))&&it->age==32);
BOOST_TEST(i.replace(it1,employee(3,"Albert",20,9012))&&it1->name== BOOST_TEST(i.replace(it1,employee(3,"Albert",20,9012))&&it1->name==