Full merge from trunk at revision 41356 of entire boost-root tree.

[SVN r41370]
This commit is contained in:
Beman Dawes 2007-11-25 18:38:02 +00:00
parent 9b4c07478c
commit 0468378c0d
40 changed files with 1902 additions and 316 deletions

View File

@ -148,6 +148,18 @@ codebase.
<br style="clear:all;">
</p>
<h2><a name="boost_1_35">Boost 1.35 release</a></h2>
<p>
<a href="tutorial/key_extraction.html#global_fun"><code>global_fun</code></a>
was included after a proposal by Markus Werle. Bruno Mart&iacute;nez Aguerre
suggested the inclusion of
<a href="tutorial/indices.html#iterator_to"><code>iterator_to</code></a>. The
rollback versions of <code>modify</code> and <code>modify_key</code> arose
from discussions with Mat&iacute;as Capeletto. Steven Watanabe spotted an
include guard bug present from the first release of the library.
</p>
<hr>
<div class="prev_link"><a href="release_notes.html"><img src="prev.gif" alt="release notes" border="0"><br>
@ -161,9 +173,9 @@ Index
<br>
<p>Revised December 21st 2006</p>
<p>Revised September 3rd 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -46,12 +46,13 @@ along with suitable workarounds when available.
<li><a href="#gcc_4_darwin">Darwin GCC 4.0</a></li>
</ul>
</li>
<li><a href="#acc_612">HP aC++ A.06.12 for HP-UX</a></li>
<li><a href="#acc_612">HP aC++ A.06.12 for HP-UX and later</a></li>
<li><a href="#va_60">IBM VisualAge C++ V6.0 for AIX</a></li>
<li><a href="#intel_90_lin">Intel C++ Compiler for Linux 9.0 and later</a></li>
<li><a href="#va_90">IBM VisualAge C++ V9.0 for AIX</a></li>
<li><a href="#intel_81_lin">Intel C++ Compiler for Linux 8.1 and later</a></li>
<li><a href="#intel_7x_win">Intel C++ Compiler for Windows 32-bit 7.0/7.1</a></li>
<li><a href="#intel_80_win">Intel C++ Compiler for Windows 32-bit 8.0 and later</a></li>
<li><a href="#intel_em64t_91_win">Intel C++ Compiler Extended Memory 64 Technology 9.1 for Windows</a></li>
<li><a href="#intel_100_win64">Intel C++ Compiler for Windows 64-bit 10.0</a></li>
<li><a href="#cw_83">Metrowerks CodeWarrior 8.3</a></li>
<li><a href="#cw_9x">Metrowerks CodeWarrior 9 and later</a></li>
<li>
@ -79,7 +80,8 @@ along with suitable workarounds when available.
</ul>
</li>
<li><a href="#msvc_80_x86_amd64">Microsoft Visual C++ 8.0 x64 cross-compiler</a></li>
<li><a href="#sun_11">Sun Studio 11 for Solaris</a></li>
<li><a href="#msvc_90">Microsoft Visual C++ 9.0</a></li>
<li><a href="#sun_10">Sun Studio 10 for Solaris and later</a></li>
<li><a href="#portability">Portability techniques</a>
<ul>
<li><a href="#member_offset">Use of <code>member_offset</code></a></li>
@ -100,13 +102,18 @@ along with suitable workarounds when available.
<h2><a name="bcb_64">Borland C++ Builder 6.4 and later</a></h2>
<p>
Currently, Boost.MultiIndex cannot be used with any of BCB 6.4 up to BCB 2006.
Currently, Boost.MultiIndex cannot be used with any of BCB 6.4 up to BCB 2006
and CodeGear C++Builder 2007.
The number of problems encountered during the tests makes it unlikely that
future versions of the library can be made to work under these compilers.
</p>
<h2><a name="comeau_433_win_vc7_71">Comeau C/C++ 4.3.3 for Windows (VC++ 7.0/7.1 backend)</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.34.1. The information might be no longer accurate.
</p>
<p>
No problems have been detected with this compiler. The library fails to compile,
however, when Microsoft Visual C++ 6.0 is used as the backend.
@ -115,8 +122,7 @@ however, when Microsoft Visual C++ 6.0 is used as the backend.
<h2><a name="compaq_65">Compaq C++ 6.5-042 for Tru64 UNIX and later</a></h2>
<p>
No problems have been detected with this compiler. Versions 6.5-042,
7.1-005 and 7.1-006 have been tested.
No problems have been detected with this compiler. Last tested for version 7.1-006.
</p>
<h2><a name="gcc_32">GNU GCC 3.2 and later</a></h2>
@ -126,20 +132,17 @@ No problems have been detected with several versions of this compiler
starting from 3.2. The following versions have been explicitly tested:
<ul>
<li>GCC 3.2 20020927 (prerelease) under Cygwin 1.5.7,</li>
<li>GCC 3.2.3 under Linux,</li>
<li>GCC 3.3.5 (qnx-nto) under QNX 6.3.0 and QNX 6.3.2,
<li>GCC 3.3.6 under Linux,</li>
<li>GCC 3.4.2 (mingw-special) under Win32,
(mingw-special) + STLport 5.0.1 under Win32,</li>
<li>GCC 3.4.3 under Solaris,</li>
<li>GCC 3.4.4 under Linux and Tru64 (see <a href="#gcc_tru64">below</a>),</li>
<li>GCC 3.4.5 under Linux and Linux x86-64, (mingw-special) under Win32,
(mingw-special) + STLport 5.0.1 under Win32,
(mingw-special) + STLport 5.1.0 under Win32,</li>
<li>GCC 4.0.1 (Apple build 5250) under Mac OS,</li>
<li>GCC 4.0.3 under Linux and Tru64 (see <a href="#gcc_tru64">below</a>),</li>
<li>GCC 4.1.0 under Linux and Linux x86-64,</li>
<li>GCC 4.1.1 (OpenPKG-2-STABLE) under Solaris.</li>
<li>GCC 3.4.2 under HP-UX IA64,</li>
<li>GCC 3.4.3 under Linux x86-64,</li>
<li>GCC 3.4.4 under Linux, (cygming special) under Cygwin 1.5.22,</li>
<li>GCC 3.4.5 (mingw special) under Win32,</li>
<li>GCC 3.4.6 under Linux x86-64,</li>
<li>GCC 4.0.1 under Linux x86-64, (Apple builds 5363 and 5367) under Mac OS,</li>
<li>GCC 4.1.1 under Linux x86-64,</li>
<li>GCC 4.1.2 (OpenPKG-CURRENT) under Solaris,</li>
<li>GCC 4.2.1 under HP-UX IA64 and Linux x86-64, (mingw32-2) under Win32,</li>
<li>GCC 4.2.2 under Linux.</li>
</ul>
Boost.MultiIndex does not work with versions 3.1 and prior of GCC.
</p>
@ -172,18 +175,17 @@ release of GNU GCC 4.0.0, so the invariant-checking mode is available from this
upgrade.
</p>
<h2><a name="acc_612">HP aC++ A.06.12 for HP-UX</a></h2>
<h2><a name="acc_612">HP aC++ A.06.12 for HP-UX and later</a></h2>
<p>
No problems have been detected with this compiler.
Last tested for version A.06.14.
</p>
<h2><a name="va_60">IBM VisualAge C++ V6.0 for AIX</a></h2>
<p>
<b>Note:</b> This information was last checked for Boost 1.33.1. There is a
possibility that changes in Boost since that release have
caused problems with this platform.
<b>Note:</b> Last tested in Boost 1.33.1. The information might be no longer accurate.
</p>
<blockquote><hr></blockquote>
@ -214,10 +216,33 @@ Serialization capabilities are not available as Boost.Serialization is not
supported on this platform.
</p>
<h2><a name="intel_90_lin">Intel C++ Compiler for Linux 9.0 and later</a></h2>
<h2><a name="va_90">IBM VisualAge C++ V9.0 for AIX</a></h2>
<p>
No problems have been detected with this compilers from version 9.0.
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
refer to the section on
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
<code>member_offset</code> causes the compiler to emit warnings about the
use of <code>offsetof</code> with non-POD types: these warnings can be suppressed
by setting the compiler option <code>-qsuppress=1540-1281</code>, or, alternatively,
by inserting the following preprocessor directive:
</p>
<blockquote><pre>
<span class=preprocessor>#pragma</span> <span class=identifier>info</span><span class=special>(</span><span class=identifier>nolan</span><span class=special>)</span>
</pre></blockquote>
<p>
This latter pragma, however, may also eliminate other warnings not related
to the use of <code>offsetof</code>.
Other than this, Boost.MultiIndex works without problems.
</p>
<h2><a name="intel_81_lin">Intel C++ Compiler for Linux 8.1 and later</a></h2>
<p>
No problems have been detected with this compiler.
Tested from version 8.1 to 9.1.
</p>
<h2><a name="intel_7x_win">Intel C++ Compiler for Windows 32-bit 7.0/7.1</a></h2>
@ -246,11 +271,11 @@ disabled by default. This will cause problems with many Boost libraries,
and in particular with the serialization part of Boost.MultiIndex.
Argument dependent lookup is enabled by adding
<code>/Qoption,c,--arg_dep_lookup</code> to the project options.
Other than this, Boost.MultiIndex works without problems. Compiler versions
from 8.0 to 9.1 have been tested.
Other than this, Boost.MultiIndex works without problems.
Last tested for compiler version 10.0.
</p>
<h2><a name="intel_em64t_91_win">Intel C++ Compiler Extended Memory 64 Technology 9.1 for Windows</a></h2>
<h2><a name="intel_100_win64">Intel C++ Compiler for Windows 64-bit 10.0</a></h2>
<p>
No problems have been detected with this compiler.
@ -276,12 +301,16 @@ objects of derived types. For instance:
</pre></blockquote>
<p>
Other than this, Boost.MultiIndex works without problems under the
two operating systems tested: Mac OS and Windows.
Other than this, Boost.MultiIndex works without problems under Mac OS and Windows (last
tested under Windows only).
</p>
<h2><a name="cw_9x">Metrowerks CodeWarrior 9 and later</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.34.1. The information might be no longer accurate.
</p>
<p>
Boost.MultiIndex works correctly with versions of this compiler from 9.0 to
9.5, under the two operating systems tested: Mac OS and Windows.
@ -642,13 +671,26 @@ No problems have been detected with this configuration.
No problems have been detected with this compiler.
</p>
<h2><a name="sun_11">Sun Studio 11 for Solaris</a></h2>
<h2><a name="msvc_90">Microsoft Visual C++ 9.0</a></h2>
<p>
No problems have been detected with this platform. The exact compiler version
tested was Sun C++ 5.8 Patch 121017-03 2006/07/19. The option
<code>-library=stlport4</code> was used to replace the default standard
library with STLport.
No problems have been detected with this compiler.
The Beta 2 version of this product was used for the testing.
</p>
<h2><a name="sun_10">Sun Studio 10 for Solaris and later</a></h2>
<p>
No problems have been detected with this platform. The exact compiler versions
tested were:
<ul>
<li>Sun C++ 5.7 Patch 117830-07 2006/03/15 (Sun Studio 10),</li>
<li>Sun C++ 5.8 Patch 121017-09 2007/01/17 (Sun Studio 11),</li>
<li>Sun C++ 5.9 (Sun Studio 12).</li>
</ul>
The option <code>-library=stlport4</code> was used to replace the default
standard library with STLport.
</p>
<h2><a name="portability">Portability techniques</a></h2>
@ -666,7 +708,7 @@ to work correctly with <code>member</code>:
<ul>
<li>MSVC++ 6.0/7.0,</li>
<li>Intel C++ 7.0/7.1 for Windows,</li>
<li>VisualAge 6.0 for AIX.</li>
<li>VisualAge 6.0/9.0 for AIX.</li>
</ul>
This program can help determine if your compiler
properly supports pointers to members as non-type template parameters:
@ -1071,9 +1113,9 @@ Performance
<br>
<p>Revised October 16th 2006</p>
<p>Revised November 6th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -31,7 +31,7 @@ Tests
<ul>
<li><a href="#example1">Example 1: basic usage</a></li>
<li><a href="#example2">Example 2: using member functions as keys</a></li>
<li><a href="#example2">Example 2: using functions as keys</a></li>
<li><a href="#example3">Example 3: constructing <code>multi_index_container</code>s
with <code>ctor_args_list</code></a></li>
<li><a href="#example4">Example 4: bidirectional map</a></li>
@ -42,6 +42,7 @@ Tests
<li><a href="#example9">Example 9: serialization and MRU lists</a></li>
<li><a href="#example10">Example 10: random access indices</a></li>
<li><a href="#example11">Example 11: index rearrangement</a></li>
<li><a href="#example12">Example 12: using Boost.Interprocess allocators</a></li>
</ul>
<h2><a name="example1">Example 1: basic usage</a></h2>
@ -55,23 +56,23 @@ Basic program showing the multi-indexing capabilities of Boost.MultiIndex
with an admittedly boring set of <code>employee</code> records.
</p>
<h2><a name="example2">Example 2: using member functions as keys</a></h2>
<h2><a name="example2">Example 2: using functions as keys</a></h2>
<p>
See <a href="../example/memfun_key.cpp">source code</a>.
See <a href="../example/fun_key.cpp">source code</a>.
</p>
<p>
Usually keys assigned to an index are based on a member variable of the
element, but key extractors can be defined which take their value from
a member function. This has some similarity with the concept of
a member function or a global function. This has some similarity with the concept of
<i>calculated keys</i> supported by some relational database engines.
The example shows how to use the predefined <code>const_mem_fun</code>
key extractor to deal with this situation.
and <code>global_fun</code> key extractors to deal with this situation.
</p>
<p>
Keys based on member functions usually will not be actual references,
Keys based on functions usually will not be actual references,
but rather the temporary values resulting from the invocation of the
member function used. This implies that <code>modify_key</code> cannot be
applied to this type of extractors, which is a perfectly logical
@ -111,6 +112,12 @@ for both keys. The program features a tiny Spanish-English
dictionary with online query of words in both languages.
</p>
<p>
This bidirectional map can be considered as a primitive precursor
to the full-fledged container provided by
<a href="../../bimap/index.html">Boost.Bimap</a>.
</p>
<h2><a name="example5">Example 5: sequenced indices</a></h2>
<p>
@ -412,6 +419,23 @@ is used to apply to the deck a shuffle performed externally on an
auxiliary data structure.
</p>
<h2><a name="example12">Example 12: using Boost.Interprocess allocators</a></h2>
<p>
See <a href="../example/ip_allocator.cpp">source code</a>.
</p>
<p>
Boost.MultiIndex supports special allocators such as those provided by
<a href="../../interprocess/index.html">Boost.Interprocess</a>,
which allows for <code>multi_index_container</code>s to be placed in shared
memory. The example features a front-end to a small book database
implemented by means of a <code>multi_index_container</code> stored
in a Boost.Interprocess memory mapped file. The reader can verify that several
instances of the program correctly work simultaneously and immediately see
the changes to the database performed by any other instance.
</p>
<hr>
<div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br>
@ -426,9 +450,9 @@ Tests
<br>
<p>Revised March 3rd 2006</p>
<p>Revised July 16th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -41,7 +41,6 @@ principle driving the current internal design of <code>multi_index_container</co
<li><a href="#notifying">Notifying indices</a></li>
<li><a href="#constraints">Constraints</a></li>
<li><a href="#user_defined_indices">User-defined indices</a></li>
<li><a href="#bimap">Bidirectional map</a></li>
<li><a href="#indexed_maps">Indexed maps</a></li>
<li><a href="#move_semantics">Move semantics</a></li>
</ul>
@ -150,19 +149,6 @@ simple enough to make them worth documenting so that the (bold)
user can write implementations for her own indices.
</p>
<h2><a name="bimap">Bidirectional map</a></h2>
<p>
<a href="examples.html#example4">Example 4</a> in the examples section
features a <i>bidirectional map</i>, implemented as a
<code>multi_index_container</code> with two unique ordered indices. This particular
structure is deemed important enough as to provide it as a separate
class template, relying internally in <code>multi_index_container</code>. As
feedback is collected from the users of Boost.MultiIndex, other singular
instantiations of <code>multi_index_container</code> might be encapsulated
to form a component library of ready to use containers.
</p>
<h2><a name="indexed_maps">Indexed maps</a></h2>
<p>
@ -240,9 +226,9 @@ Release notes
<br>
<p>Revised February 6th 2006</p>
<p>Revised July 5th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -44,9 +44,11 @@ Sequenced indices
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#types">Nested types</a></li>
<li><a href="#constructors">Constructors, copy and assignment</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#observers">Observers</a></li>
<li><a href="#lookup">Lookup</a></li>
<li><a href="#bucket_interface">Bucket interface</a></li>
<li><a href="#hash_policy">Hash policy</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
@ -248,7 +250,12 @@ do not exactly conform to the requirements for unordered associative containers.
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>end</span><span class=special>();</span>
<span class=identifier>const_iterator</span> <span class=identifier>end</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// modifiers:</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>
@ -262,7 +269,11 @@ do not exactly conform to the requirements for unordered associative containers.
<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>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
@ -313,6 +324,11 @@ do not exactly conform to the requirements for unordered associative containers.
<span class=identifier>const_local_iterator</span> <span class=identifier>begin</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>local_iterator</span> <span class=identifier>end</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>);</span>
<span class=identifier>const_local_iterator</span> <span class=identifier>end</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_local_iterator</span> <span class=identifier>cbegin</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_local_iterator</span> <span class=identifier>cend</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>local_iterator</span> <span class=identifier>local_iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_local_iterator</span> <span class=identifier>local_iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// hash policy:</span>
@ -434,6 +450,18 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);</br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.</br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code>
@ -589,6 +617,41 @@ user-provided operation (except possibly <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, restores all keys of the element
to their original state.</br>
<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
all the indices of the <code>multi_index_container</code>. Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
throws inside the handling code executing after some other user-provided
operation has thrown, it is the exception generated by <code>back</code> that
is rethrown.
</blockquote>
<a name="modify_key">
<code>template&lt;typename Modifier> bool modify_key(iterator position,Modifier mod);</code></a>
@ -600,26 +663,31 @@ from <code>value_type</code>. <code>Modifier</code> is a model of
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
<b>Effects:</b> Calls <code>mod(k)</code> where <code>k</code> is the key
obtained by the internal <code>KeyFromValue</code> object of the index from
the element pointed to by <code>position</code>, and rearranges
<code>*position</code> into all the indices of the <code>multi_index_container</code>.
Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, the element is erased.<br>
<b>Postconditions:</b>Validity of <code>position</code> is preserved if
the operation succeeds.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Basic. If an exception is thrown by some
user-provided operation (except possibly <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
<b>Effects:</b> Equivalent to <code>modify(position,mod')</code>,
with <code>mod'</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code>, where
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> and <code>Rollback</code>
are models of <a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The sequence of operations <code>mod(k)</code>,
<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>
<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
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
<code>back'(x)</code> is the same as <code>back(key(x))</code>, where
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<h4><a name="observers">Observers</a></h4>
@ -768,7 +836,8 @@ std::pair&lt;iterator,iterator> equal_range(const CompatibleKey&amp; x)const;
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
(<code>hasher</code>, <code>key_equal</code>).</br>
<b>Effects:</b> Returns a range containing all elements with keys equivalent
to <code>x</code> (and only those).<br>
to <code>x</code> (and only those), or (<code>end()</code>,<code>end()</code>)
if no such elements exist.<br>
<b>Complexity:</b> Average case <code>O(count(x))</code>, worst case
<code>O(n)</code>.<br>
</blockquote>
@ -786,11 +855,24 @@ std::pair&lt;iterator,iterator> equal_range(</br>
<code>CompatiblePred</code>) is a compatible extension of
(<code>hasher</code>, <code>key_equal</code>).</br>
<b>Effects:</b> Returns a range containing all elements with keys equivalent
to <code>x</code> (and only those).<br>
to <code>x</code> (and only those), or (<code>end()</code>,<code>end()</code>)
if no such elements exist.<br>
<b>Complexity:</b> Average case <code>O(count(x,hash,eq))</code>, worst case
<code>O(n)</code>.<br>
</blockquote>
<h4><a name="bucket_interface">Bucket interface</a></h4>
<code>local_iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_iterator_to(const value_type&amp; x);</br>
const_local_iterator local_iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.</br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="hash_policy">Hash policy</a></h4>
@ -895,9 +977,9 @@ Sequenced indices
<br>
<p>Revised July 13th 2006</p>
<p>Revised July 2nd 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -88,7 +88,9 @@ The following dependencies among headers of Boost.MultiIndex hold:
<li><a href="key_extraction.html#member_synopsis">
<code>"boost/multi_index/member.hpp"</code></a>,</li>
<li><a href="key_extraction.html#mem_fun_synopsis">
<code>"boost/multi_index/mem_fun.hpp"</code></a> and</li>
<code>"boost/multi_index/mem_fun.hpp"</code></a>,</li>
<li><a href="key_extraction.html#global_fun_synopsis">
<code>"boost/multi_index/global_fun.hpp"</code></a> and</li>
<li><a href="key_extraction.html#composite_key_synopsis">
<code>"boost/multi_index/composite_key.hpp"</code></a>.</li>
</ul>
@ -125,9 +127,9 @@ Index
<br>
<p>Revised February 6th 2005</p>
<p>Revised June 19th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -63,6 +63,12 @@ Compiler specifics
<li><a href="#boost_multi_index_mem_fun">Macro <code>BOOST_MULTI_INDEX_MEM_FUN</code></a></li>
</ul>
</li>
<li><a href="#global_fun_synopsis">Header
<code>"boost/multi_index/global_fun.hpp"</code> synopsis</a>
<ul>
<li><a href="#global_fun">Class template <code>global_fun</code></a></li>
</ul>
</li>
<li><a href="#composite_key_synopsis">Header
<code>"boost/multi_index/composite_key.hpp"</code> synopsis</a>
<ul>
@ -131,12 +137,13 @@ for every <code>k1</code> of type <code>const KeyFromValue</code> and
</p>
<p>
Boost.MultiIndex provides five general-purpose key extractors:
Boost.MultiIndex provides six general-purpose key extractors:
<ul>
<li><a href="#identity"><code>identity</code></a>,</li>
<li><a href="#member"><code>member</code></a>,</li>
<li><a href="#const_mem_fun"><code>const_mem_fun</code></a>,</li>
<li><a href="#mem_fun"><code>mem_fun</code></a> and</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="#composite_key"><code>composite_key</code></a>,</li>
</ul>
plus replacements for some of them:
@ -178,6 +185,7 @@ ultimately dereferencing to values of <code>Type&amp;</code> or
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>member</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>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>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>global_fun</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>composite_key</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
</pre></blockquote>
@ -769,6 +777,147 @@ but it resolves to
for MSVC++ 6.0 or lower.
</p>
<h2>
<a name="global_fun_synopsis">Header
<a href="../../../../boost/multi_index/global_fun.hpp">
<code>"boost/multi_index/global_fun.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>Type</span> <span class=special>(*</span><span class=identifier>PtrToFunction</span><span class=special>)(</span><span class=identifier>Value</span><span class=special>)&gt;</span>
<span class=keyword>struct</span> <span class=identifier>global_fun</span><span class=special>;</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
<span class=special>}</span> <span class=comment>// namespace boost</span>
</pre></blockquote>
<h3><a name="global_fun">Class template <code>global_fun</code></a></h3>
<p>
<code>global_fun</code> is a <a href="#key_extractors"><code>Key Extractor</code></a>
based on a given global or static member function accepting the base type as argument
and returning the associated key.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>Type</span> <span class=special>(*</span><span class=identifier>PtrToFunction</span><span class=special>)(</span><span class=identifier>Value</span><span class=special>)&gt;</span>
<span class=keyword>struct</span> <span class=identifier>global_fun</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 under the following circumstances:
// - If Value is a reference to a constant type, only provided
// when const ChainedPtr&amp; is not convertible to Value;
// - if Value is a reference to a non-const type, only provided
// when ChainedPtr&amp; is not convertible to Value;
// - else, only provided when const ChainedPtr&amp; is not
// convertible to const Value&amp;.</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=comment>// only provided if Value is a reference type</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Value</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 Value is not a reference type</span>
<span class=identifier>Type</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=special>;</span>
<span class=comment>// only provided if Value is not a reference type</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>Value</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=comment>// only provided if Value is a reference type</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>remove_reference</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>&gt;::</span><span class=identifier>type</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=comment>// only provided if Value is not a reference type or is
// a reference to a constant type</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>typename</span> <span class=identifier>remove_const</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&gt;::</span><span class=identifier>type</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>PtrToFunction</code> specifies the particular function used to extract
the key of type <code>Type</code> from some <code>BaseType</code>.
<code>global_fun</code> supports the following function signatures:
<ul>
<li><code>Type f(BaseType)</code> (<code>Value</code> is <code>BaseType</code>),</li>
<li><code>Type f(const BaseType&amp;)</code> (<code>Value</code> is <code>const BaseType&amp;</code>),</li>
<li><code>Type f(BaseType&amp;)</code> (<code>Value</code> is <code>BaseType&amp;</code>).</li>
</ul>
<code>global_fun&lt;Type,Value,PtrToFunction&gt;</code> is a model of:
<ul>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from <code>reference_wrapper&lt;BaseType></code>,</li>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from any <a href="#chained_pointers">chained pointer</a>
to <code>BaseType</code>.</li>
</ul>
When <code>Value</code> is <code>BaseType</code> or
<code>const BaseType&amp;</code>,
<code>global_fun&lt;Type,Value,PtrToFunction&gt;</code> is also a model of:
<ul>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from <code>BaseType</code>,</li>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from <code>reference_wrapper&lt;const BaseType></code>,</li>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from any <a href="#chained_pointers">chained pointer</a>
to <code>const BaseType</code>.</li>
</ul>
</p>
<h4><code>global_fun</code> members</h4>
<code>template&lt;typename ChainedPtr> Type operator()(const ChainedPtr&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>ChainedPtr</code> is a <a href="#chained_pointers">chained pointer</a>
type to <code>Value</code>.<br>
<b>Returns:</b> <code>PtrToFunction)(y)</code>, where <code>y</code> is the
object chained-pointed to by <code>x</code>.
</blockquote>
<code>Type operator()(Value x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x)</code>.
</blockquote>
<code>Type operator()(const Value&amp; x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x)</code>.
</blockquote>
<code>Type operator()(const reference_wrapper&lt;const Value&gt;&amp; x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x.get())</code>.
</blockquote>
<code>
Type operator()(<br>
&nbsp;&nbsp;const reference_wrapper&lt;remove_reference&lt;Value&gt;::type&gt;&amp; x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x.get())</code>.
</blockquote>
<code>Type operator()(<br>
&nbsp;&nbsp;const reference_wrapper&lt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;typename remove_const&lt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename remove_reference&lt;Value&gt;::type&gt;::type&gt;&amp; x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x.get())</code>.
</blockquote>
<h2>
<a name="composite_key_synopsis">Header
<a href="../../../../boost/multi_index/composite_key.hpp">
@ -787,7 +936,7 @@ for MSVC++ 6.0 or lower.
<span class=comment>// comparison operators for composite_key_result:</span>
<span class=comment>// <b>OP</b> is any of =,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=comment>// <b>OP</b> is any of ==,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=keyword>template</span><span class=special>&lt;</span><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> <b><i>OP</i></b><span class=special>(</span>
@ -1005,7 +1154,7 @@ instantiations as their extracted key.
<span class=comment>// comparison:</span>
<span class=comment>// <b>OP</b> is any of =,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=comment>// <b>OP</b> is any of ==,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=keyword>template</span><span class=special>&lt;</span><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> <b><i>OP</i></b><span class=special>(</span>
@ -2072,9 +2221,22 @@ is lexicographical. Also, the following types are
<code>composite_key_result&lt;composite_key&lt;K0,...,Kk> ></code>, with
<code>Ki::result_type = Qi</code> for all <code>i = 0,...,k</code>.
</blockquote>
provided that each <code>Qi</code> is either <code>Ti</code> or a
<a href="ord_indices.html#set_operations"><code>Compatible Key</code></a>
of <code>Comparei</code>. In this case, the comparison is done
provided that
<ul>
<li>for <code>i = 0,...,min(j,k)-1</code>, <code>Qi</code> is either <code>Ti</code>
or <i>not coarser</i> than <code>Ti</code> (<code>Qi</code> is a
<a href="ord_indices.html#set_operations"><code>Compatible Key</code></a>
of <code>Comparei</code> and there are no two distinct elements of
<code>Ti</code> equivalent to one single element of <code>Qi</code>);
</li>
<li>
<code>Qm</code> (with <code>m = min(j,k)</code>) is either <code>Tm</code> or a
<a href="ord_indices.html#set_operations"><code>Compatible Key</code></a>
of <code>Comparem</code>.
</li>
</ul>
In this case, the comparison is done
lexicographically only on the first <code>1+min(j,k)</code> elements.
</p>
@ -2101,9 +2263,9 @@ Compiler specifics
<br>
<p>Revised July 13th 2006</p>
<p>Revised August 2nd 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -493,7 +493,8 @@ scheme outlined in the
<ol>
<li><code>Value</code> is the
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>
type of the elements contained.</li>
type of the elements contained.
</li>
<li><code>IndexSpecifierList</code> specifies the indices that the
<code>multi_index_container</code> is composed of. It must be a non-empty
<a href="../../../../libs/mpl/doc/refmanual/forward-sequence.html">
@ -503,8 +504,27 @@ scheme outlined in the
syntactic convenience, the
<a href="indices.html#indexed_by"><code>indexed_by</code></a>
MPL sequence can be used.
<li><code>Allocator</code> must comply with the C++ requirements for
allocators <b>[lib.allocator.requirements]</b>.
</li>
<li><code>Allocator</code> must be an allocator of <code>Value</code> objects
satisfying the associated C++ requirements at <b>[lib.allocator.requirements]</b>.
The following relaxations to the standard requirements are allowed:
<ul>
<li>Non-equal allocator instances are supported: swapping two non-equal
instances must not throw any exception.
</li>
<li>For every type <code>T</code>,
the type <code>Allocator::rebind&lt;T&gt;::other::pointer</code> can be any
kind of
<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
<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
from <code>Allocator</code>. A <code>pointer</code> constructed from
<code>p</code> shall dereference to <code>*p</code>.
</li>
</ul>
</li>
</ol>
Indices of a given <code>multi_index_container</code> instantiation cannot have
duplicate <a href="indices.html#tags">tags</a>, either within a single
@ -882,9 +902,9 @@ Index reference
<br>
<p>Revised February 6th 2006</p>
<p>Revised July 17th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -43,6 +43,7 @@ Hashed indices
<li><a href="#complexity_signature">Complexity signature</a></li>
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#constructors">Constructors, copy and assignment</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#observers">Observers</a></li>
<li><a href="#set_operations">Set operations</a></li>
@ -205,7 +206,7 @@ requirements for these types of containers.
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=keyword>namespace</span><span class=special>{</span> <b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=special>}</span> <span class=comment>// see range()</span>
<b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=comment>// see range()</span>
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
@ -252,7 +253,14 @@ requirements for these types of containers.
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>();</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
@ -272,7 +280,11 @@ requirements for these types of containers.
<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>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
@ -395,7 +407,7 @@ section</a>. The complexity signature of ordered indices is:
<li>copying: <code>c(n)=n*log(n)</code>,</li>
<li>insertion: <code>i(n)=log(n)</code>,</li>
<li>hinted insertion: <code>h(n)=1</code> (constant) if the hint element
precedes the point of insertion, <code>h(n)=log(n)</code> otherwise,</li>
is immediately after the point of insertion, <code>h(n)=log(n)</code> otherwise,</li>
<li>deletion: <code>d(n)=1</code> (amortized constant),</li>
<li>replacement: <code>r(n)=1</code> (constant) if the element position does not
change, <code>r(n)=log(n)</code> otherwise,</li>
@ -448,6 +460,18 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);</br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.</br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code>
@ -602,6 +626,41 @@ user-provided operation (except possibly <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, restores all keys of the element
to their original state.</br>
<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
all the indices of the <code>multi_index_container</code>. Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
throws inside the handling code executing after some other user-provided
operation has thrown, it is the exception generated by <code>back</code> that
is rethrown.
</blockquote>
<a name="modify_key">
<code>template&lt;typename Modifier> bool modify_key(iterator position,Modifier mod);</code></a>
@ -613,26 +672,31 @@ from <code>value_type</code>. <code>Modifier</code> is a model of
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
<b>Effects:</b> Calls <code>mod(k)</code> where <code>k</code> is the key
obtained by the internal <code>KeyFromValue</code> object of the index from
the element pointed to by <code>position</code>, and rearranges
<code>*position</code> into all the indices of the <code>multi_index_container</code>.
Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, the element is erased.<br>
<b>Postconditions:</b>Validity of <code>position</code> is preserved if
the operation succeeds.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Basic. If an exception is thrown by some
user-provided operation (except possibly <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
<b>Effects:</b> Equivalent to <code>modify(position,mod')</code>,
with <code>mod'</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code>, where
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> and <code>Rollback</code>
are models of <a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The sequence of operations <code>mod(k)</code>,
<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>
<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
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
<code>back'(x)</code> is the same as <code>back(key(x))</code>, where
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<h4><a name="observers">Observers</a></h4>
@ -954,9 +1018,9 @@ Hashed indices
<br>
<p>Revised March 31st 2006</p>
<p>Revised July 2nd 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -41,6 +41,7 @@ Key extraction
<li><a href="#complexity_signature">Complexity signature</a></li>
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#constructors">Constructors, copy and assignment</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#capacity">Capacity operations</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#list_operations">List operations</a></li>
@ -238,6 +239,13 @@ to the requirements for these types of containers.
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>();</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
@ -273,6 +281,8 @@ to the requirements for these types of containers.
<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>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
@ -396,7 +406,7 @@ of the complexity formulas:
<p>
(<code>shl</code> and <code>rel</code> stand for <i>shift left</i> and
<i>relocate</i>, respetively.)
<i>relocate</i>, respectively.)
</p>
<h4><a name="instantiation_types">Instantiation types</a></h4>
@ -462,6 +472,18 @@ index of the <code>multi_index_container</code> to which this index belongs.
</pre></blockquote>
</blockquote>
<h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);</br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.</br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="capacity">Capacity operations</a></h4>
<a name="capacity_memfun"><code>size_type capacity()const;</code></a>
@ -634,8 +656,8 @@ iterator of the index.</br>
<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
all the indices of the <code>multi_index_container</code>. Rearrangement on
rancom access indices does not change the position of the element with respect
to the index; rearrangement on other indices may or might not suceed. If the
random access indices does not change the position of the element with respect
to the index; rearrangement on other indices may or might not succeed. If the
rearrangement fails, the element is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the
operation succeeds.<br>
@ -647,6 +669,37 @@ user-provided operation (except possibly <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, restores all keys of the element
to their original state.</br>
<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
all the indices of the <code>multi_index_container</code>. Rearrangement on
random access indices does not change the position of the element with respect
to the index; rearrangement on other indices may or might not succeed. If the
rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
throws inside the handling code executing after some other user-provided
operation has thrown, it is the exception generated by <code>back</code> that
is rethrown.
</blockquote>
<h4><a name="list_operations">List operations</a></h4>
<p>
@ -946,9 +999,9 @@ Key extraction
<br>
<p>Revised February 6th 2006</p>
<p>Revised July 2nd 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -41,6 +41,7 @@ Random access indices
<li><a href="#complexity_signature">Complexity signature</a></li>
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#constructors">Constructors, copy and assignment</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#capacity">Capacity operations</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#list_operations">List operations</a></li>
@ -229,6 +230,13 @@ types of containers.
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>reverse_iterator</span> <span class=identifier>rend</span><span class=special>();</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_iterator</span> <span class=identifier>cend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crbegin</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>const_reverse_iterator</span> <span class=identifier>crend</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
@ -260,6 +268,8 @@ types of containers.
<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>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
@ -436,6 +446,18 @@ index of the <code>multi_index_container</code> to which this index belongs.
</pre></blockquote>
</blockquote>
<h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);</br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.</br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="capacity">Capacity operations</a></h4>
<code>void resize(size_type n,const value_type&amp; x=value_type());</code>
@ -587,7 +609,7 @@ iterator of the index.</br>
pointed to by <code>position</code> and rearranges <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
indices does not change the position of the element with respect to the index;
rearrangement on other indices may or might not suceed. If the rearrangement
rearrangement on other indices may or might not succeed. If the rearrangement
fails, the element is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the
operation succeeds.<br>
@ -599,6 +621,37 @@ user-provided operation (except possibly <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
</blockquote>
<code>template&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, restores all keys of the element
to their original state.</br>
<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
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
indices does not change the position of the element with respect to the index;
rearrangement on other indices may or might not succeed. If the rearrangement
fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
throws inside the handling code executing after some other user-provided
operation has thrown, it is the exception generated by <code>back</code> that
is rethrown.
</blockquote>
<h4><a name="list_operations">List operations</a></h4>
<p>
@ -901,9 +954,9 @@ Random access indices
<br>
<p>Revised February 6th 2006</p>
<p>Revised July 2nd 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -31,11 +31,76 @@ Acknowledgements
<h2>Contents</h2>
<ul>
<li><a href="#boost_1_35">Boost 1.35 release</a></li>
<li><a href="#boost_1_34">Boost 1.34 release</a></li>
<li><a href="#boost_1_33_1">Boost 1.33.1 release</a></li>
<li><a href="#boost_1_33">Boost 1.33 release</a></li>
</ul>
<h2><a name="boost_1_35">Boost 1.35 release</a></h2>
<p>
<ul>
<li>New <a href="tutorial/key_extraction.html#global_fun"><code>global_fun</code></a>
predefined key extractor.
</li>
<li>Added <a href="tutorial/indices.html#iterator_to"><code>iterator_to</code></a>
facility.
</li>
<li>Included <a href="tutorial/creation.html#special_allocator">support for
non-standard allocators</a> such as those of
<a href="../../interprocess/index.html">Boost.Interprocess</a>, which makes
<code>multi_index_container</code>s placeable in shared memory.
</li>
<li>New versions of <code>modify</code> and <code>modify_key</code> with
rollback, as described in the
<a href="tutorial/basics.html#ord_updating">tutorial</a>.
</li>
<li>Indices provide the new <code>cbegin</code>, <code>cend</code> and,
when applicable, <code>crbegin</code> and <code>crend</code>
member functions, in accordance with the latest drafts of the next
revision of the C++ standard.
</li>
<li>Hinted insertion in ordered indices fully conforms to the resolutions of
C++ Standard Library
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233">Defect
Report 233</a>. The new requirement that the point of insertion
be always as close as possible to the hint induces a different behavior than
exhibited in former releases of Boost.MultiIndex, which can potentially cause
backwards compatibility problems; in any case, the likelihood of these
compatibility issues arising in a real scenario is very low.
</li>
<li>Sequenced and random access indices now follow the requirements of the
C++ standard for sequence containers with respect to the operations
<code>assign(f,l)</code> and <code>insert(p,f,l)</code> (23.1.1/9): if
<code>f</code> and <code>l</code> are of the same integral type, the
iterator-based overloads of these member functions are avoided:
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span><span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>sequenced_container</span><span class=special>;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=identifier>l</span><span class=special>(...);</span>
<span class=identifier>sequenced_container</span> <span class=identifier>c</span><span class=special>;</span>
<span class=comment>// iterator-based overload of assign</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=identifier>l</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>l</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
<span class=comment>// The following is equivalent to
// c.assign(
// static_cast&lt;sequenced_container::size_type&gt;(10),100);
// that is, &quot;10&quot; and &quot;100&quot; are not taken to be iterators as
// in the previous expression.</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=number>10</span><span class=special>,</span><span class=number>100</span><span class=special>);</span>
</pre></blockquote>
</li>
<li>The performance of ordered indices <code>range</code> and
<code>equal_range</code> has been improved.
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_34">Boost 1.34 release</a></h2>
<p>
@ -140,9 +205,9 @@ Acknowledgements
<br>
<p>Revised February 6th 2006</p>
<p>Revised October 11th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -116,7 +116,8 @@ with some of the least common features offered by Boost.MultiIndex.
</tr>
<tr class="odd_tr">
<td><a href="../test/test_serialization1.cpp"><code>test_serialization1.cpp</code></a><br>
<a href="../test/test_serialization2.cpp"><code>test_serialization2.cpp</code></a></td>
<a href="../test/test_serialization2.cpp"><code>test_serialization2.cpp</code></a><br>
<a href="../test/test_serialization3.cpp"><code>test_serialization3.cpp</code></a></td>
<td>Serialization support.</td>
</tr>
<tr>
@ -149,9 +150,9 @@ Future work
<br>
<p>Revised March 2nd 2006</p>
<p>Revised July 11th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -956,15 +956,69 @@ original value is kept and the method returns without altering the container, bu
leaves no trace of the previous value of the element. Integrity constraints
thus lead to the following policy: when a collision happens in the
process of calling <code>modify</code>, the element is erased and the method returns
<code>false</code>. This difference in behavior between <code>replace</code> and
<code>modify</code> has to be considered by the programmer on a case-by-case basis.
<code>false</code>. There is a further version of <code>modify</code> which
accepts a <i>rollback</i> functor to undo the changes in case of collision:
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>change_id</span>
<span class=special>{</span>
<span class=identifier>change_id</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>new_id</span><span class=special>):</span><span class=identifier>new_id</span><span class=special>(</span><span class=identifier>new_id</span><span class=special>){}</span>
<span class=keyword>void</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>employee</span><span class=special>&amp;</span> <span class=identifier>e</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>e</span><span class=special>.</span><span class=identifier>id</span><span class=special>=</span><span class=identifier>new_id</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>private</span><span class=special>:</span>
<span class=keyword>int</span> <span class=identifier>new_id</span><span class=special>;</span>
<span class=special>};</span>
<span class=special>...</span>
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=...</span>
<span class=keyword>int</span> <span class=identifier>old_id</span><span class=special>=</span><span class=identifier>it</span><span class=special>-&gt;</span><span class=identifier>id</span><span class=special>;</span> <span class=comment>// keep the original id
// try to modify the id, restore it in case of collisions</span>
<span class=identifier>es</span><span class=special>.</span><span class=identifier>modify</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>change_id</span><span class=special>(</span><span class=number>321</span><span class=special>),</span><span class=identifier>change_id</span><span class=special>(</span><span class=identifier>old_id</span><span class=special>));</span>
</pre></blockquote>
<p>In the example, <code>change_id(old_id)</code> is invoked to restore the original
conditions when the modification results in collisions with some other element.
The differences in behavior between <code>replace</code>, <code>modify</code> and
<code>modify</code> with rollback have to be considered by the programmer on a
case-by-case basis to determine the best updating mechanism.
</p>
<p align="center">
<table cellspacing="0">
<caption><b>Behavior of the different updating mechanisms.</b></caption>
<tr>
<th align="center">updating function</th>
<th>If there is a collision...</th>
</tr>
<tr>
<td align="center"><code>replace(it,x)</code></td>
<td>replacement does not take place.</td>
</tr>
<tr class="odd_tr">
<td align="center"><code>modify(it,mod)</code></td>
<td>the element is erased.</td>
</tr>
<tr>
<td align="center"><code>modify(it,mod,back)</code></td>
<td><code>back</code> is used to restore the original conditions.
(If <code>back</code> throws, the element is erased.)
</td>
</tr>
</table>
</p>
<p>
A key-based version of <code>modify</code>, named
<a href="../reference/ord_indices.html#modify_key"><code>modify_key</code></a>, is
provided as well. In this case, the modifying functor is passed a reference to
the <code>key_value</code> part of the element instead of the whole object.
Key-based versions of <code>modify</code>, named
<a href="../reference/ord_indices.html#modify_key"><code>modify_key</code></a>, are
provided as well. In this case, the modifying functors are passed a reference to
the <code>key_type</code> part of the element instead of the whole object.
</p>
<blockquote><pre>
@ -990,8 +1044,8 @@ the <code>key_value</code> part of the element instead of the whole object.
</pre></blockquote>
<p>
Just as <code>modify</code> does, <code>modify_key</code> erases the element if
the modification results in collisions in some index. <code>modify</code> and
Like <code>modify</code>, there are versions of <code>modify_key</code> with and
without rollback. <code>modify</code> and
<code>modify_key</code> are particularly well suited to use in conjunction to
<a href="../../../../libs/lambda/index.html">Boost.Lambda</a>
for defining the modifying functors:
@ -1205,9 +1259,9 @@ Index types
<br>
<p>Revised July 13th 2006</p>
<p>Revised July 17th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -32,6 +32,7 @@ Debugging support
<ul>
<li><a href="#value_semantics">Value semantics</a></li>
<li><a href="#ctor_args_list">Use of <code>ctor_args_list</code></a></li>
<li><a href="#special_allocator">Special allocator support</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
@ -191,6 +192,60 @@ A program is provided in the <a href="../examples.html#example3">examples sectio
puts in practise these concepts.
</p>
<h2><a name="special_allocator">Special allocator support</a></h2>
<p>
Boost.MultiIndex allows for a slightly more general class of allocators
than strictly required by the C++ standard, as explained in detail in the
<a href="../reference/multi_index_container.html#instantiation_types">reference</a>.
An important type of non-standard allocators supported are those provided by the
<a href="../../../interprocess/index.html">Boost Interprocess Library</a>;
this opens up the possibility of placing <code>multi_index_container</code>s
in shared memory.
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>allocators</span><span class=special>/</span><span class=identifier>allocator</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>managed_shared_memory</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>bip</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>interprocess</span><span class=special>;</span>
<span class=comment>// a shared memory compatible allocator of ints</span>
<span class=keyword>typedef</span> <span class=identifier>bip</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span><span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span><span class=special>::</span><span class=identifier>segment_manager</span>
<span class=special>&gt;</span> <span class=identifier>shared_int_allocator</span><span class=special>;</span>
<span class=comment>// define a shared memory compatible multi_index_container
// using shared_int_allocator</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;,</span>
<span class=identifier>shared_int_allocator</span>
<span class=special>&gt;</span> <span class=identifier>unique_int_list</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// create a managed memory segment</span>
<span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span> <span class=identifier>seg</span><span class=special>(</span>
<span class=identifier>bip</span><span class=special>::</span><span class=identifier>create_only</span><span class=special>,</span><span class=string>&quot;SharedMemoryID&quot;</span><span class=special>,</span><span class=number>65536</span><span class=special>);</span>
<span class=comment>// construct a unique_int_list into the segment</span>
<span class=identifier>unique_int_list</span><span class=special>*</span> <span class=identifier>puil</span><span class=special>=</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>construct</span><span class=special>&lt;</span><span class=identifier>unique_int_list</span><span class=special>&gt;</span>
<span class=special>(</span><span class=string>&quot;UniqueIntListID&quot;</span><span class=special>)</span> <span class=comment>// object identifier within the segment
// Construction args: first a ctor arg list, then a
// shared memory allocator obtained from the segment object.</span>
<span class=special>(</span><span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
<span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>allocator_type</span><span class=special>(</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>get_segment_manager</span><span class=special>()));</span>
</pre></blockquote>
<p>
The examples section includes a <a href="../examples.html#example12">program</a>
that further explores this capability.
</p>
<h2><a name="serialization">Serialization</a></h2>
<p>
@ -285,7 +340,7 @@ Debugging support
<br>
<p>Revised February 27th 2007</p>
<p>Revised July 17th 2007</p>
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software

View File

@ -48,6 +48,7 @@ Key extraction
</ul>
</li>
<li><a href="#rearrange">Index rearranging</a></li>
<li><a href="#iterator_to"><code>iterator_to</code></a></li>
<li><a href="#ordered_node_compression">Ordered indices node compression</a></li>
</ul>
@ -90,6 +91,7 @@ some added benefits, functionally or in the area of performance.
</tr>
<tr class="odd_tr">
<td align="center"><code>&nbsp;&nbsp;random_access&nbsp;&nbsp;</code></td>
</tr>
</table>
</p>
@ -608,7 +610,8 @@ thus, <code>rearrange</code> does not accept the following:
<blockquote><pre>
<span class=comment>// undefined behavior: [rbegin(),rend()) is not free with respect
// to the base index</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>rbegin</span><span class=special>());</span></pre></blockquote>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>rbegin</span><span class=special>());</span>
</pre></blockquote>
<p>
The view concept is defined in detail in the
@ -617,6 +620,57 @@ See <a href="../examples.html#example11">example 11</a> in the examples section
for a demonstration of use of <code>rearrange</code>.
</p>
<h2><a name="iterator_to"><code>iterator_to</code></a></h2>
<p>
All indices of Boost.MultiIndex provide a member function called <code>iterator_to</code>
which returns an iterator to a given element of the container:
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>c</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// convoluted way to do c.pop_back()</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>iterator_to</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>back</span><span class=special>()));</span>
<span class=comment>// The following, though similar to the previous code,
// does not work: iterator_to accepts a reference to
// the element in the container, not a copy.</span>
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>back</span><span class=special>();</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>iterator_to</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// run-time failure ensues</span>
</pre></blockquote>
<p>
<code>iterator_to</code> provides a way to retrieve an iterator to an element
from a pointer to the element, thus making iterators and pointers interchangeable
for the purposes of element pointing (not so for traversal) in many situations.
This notwithstanding, it is not the aim of <code>iterator_to</code> to
promote the usage of pointers as substitutes for real iterators: the latter are
specifically designed for handling the elements of a container,
and not only benefit from the iterator orientation of container interfaces,
but are also capable of exposing many more programming bugs than raw pointers, both
at compile and run time. <code>iterator_to</code> is thus meant to be used
in scenarios where access via iterators is not suitable or desireable:
<ul>
<li>Interoperability with preexisting APIs based on pointers or references.</li>
<li>Publication of pointer-based interfaces (for instance, when
designing a C-compatible library).
</li>
<li>The exposure of pointers in place of iterators can act as a <i>type
erasure</i> barrier effectively decoupling the user of the code
from the implementation detail of which particular container is being
used. Similar techniques, like the famous Pimpl idiom, are used
in large projects to reduce dependencies and build times.
</li>
<li>Self-referencing contexts where an element acts upon its owner
container and no iterator to itself is available.
</li>
</ul>
</p>
<h2><a name="ordered_node_compression">Ordered indices node compression</a></h2>
<p>
@ -664,9 +718,9 @@ Key extraction
<br>
<p>Revised February 6th 2006</p>
<p>Revised October 15th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -41,6 +41,7 @@ Container creation
<li><a href="#member"><code>member</code></a></li>
<li><a href="#const_mem_fun"><code>const_mem_fun</code>
and <code>mem_fun</code></a></li>
<li><a href="#global_fun"><code>global_fun</code></a></li>
</ul>
</li>
<li><a href="#user_defined_key_extractors">User-defined key extractors</a></li>
@ -244,6 +245,68 @@ of Boost.MultiIndex key extractors</a>.
provides a complete program showing how to use <code>const_mem_fun</code>.
<p>
<h3><a name="global_fun"><code>global_fun</code></a></h3>
<p>
Whereas <code>const_mem_fun</code> and <code>mem_fun</code> are based on a
given member function of the base type from where the key is extracted,
<a href="../reference/key_extraction.html#global_fun"><code>global_fun</code></a>
takes a global function (or static member function) accepting the base
type as its parameter and returning the key:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>global_fun</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>rectangle</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>x0</span><span class=special>,</span><span class=identifier>y0</span><span class=special>;</span>
<span class=keyword>int</span> <span class=identifier>x1</span><span class=special>,</span><span class=identifier>y1</span><span class=special>;</span>
<span class=special>};</span>
<span class=keyword>unsigned</span> <span class=keyword>long</span> <span class=identifier>area</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>rectangle</span><span class=special>&amp;</span> <span class=identifier>r</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=special>(</span><span class=keyword>unsigned</span> <span class=keyword>long</span><span class=special>)(</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>x1</span><span class=special>-</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>x0</span><span class=special>)*(</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>x1</span><span class=special>-</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>x0</span><span class=special>)+</span>
<span class=special>(</span><span class=keyword>unsigned</span> <span class=keyword>long</span><span class=special>)(</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>y1</span><span class=special>-</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>y0</span><span class=special>)*(</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>y1</span><span class=special>-</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>y0</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>rectangle</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=comment>// sort by increasing area</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>global_fun</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=identifier>rectangle</span><span class=special>&amp;,</span><span class=keyword>unsigned</span> <span class=keyword>long</span><span class=special>,&amp;</span><span class=identifier>area</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>rectangle_container</span><span class=special>;</span>
</pre></blockquote>
<p>
The specification of <code>global_fun</code> obeys the following syntax:
</p>
<blockquote><pre>
<span class=identifier>global_fun</span><span class=special>&lt;</span><span class=identifier><i>(argument type)</i></span><span class=special>,</span><span class=identifier><i>(key type)</i></span><span class=special>,</span><span class=identifier><i>(pointer to function)</i></span><span class=special>&gt;</span>
</pre></blockquote>
<p>
where the argument type and key type must match <i>exactly</i> those in the
signature of the function used; for instance, in the example above the argument
type is <code>const rectangle&amp;</code>, without omitting the "<code>const</code>"
and "<code>&amp;</code>" parts. So, although most of the time the base type will be
accepted by constant reference, <code>global_fun</code> is also prepared to take
functions accepting their argument by value or by non-constant reference: this
latter case cannot generally be used directly in the specification of
<code>multi_index_container</code>s as their elements are treated as constant,
but the section on <a href="#advanced_key_extractors">advanced features
of Boost.MultiIndex key extractors</a> describes valid use cases of
key extraction based on such functions with a non-constant reference argument.
</p>
<p><a href="../examples.html#example2">Example 2</a> in the examples section
uses <code>gobal_fun</code>.
<p>
<h2><a name="user_defined_key_extractors">User-defined key extractors</a></h2>
<p>
@ -632,10 +695,12 @@ following final type:
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>T</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>i</span><span class=special>;</span>
<span class=keyword>const</span> <span class=keyword>int</span> <span class=identifier>j</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=keyword>int</span> <span class=identifier>g</span><span class=special>();</span>
<span class=keyword>int</span> <span class=identifier>i</span><span class=special>;</span>
<span class=keyword>const</span> <span class=keyword>int</span> <span class=identifier>j</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=keyword>int</span> <span class=identifier>g</span><span class=special>();</span>
<span class=keyword>static</span> <span class=keyword>int</span> <span class=identifier>gf</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>T</span><span class=special>&amp;);</span>
<span class=keyword>static</span> <span class=keyword>int</span> <span class=identifier>gg</span><span class=special>(</span><span class=identifier>T</span><span class=special>&amp;);</span>
<span class=special>};</span>
</pre></blockquote>
@ -656,7 +721,7 @@ each of its members.
<th>read/write?</th>
</tr>
<tr>
<td align="center" rowspan="4"><code>T</code></td>
<td align="center" rowspan="6"><code>T</code></td>
<td><code>i</code></td>
<td><code>member&lt;T,int,&amp;T::i></code></td>
<td align="center">yes</td>
@ -680,9 +745,21 @@ each of its members.
<td align="center">no</td>
<td align="center">no</td>
</tr>
<tr>
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td><code>gg()</code></td>
<td><code>global_fun&lt;T&amp;,int,&amp;T::gg></code></td>
<td align="center">no</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td align="center" rowspan="4"><code>reference_wrapper&lt;T></code></td>
<td align="center" rowspan="6"><code>reference_wrapper&lt;T></code></td>
<td><code>i</code></td>
<td><code>member&lt;T,int,&amp;T::i></code></td>
<td align="center">yes</td>
@ -706,9 +783,21 @@ each of its members.
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td><code>gg()</code></td>
<td><code>global_fun&lt;T&amp;,int,&amp;T::gg></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td align="center" rowspan="4"><code>reference_wrapper&lt;const T></code></td>
<td align="center" rowspan="6"><code>reference_wrapper&lt;const T></code></td>
<td><code>i</code></td>
<td><code>member&lt;T,const int,&amp;T::i></code></td>
<td align="center">yes</td>
@ -730,9 +819,19 @@ each of its members.
<td><code>g()</code></td>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td><code>gg()</code></td>
<td colspan="3">&nbsp;</td>
</tr>
<tr class="odd_tr">
<td align="center" rowspan="4">chained pointer to <code>T</code><br>
<td align="center" rowspan="6">chained pointer to <code>T</code><br>
or to <code>reference_wrapper&lt;T></code></td>
<td><code>i</code></td>
<td><code>member&lt;T,int,&amp;T::i></code></td>
@ -757,9 +856,21 @@ each of its members.
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td><code>gg()</code></td>
<td><code>global_fun&lt;T&amp;,int,&amp;T::gg></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td align="center" rowspan="4">chained pointer to <code>const T</code><br>
<td align="center" rowspan="6">chained pointer to <code>const T</code><br>
or to <code>reference_wrapper&lt;const T></code></td>
<td><code>i</code></td>
<td><code>member&lt;T,const int,&amp;T::i></code></td>
@ -782,6 +893,16 @@ each of its members.
<td><code>g()</code></td>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td><code>gg()</code></td>
<td colspan="3">&nbsp;</td>
</tr>
</table>
</p>
@ -790,10 +911,12 @@ each of its members.
The column "applicable to <code>const</code> elements?" states whether the
corresponding key extractor can be used when passed constant elements (this
relates to the elements specified in the first column, not the referenced
<code>T</code> objects). The only negative case is for <code>T::g</code> when
the elements are raw <code>T</code> objects, which make sense as we are dealing
with a non-constant member function: this also implies that <code>multi_index_container</code>s
of elements of <code>T</code> cannot be sorted by <code>T::g</code>, because
<code>T</code> objects). The only negative cases are for <code>T::g</code> and
<code>T:gg</code> when the elements are raw <code>T</code> objects, which make sense
as we are dealing with a non-constant member function (<code>T::g</code>)
and a function taking <code>T</code> by
non-constant reference: this also implies that <code>multi_index_container</code>s
of elements of <code>T</code> cannot be sorted by <code>T::g</code> or <code>T::gg</code>, because
elements contained within a <code>multi_index_container</code> are treated as constant.
</p>
@ -804,7 +927,7 @@ The column "read/write?" shows which combinations yield
<p>
Some care has to be taken to preserve <code>const</code>-correctness in the
specification of the key extractors: in some sense, the <code>const</code>
specification of <code>member</code> key extractors: in some sense, the <code>const</code>
qualifier is carried along to the member part, even if that particular
member is not defined as <code>const</code>. For instance, if the elements
are of type <code>const T *</code>, sorting by <code>T::i</code> is <i>not</i>
@ -832,9 +955,9 @@ Container creation
<br>
<p>Revised February 6th 2006</p>
<p>Revised June 11th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -1,6 +1,6 @@
# Boost.MultiIndex examples Jamfile
#
# Copyright 2003-2006 Joaquín M López Muñoz.
# Copyright 2003-2007 Joaquín M López Muñoz.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
@ -27,14 +27,19 @@ exe composite_keys
: <include>$(BOOST_ROOT)
;
exe fun_key
: fun_key.cpp
: <include>$(BOOST_ROOT)
;
exe hashed
: hashed.cpp
: <include>$(BOOST_ROOT)
;
exe memfun_key
: memfun_key.cpp
: <include>$(BOOST_ROOT)
exe ip_allocator
: ip_allocator.cpp
: <include>$(BOOST_ROOT) <threading>multi
;
exe non_default_ctor

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex example of composite keys.
*
* Copyright 2003-2005 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -18,6 +18,7 @@
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/next_prior.hpp>
#include <boost/tokenizer.hpp>
#include <functional>
#include <iostream>
@ -287,7 +288,7 @@ int main()
continue;
}
it->second->execute(++tok.begin(),tok.end());
it->second->execute(boost::next(tok.begin()),tok.end());
}
return 0;

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex example of member functions used as key extractors.
/* Boost.MultiIndex example of functions used as key extractors.
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -14,6 +14,7 @@
#endif
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/global_fun.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <iostream>
@ -46,7 +47,13 @@ private:
std::string family_name;
};
/* multi_index_container with only one index based on name_record::name().
std::string::size_type name_record_length(const name_record& r)
{
return r.name().size();
}
/* multi_index_container with indices based on name_record::name()
* and name_record_length().
* See Compiler specifics: Use of const_mem_fun_explicit and
* mem_fun_explicit for info on BOOST_MULTI_INDEX_CONST_MEM_FUN.
*/
@ -56,6 +63,9 @@ typedef multi_index_container<
indexed_by<
ordered_unique<
BOOST_MULTI_INDEX_CONST_MEM_FUN(name_record,std::string,name)
>,
ordered_non_unique<
global_fun<const name_record&,std::string::size_type,name_record_length>
>
>
> name_record_set;
@ -71,9 +81,20 @@ int main()
/* list the names in ns in phonebook order */
std::cout<<"Phonenook order\n"
<<"---------------"<<std::endl;
for(name_record_set::iterator it=ns.begin();it!=ns.end();++it){
std::cout<<it->name()<<std::endl;
}
/* list the names in ns according to their length*/
std::cout<<"\nLength order\n"
<< "------------"<<std::endl;
for(nth_index_iterator<name_record_set,1>::type it1=get<1>(ns).begin();
it1!=get<1>(ns).end();++it1){
std::cout<<it1->name()<<std::endl;
}
return 0;
}

293
example/ip_allocator.cpp Normal file
View File

@ -0,0 +1,293 @@
/* Boost.MultiIndex example of use of Boost.Interprocess allocators.
*
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
using boost::multi_index_container;
using namespace boost::multi_index;
namespace bip=boost::interprocess;
/* shared_string is a string type placeable in shared memory,
* courtesy of Boost.Interprocess.
*/
typedef bip::basic_string<
char,std::char_traits<char>,
bip::allocator<char,bip::managed_mapped_file::segment_manager>
> shared_string;
/* Book record. All its members can be placed in shared memory,
* hence the structure itself can too.
*/
struct book
{
shared_string name;
shared_string author;
unsigned pages;
unsigned prize;
book(const shared_string::allocator_type& al):
name(al),author(al),pages(0),prize(0)
{}
friend std::ostream& operator<<(std::ostream& os,const book& b)
{
os<<b.author<<": \""<<b.name<<"\", $"<<b.prize<<", "<<b.pages<<" pages\n";
return os;
}
};
/* partial_str_less allows for partial searches taking into account
* only the first n chars of the strings compared against. See
* Tutorial: Basics: Special lookup operations for more info on this
* type of comparison functors.
*/
/* partial_string is a mere string holder used to differentiate from
* a plain string.
*/
struct partial_string
{
partial_string(const shared_string& str):str(str){}
shared_string str;
};
struct partial_str_less
{
bool operator()(const shared_string& x,const shared_string& y)const
{
return x<y;
}
bool operator()(const shared_string& x,const partial_string& y)const
{
return x.substr(0,y.str.size())<y.str;
}
bool operator()(const partial_string& x,const shared_string& y)const
{
return x.str<y.substr(0,x.str.size());
}
};
/* Define a multi_index_container of book records with indices on
* author, name and prize. The index on names allows for partial
* searches. This container can be placed in shared memory because:
* * book can be placed in shared memory.
* * We are using a Boost.Interprocess specific allocator.
*/
/* see Compiler specifics: Use of member_offset for info on
* BOOST_MULTI_INDEX_MEMBER
*/
typedef multi_index_container<
book,
indexed_by<
ordered_non_unique<
BOOST_MULTI_INDEX_MEMBER(book,shared_string,author)
>,
ordered_non_unique<
BOOST_MULTI_INDEX_MEMBER(book,shared_string,name),
partial_str_less
>,
ordered_non_unique<
BOOST_MULTI_INDEX_MEMBER(book,unsigned,prize)
>
>,
bip::allocator<book,bip::managed_mapped_file::segment_manager>
> book_container;
/* A small utility to get data entered via std::cin */
template<typename T>
void enter(const char* msg,T& t)
{
std::cout<<msg;
std::string str;
std::getline(std::cin,str);
std::istringstream iss(str);
iss>>t;
}
void enter(const char* msg,std::string& str)
{
std::cout<<msg;
std::getline(std::cin,str);
}
void enter(const char* msg,shared_string& str)
{
std::cout<<msg;
std::string stdstr;
std::getline(std::cin,stdstr);
str=stdstr.c_str();
}
int main()
{
/* Create (or open) the memory mapped file where the book container
* is stored, along with a mutex for synchronized access.
*/
bip::managed_mapped_file seg(
bip::open_or_create,"./book_container.db",
65536);
bip::named_mutex mutex(
bip::open_or_create,"7FD6D7E8-320B-11DC-82CF-F0B655D89593");
/* create or open the book container in shared memory */
book_container* pbc=seg.find_or_construct<book_container>("book container")(
book_container::ctor_args_list(),
book_container::allocator_type(seg.get_segment_manager()));
std::string command_info=
"1. list books by author\n"
"2. list all books by prize\n"
"3. insert a book\n"
"4. delete a book\n"
"0. exit\n";
std::cout<<command_info;
/* main loop */
for(bool exit=false;!exit;){
int command=-1;
enter("command: ",command);
switch(command){
case 0:{ /* exit */
exit=true;
break;
}
case 1:{ /* list books by author */
std::string author;
enter("author (empty=all authors): ",author);
/* operations with the container must be mutex protected */
bip::scoped_lock<bip::named_mutex> lock(mutex);
std::pair<book_container::iterator,book_container::iterator> rng;
if(author.empty()){
rng=std::make_pair(pbc->begin(),pbc->end());
}
else{
rng=pbc->equal_range(
shared_string(
author.c_str(),
shared_string::allocator_type(seg.get_segment_manager())));
}
if(rng.first==rng.second){
std::cout<<"no entries\n";
}
else{
std::copy(
rng.first,rng.second,std::ostream_iterator<book>(std::cout));
}
break;
}
case 2:{ /* list all books by prize */
bip::scoped_lock<bip::named_mutex> lock(mutex);
std::copy(
get<2>(*pbc).begin(),get<2>(*pbc).end(),
std::ostream_iterator<book>(std::cout));
break;
}
case 3:{ /* insert a book */
book b(shared_string::allocator_type(seg.get_segment_manager()));
enter("author: ",b.author);
enter("name: " ,b.name);
enter("prize: " ,b.prize);
enter("pages: " ,b.pages);
std::cout<<"insert the following?\n"<<b<<"(y/n): ";
char yn='n';
enter("",yn);
if(yn=='y'||yn=='Y'){
bip::scoped_lock<bip::named_mutex> lock(mutex);
pbc->insert(b);
}
break;
}
case 4:{ /* delete a book */
shared_string name(
shared_string::allocator_type(seg.get_segment_manager()));
enter(
"name of the book (you can enter\nonly the first few characters): ",
name);
typedef nth_index<book_container,1>::type index_by_name;
index_by_name& idx=get<1>(*pbc);
index_by_name::iterator it;
book b(shared_string::allocator_type(seg.get_segment_manager()));
{
/* Look for a book whose title begins with name. Note that we
* are unlocking after doing the search so as to not leave the
* container blocked during user prompting. That is also why a
* local copy of the book is done.
*/
bip::scoped_lock<bip::named_mutex> lock(mutex);
it=idx.find(partial_string(name));
if(it==idx.end()){
std::cout<<"no such book found\n";
break;
}
b=*it;
}
std::cout<<"delete the following?\n"<<b<<"(y/n): ";
char yn='n';
enter("",yn);
if(yn=='y'||yn=='Y'){
bip::scoped_lock<bip::named_mutex> lock(mutex);
idx.erase(it);
}
break;
}
default:{
std::cout<<"select one option:\n"<<command_info;
break;
}
}
}
return 0;
}

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex performance test.
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -16,6 +16,7 @@
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/next_prior.hpp>
#include <climits>
#include <ctime>
#include <iomanip>
@ -163,7 +164,7 @@ struct list_wrapper:List
pair<iterator,bool> insert(const value_type& v)
{
List::push_back(v);
return pair<iterator,bool>(--List::end(),true);
return pair<iterator,bool>(boost::prior(List::end()),true);
}
};

View File

@ -1,12 +1,31 @@
# Boost.MultiIndex tests Jamfile
#
# Copyright 2003-2006 Joaquín M López Muñoz.
# Copyright 2003-2007 Joaquín M López Muñoz.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
#
# See http://www.boost.org/libs/multi_index for library home page.
import os ;
import type ;
# Windows Vista UAC has an heuristic by which executable files whose name
# contains any of the words "install", "setup", "update", etc. are assumed
# to be installation packages needing administrative rights, which causes
# the system to bring up a window asking for execution confirmation by the
# user, thus interferring in the unattended bjam process.
# Problem bypassed by changing the EXE names containing a taboo word.
# Thanks to Rene Rivera for guidance on the use of the <tag> feature.
rule change-test_update-exe-name ( name : type ? : property-set )
{
if [ os.on-windows ] && [ type.is-subtype $(type) EXE ]
{
return test_updat.exe ;
}
}
test-suite "multi_index" :
[ run test_basic.cpp test_basic_main.cpp ]
[ run test_capacity.cpp test_capacity_main.cpp ]
@ -26,9 +45,13 @@ test-suite "multi_index" :
[ run test_rearrange.cpp test_rearrange_main.cpp ]
[ run test_safe_mode.cpp test_safe_mode_main.cpp ]
[ run test_serialization.cpp test_serialization1.cpp
test_serialization2.cpp test_serialization_main.cpp
test_serialization2.cpp test_serialization3.cpp
test_serialization_main.cpp
/boost/serialization//boost_serialization ]
[ run test_set_ops.cpp test_set_ops_main.cpp ]
[ run test_special_set_ops.cpp test_special_set_ops_main.cpp ]
[ run test_update.cpp test_update_main.cpp ]
[ run test_update.cpp test_update_main.cpp
: : :
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@change-test_update-exe-name ]
;

View File

@ -1,6 +1,6 @@
/* Used in Boost.MultiIndex tests.
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -23,6 +23,7 @@
#include <cstddef>
#include <ostream>
#include <string>
#include "non_std_allocator.hpp"
struct employee
{
@ -92,7 +93,8 @@ struct employee_set_indices:
typedef
boost::multi_index::multi_index_container<
employee,
employee_set_indices> employee_set;
employee_set_indices,
non_std_allocator<employee> > employee_set;
#if defined(BOOST_NO_MEMBER_TEMPLATES)
typedef boost::multi_index::nth_index<

136
test/non_std_allocator.hpp Normal file
View File

@ -0,0 +1,136 @@
/* Used in Boost.MultiIndex tests.
*
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_TEST_NON_STD_ALLOCATOR_HPP
#define BOOST_MULTI_INDEX_TEST_NON_STD_ALLOCATOR_HPP
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <iterator>
#include <cstddef>
template<typename T>
class non_raw_pointer
{
public:
typedef std::ptrdiff_t difference_type;
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef std::random_access_iterator_tag iterator_category;
non_raw_pointer(){}
explicit non_raw_pointer(T* p_):p(p_){}
T& operator*()const{return *p;}
T* operator->()const{return p;}
non_raw_pointer& operator++(){++p;return *this;}
non_raw_pointer operator++(int){non_raw_pointer t(*this);++p;return t;}
non_raw_pointer& operator--(){--p;return *this;}
non_raw_pointer operator--(int){non_raw_pointer t(*this);--p;return t;}
non_raw_pointer& operator+=(std::ptrdiff_t n){p+=n;return *this;}
non_raw_pointer& operator-=(std::ptrdiff_t n){p-=n;return *this;}
T& operator[](std::ptrdiff_t n)const{return p[n];}
private:
T* p;
};
template<typename T>
non_raw_pointer<T> operator+(const non_raw_pointer<T>& x,std::ptrdiff_t n)
{return non_raw_pointer<T>((&*x)+n);}
template<typename T>
non_raw_pointer<T> operator+(std::ptrdiff_t n,const non_raw_pointer<T>& x)
{return non_raw_pointer<T>(n+(&*x));}
template<typename T>
non_raw_pointer<T> operator-(const non_raw_pointer<T>& x,std::ptrdiff_t n)
{return non_raw_pointer<T>((&*x)-n);}
template<typename T>
std::ptrdiff_t operator-(
const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
{return (&*x)-(&*y);}
template<typename T>
bool operator==(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
{return (&*x)==(&*y);}
template<typename T>
bool operator!=(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
{return (&*x)!=(&*y);}
template<typename T>
bool operator<(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
{return (&*x)<(&*y);}
template<typename T>
bool operator>(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
{return (&*x)>(&*y);}
template<typename T>
bool operator>=(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
{return (&*x)>=(&*y);}
template<typename T>
bool operator<=(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
{return (&*x)<=(&*y);}
template<typename T>
class non_std_allocator
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef non_raw_pointer<T> pointer;
typedef non_raw_pointer<const T> const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template<class U>struct rebind{typedef non_std_allocator<U> other;};
non_std_allocator(){}
non_std_allocator(const non_std_allocator<T>&){}
template<class U>non_std_allocator(const non_std_allocator<U>&,int=0){}
pointer allocate(size_type n)
{
return pointer((T*)(new char[n*sizeof(T)]));
}
void deallocate(pointer p,size_type)
{
delete[](char *)&*p;
}
size_type max_size() const{return (size_type )(-1);}
friend bool operator==(const non_std_allocator&,const non_std_allocator&)
{
return true;
}
friend bool operator!=(const non_std_allocator&,const non_std_allocator&)
{
return false;
}
};
template<>
class non_std_allocator<void>
{
public:
typedef non_raw_pointer<void> pointer;
typedef non_raw_pointer<const void> const_pointer;
typedef void value_type;
template<class U>struct rebind{typedef non_std_allocator<U> other;};
};
#endif

View File

@ -1,6 +1,6 @@
/* Used in Boost.MultiIndex tests.
*
* Copyright 2003-2004 Joaqu匤 M L<EFBFBD>ez Mu<EFBFBD>z.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -32,6 +32,21 @@ inline void increment_int(int& x)
++x;
}
inline void decrement_first(pair_of_ints& p)
{
--p.first;
}
inline void decrement_second(pair_of_ints& p)
{
--p.second;
}
inline void decrement_int(int& x)
{
--x;
}
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
namespace boost{
namespace serialization{

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for capacity memfuns.
*
* Copyright 2003-2006 Joaqu匤 M L<EFBFBD>ez Mu<EFBFBD>z.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -53,6 +53,9 @@ void test_capacity()
ss.resize(5);
BOOST_CHECK(ss.size()==5);
ss.resize(4);
BOOST_CHECK(ss.size()==4);
multi_index_container<int,indexed_by<random_access<> > > rs;
rs.resize(10);

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for copying and assignment.
*
* Copyright 2003-2006 Joaqu匤 M L<EFBFBD>ez Mu<EFBFBD>z.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -57,6 +57,27 @@ static void test_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
#pragma parse_func_templ reset
#endif
template<typename Sequence>
static void test_integral_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
{
/* Special cases described in 23.1.1/9: integral types must not
* be taken as iterators in assign(f,l) and insert(p,f,l).
*/
Sequence s;
s.assign(5,10);
BOOST_CHECK(s.size()==5&&std::accumulate(s.begin(),s.end(),0)==50);
s.assign(2u,5u);
BOOST_CHECK(s.size()==2&&std::accumulate(s.begin(),s.end(),0)==10);
s.clear();
s.insert(s.begin(),5,10);
BOOST_CHECK(s.size()==5&&std::accumulate(s.begin(),s.end(),0)==50);
s.insert(s.begin(),2u,5u);
BOOST_CHECK(s.size()==7&&std::accumulate(s.begin(),s.end(),0)==60);
}
void test_copy_assignment()
{
employee_set es;
@ -130,7 +151,11 @@ void test_copy_assignment()
/* MSVC++ 6.0 chokes on test_assign without this explicit instantiation */
multi_index_container<int,indexed_by<sequenced<> > > s1;
test_assign<multi_index_container<int,indexed_by<sequenced<> > > >();
test_integral_assign<
multi_index_container<int,indexed_by<sequenced<> > > >();
multi_index_container<int,indexed_by<random_access<> > > s2;
test_assign<multi_index_container<int,indexed_by<random_access<> > > >();
test_integral_assign<
multi_index_container<int,indexed_by<random_access<> > > >();
}

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for iterators.
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -13,6 +13,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include "pre_multi_index.hpp"
#include "employee.hpp"
#include <boost/next_prior.hpp>
#include <boost/test/test_tools.hpp>
using namespace boost::multi_index;
@ -25,6 +26,7 @@ void test_non_const_iterators(Index& i,int target)
int n=0;
for(iterator it=i.begin();it!=i.end();++it){
BOOST_CHECK(i.iterator_to(*it)==it);
n+=it->id;
}
int m=0;
@ -51,8 +53,14 @@ void test_const_iterators(const Index& i,int target)
typedef typename Index::const_iterator const_iterator;
typedef typename Index::const_reverse_iterator const_reverse_iterator;
BOOST_CHECK(i.cbegin()==i.begin());
BOOST_CHECK(i.cend()==i.end());
BOOST_CHECK(i.crbegin()==i.rbegin());
BOOST_CHECK(i.crend()==i.rend());
int n=0;
for(const_iterator it=i.begin();it!=i.end();++it){
BOOST_CHECK(i.iterator_to(*it)==it);
n+=it->id;
}
int m=0;
@ -82,11 +90,13 @@ void test_non_const_hashed_iterators(Index& i,int target)
int n=0;
for(iterator it=i.begin();it!=i.end();++it){
BOOST_CHECK(i.iterator_to(*it)==it);
n+=it->id;
}
int m=0;
for(size_type buc=0;buc<i.bucket_count();++buc){
for(local_iterator it=i.begin(buc);it!=i.end(buc);++it){
BOOST_CHECK(i.local_iterator_to(*it)==it);
m+=it->id;
}
}
@ -101,13 +111,20 @@ void test_const_hashed_iterators(const Index& i,int target)
typedef typename Index::const_local_iterator const_local_iterator;
typedef typename Index::size_type size_type;
BOOST_CHECK(i.cbegin()==i.begin());
BOOST_CHECK(i.cend()==i.end());
int n=0;
for(const_iterator it=i.begin();it!=i.end();++it){
BOOST_CHECK(i.iterator_to(*it)==it);
n+=it->id;
}
int m=0;
for(size_type buc=0;buc<i.bucket_count();++buc){
BOOST_CHECK(i.cbegin(buc)==i.begin(buc));
BOOST_CHECK(i.cend(buc)==i.end(buc));
for(const_local_iterator it=i.begin(buc);it!=i.end(buc);++it){
BOOST_CHECK(i.local_iterator_to(*it)==it);
m+=it->id;
}
}
@ -129,16 +146,17 @@ void test_non_const_rnd_iterators(Index& i,int target)
int n=0;
for(iterator it=i.begin();it!=middle;++it){
BOOST_CHECK(i.iterator_to(*it)==it);
n+=it->id;
n+=it[off].id;
}
if(odd)n+=(--i.end())->id;
if(odd)n+=(boost::prior(i.end()))->id;
int m=0;
for(reverse_iterator rit=i.rbegin();rit!=rmiddle;++rit){
m+=rit->id;
m+=(rit+off)->id;
}
if(odd)m+=(--i.rend())->id;
if(odd)m+=(boost::prior(i.rend()))->id;
int p=0;
for(iterator it2=i.end();it2!=middle;){
--it2;
@ -164,6 +182,11 @@ void test_const_rnd_iterators(const Index& i,int target)
typedef typename Index::const_reverse_iterator const_reverse_iterator;
typedef typename Index::difference_type difference_type;
BOOST_CHECK(i.cbegin()==i.begin());
BOOST_CHECK(i.cend()==i.end());
BOOST_CHECK(i.crbegin()==i.rbegin());
BOOST_CHECK(i.crend()==i.rend());
const_iterator middle=i.begin()+(i.end()-i.begin())/2;
difference_type off=middle-i.begin();
const_reverse_iterator rmiddle=i.rbegin()+off;
@ -171,16 +194,17 @@ void test_const_rnd_iterators(const Index& i,int target)
int n=0;
for(const_iterator it=i.begin();it!=middle;++it){
BOOST_CHECK(i.iterator_to(*it)==it);
n+=it->id;
n+=it[off].id;
}
if(odd)n+=(--i.end())->id;
if(odd)n+=(boost::prior(i.end()))->id;
int m=0;
for(const_reverse_iterator rit=i.rbegin();rit!=rmiddle;++rit){
m+=rit->id;
m+=(rit+off)->id;
}
if(odd)m+=(--i.rend())->id;
if(odd)m+=(boost::prior(i.rend()))->id;
int p=0;
for(const_iterator it2=i.end();it2!=middle;){
--it2;

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for key extractors.
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -30,6 +30,10 @@ struct test_class
bool bool_mem_fun_const()const{return true;}
bool bool_mem_fun(){return false;}
static bool bool_global_fun(test_class){return true;}
static bool bool_global_fun_const_ref(const test_class&){return false;}
static bool bool_global_fun_ref(test_class&){return true;}
test_class(int i=0):int_member(i),int_cmember(i){}
test_class(int i,int j):int_member(i),int_cmember(j){}
@ -69,6 +73,15 @@ typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_cmember) key_cm;
typedef BOOST_MULTI_INDEX_CONST_MEM_FUN(
test_class,bool,bool_mem_fun_const) key_cmf;
typedef BOOST_MULTI_INDEX_MEM_FUN(test_class,bool,bool_mem_fun) key_mf;
typedef global_fun<test_class,bool,&test_class::bool_global_fun> key_gf;
typedef global_fun<
const test_class&,bool,
&test_class::bool_global_fun_const_ref
> key_gcrf;
typedef global_fun<
test_class&,bool,
&test_class::bool_global_fun_ref
> key_grf;
typedef composite_key<
test_class,
idn,
@ -84,7 +97,7 @@ typedef composite_key<
typedef composite_key<
boost::reference_wrapper<test_class>,
key_mf
> ccompw_key;
> ccompw_key;
#if !defined(BOOST_NO_SFINAE)
/* testcases for problems with non-copyable classes reported at
@ -99,6 +112,9 @@ struct test_nc_class
bool bool_mem_fun_const()const{return true;}
bool bool_mem_fun(){return false;}
static bool bool_global_fun_const_ref(const test_nc_class&){return false;}
static bool bool_global_fun_ref(test_nc_class&){return true;}
test_nc_class(int i=0):int_member(i),int_cmember(i){}
test_nc_class(int i,int j):int_member(i),int_cmember(j){}
@ -129,6 +145,14 @@ typedef BOOST_MULTI_INDEX_CONST_MEM_FUN(
test_nc_class,bool,bool_mem_fun_const) nc_key_cmf;
typedef BOOST_MULTI_INDEX_MEM_FUN(
test_nc_class,bool,bool_mem_fun) nc_key_mf;
typedef global_fun<
const test_nc_class&,bool,
&test_nc_class::bool_global_fun_const_ref
> nc_key_gcrf;
typedef global_fun<
test_nc_class&,bool,
&test_nc_class::bool_global_fun_ref
> nc_key_grf;
typedef composite_key<
test_nc_class,
nc_idn,
@ -147,6 +171,9 @@ void test_key_extractors()
key_cm k_cm;
key_cmf k_cmf;
key_mf k_mf;
key_gf k_gf;
key_gcrf k_gcrf;
key_grf k_grf;
compkey cmpk;
ccompkey ccmpk;
ccompw_key ccmpk_w;
@ -329,6 +356,71 @@ void test_key_extractors()
BOOST_CHECK(!k_mf(tpp));
BOOST_CHECK(!k_mf(tap));
BOOST_CHECK(!k_mf(tw));
BOOST_CHECK(k_gf(tr));
BOOST_CHECK(k_gf(ctr));
#if !defined(BOOST_NO_SFINAE)
BOOST_CHECK(k_gf(td));
BOOST_CHECK(k_gf(ctdr));
#endif
BOOST_CHECK(k_gf(tp));
BOOST_CHECK(k_gf(ctp));
#if !defined(BOOST_NO_SFINAE)
BOOST_CHECK(k_gf(tdp));
BOOST_CHECK(k_gf(ctdp));
#endif
BOOST_CHECK(k_gf(tpp));
BOOST_CHECK(k_gf(ctpp));
BOOST_CHECK(k_gf(tap));
BOOST_CHECK(k_gf(ctap));
BOOST_CHECK(k_gf(tw));
BOOST_CHECK(k_gf(ctw));
BOOST_CHECK(!k_gcrf(tr));
BOOST_CHECK(!k_gcrf(ctr));
#if !defined(BOOST_NO_SFINAE)
BOOST_CHECK(!k_gcrf(td));
BOOST_CHECK(!k_gcrf(ctdr));
#endif
BOOST_CHECK(!k_gcrf(tp));
BOOST_CHECK(!k_gcrf(ctp));
#if !defined(BOOST_NO_SFINAE)
BOOST_CHECK(!k_gcrf(tdp));
BOOST_CHECK(!k_gcrf(ctdp));
#endif
BOOST_CHECK(!k_gcrf(tpp));
BOOST_CHECK(!k_gcrf(ctpp));
BOOST_CHECK(!k_gcrf(tap));
BOOST_CHECK(!k_gcrf(ctap));
BOOST_CHECK(!k_gcrf(tw));
BOOST_CHECK(!k_gcrf(ctw));
BOOST_CHECK(k_grf(tr));
#if !defined(BOOST_NO_SFINAE)
BOOST_CHECK(k_grf(td));
#endif
BOOST_CHECK(k_grf(tp));
#if !defined(BOOST_NO_SFINAE)
BOOST_CHECK(k_grf(tdp));
#endif
BOOST_CHECK(k_grf(tpp));
BOOST_CHECK(k_grf(tap));
BOOST_CHECK(k_grf(tw));
BOOST_CHECK(ccmpk_w(tw)==make_tuple(false));
#if !defined(BOOST_NO_SFINAE)
@ -342,6 +434,8 @@ void test_key_extractors()
nc_ckey_m nc_ck_m;
nc_key_cmf nc_k_cmf;
nc_key_mf nc_k_mf;
nc_key_gcrf nc_k_gcrf;
nc_key_grf nc_k_grf;
nc_compkey nc_cmpk;
test_nc_derived_class nc_td(-1,0);
@ -357,6 +451,9 @@ void test_key_extractors()
BOOST_CHECK(nc_k_cmf(nc_td));
BOOST_CHECK(!nc_k_mf(nc_td));
BOOST_CHECK(!nc_k_gcrf(nc_td));
BOOST_CHECK(nc_k_grf(nc_td));
test_nc_class nc_t(1,0);
BOOST_CHECK(nc_cmpk(nc_td)==make_tuple(boost::cref(nc_t),1,1,true));
#endif
@ -370,6 +467,9 @@ void test_key_extractors()
BOOST_CHECK(k_cm(it)==j);
BOOST_CHECK(k_cmf(it));
BOOST_CHECK(!k_mf(it));
BOOST_CHECK(k_gf(it));
BOOST_CHECK(!k_gcrf(it));
BOOST_CHECK(k_grf(it));
BOOST_CHECK(cmpk(it)==make_tuple(test_class(j),j,j,true));
BOOST_CHECK(ccmpk(it)==make_tuple(test_class(j),j));
++j;

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for modifier memfuns.
*
* Copyright 2003-2006 Joaqu匤 M L<EFBFBD>ez Mu<EFBFBD>z.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -11,9 +11,12 @@
#include "test_modifiers.hpp"
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/next_prior.hpp>
#include <iterator>
#include <vector>
#include "pre_multi_index.hpp"
#include "employee.hpp"
#include <boost/next_prior.hpp>
#include <boost/test/test_tools.hpp>
class always_one
@ -283,4 +286,31 @@ void test_modifiers()
aoc.insert(always_one());
aoc.erase(*(aoc.begin()));
BOOST_CHECK(aoc.empty());
/* Testcases for compliance with "as close to hint as possible"
* proposed behavior for associative containers:
* http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233
* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html
*/
typedef multi_index_container<
int,
indexed_by<
ordered_non_unique<identity<int> >
>
> int_non_unique_container;
int_non_unique_container c;
c.insert(0);c.insert(0);
c.insert(1);c.insert(1);
c.insert(2);c.insert(2);
BOOST_CHECK(std::distance(c.begin(),c.insert(c.begin(),1))==2);
BOOST_CHECK(std::distance(c.begin(),c.insert(boost::next(c.begin()),1))==2);
BOOST_CHECK(std::distance(c.begin(),c.insert(c.lower_bound(1),1))==2);
BOOST_CHECK(
std::distance(c.begin(),c.insert(boost::next(c.lower_bound(1)),1))==3);
BOOST_CHECK(std::distance(c.begin(),c.insert(c.upper_bound(1),1))==8);
BOOST_CHECK(std::distance(c.begin(),c.insert(boost::prior(c.end()),1))==9);
BOOST_CHECK(std::distance(c.begin(),c.insert(c.end(),1))==10);
}

View File

@ -104,15 +104,17 @@ void test_range()
std::bind1st(std::less<int>(),7), /* 7 < x */
std::bind2nd(std::less_equal<int>(),7)); /* x <= 7 */
CHECK_VOID_RANGE(p);
BOOST_CHECK(p.first==is.upper_bound(7));
p=is.range(
std::bind1st(std::less_equal<int>(),8), /* 8 <= x */
std::bind2nd(std::less<int>(),2)); /* x < 2 */
CHECK_VOID_RANGE(p);
BOOST_CHECK(p.first==is.lower_bound(8));
p=is.range(
std::bind1st(std::less<int>(),4), /* 4 < x */
std::bind2nd(std::less<int>(),5)); /* x < 5 */
CHECK_VOID_RANGE(p);
BOOST_CHECK(p.first!=is.end()&&p.second!=is.end());
BOOST_CHECK(p.first!=is.end());
}

View File

@ -17,6 +17,7 @@
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/next_prior.hpp>
#include <boost/ref.hpp>
#include <boost/test/test_tools.hpp>
#include <vector>
@ -87,7 +88,7 @@ static void local_test_rearrange(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
CHECK_EQUAL(sc,{3 _ 2 _ 4 _ 5 _ 0 _ 1});
BOOST_CHECK(std::distance(it,it2)==3);
sc.relocate(--(sc.end()),it,it2);
sc.relocate(boost::prior(sc.end()),it,it2);
CHECK_EQUAL(sc,{3 _ 0 _ 2 _ 4 _ 5 _ 1});
std::vector<boost::reference_wrapper<const value_type> > v;

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for serialization.
*
* Copyright 2003-2006 Joaqu匤 M L<EFBFBD>ez Mu<EFBFBD>z.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -11,9 +11,11 @@
#include "test_serialization.hpp"
#include "test_serialization1.hpp"
#include "test_serialization2.hpp"
#include "test_serialization3.hpp"
void test_serialization()
{
test_serialization1();
test_serialization2();
test_serialization3();
}

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for serialization, part 1.
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -8,7 +8,7 @@
* See http://www.boost.org/libs/multi_index for library home page.
*/
#include "test_serialization.hpp"
#include "test_serialization1.hpp"
#include "test_serialization_template.hpp"
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
@ -16,6 +16,7 @@
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include "non_std_allocator.hpp"
using namespace boost::multi_index;
@ -49,7 +50,8 @@ void test_serialization1()
random_access<>,
sequenced<>,
ordered_non_unique<identity<int> >
>
>,
non_std_allocator<int>
> multi_index_t;
multi_index_t m;

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for serialization, part 2.
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -8,97 +8,18 @@
* See http://www.boost.org/libs/multi_index for library home page.
*/
#include "test_serialization.hpp"
#include "test_serialization2.hpp"
#include "test_serialization_template.hpp"
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include "non_std_allocator.hpp"
#include "pair_of_ints.hpp"
using namespace boost::multi_index;
void test_hashed_index_serialization()
{
const int N=100;
const int SHUFFLE=10232;
typedef multi_index_container<
int,
indexed_by<
hashed_unique<identity<int> >,
sequenced<>
>
> hashed_set;
typedef hashed_set::iterator iterator;
typedef hashed_set::local_iterator local_iterator;
hashed_set hs;
for(int i=0;i<N;++i){
hs.insert(i*SHUFFLE);
}
std::ostringstream oss;
{
boost::archive::text_oarchive oa(oss);
oa<<const_cast<const hashed_set&>(hs);
std::vector<iterator> its(N);
for(int i=0;i<N;++i){
iterator it=hs.find(i*SHUFFLE);
its.push_back(it);
oa<<const_cast<const iterator&>(its.back());
}
iterator it=hs.end();
oa<<const_cast<const iterator&>(it);
std::vector<local_iterator> lits(2*N);
for(std::size_t buc=0;buc<hs.bucket_count();++buc){
for(local_iterator lit=hs.begin(buc),lit_end=hs.end(buc);
lit!=lit_end;++lit){
oa<<*lit;
lits.push_back(lit);
oa<<const_cast<const local_iterator&>(lits.back());
}
local_iterator lit2=hs.end(buc);
lits.push_back(lit2);
oa<<const_cast<const local_iterator&>(lits.back());
}
}
hashed_set hs2;
std::istringstream iss(oss.str());
boost::archive::text_iarchive ia(iss);
ia>>hs2;
BOOST_CHECK(get<1>(hs)==get<1>(hs2));
for(int j=0;j<N;++j){
iterator it;
ia>>it;
BOOST_CHECK(*it==j*SHUFFLE);
}
iterator it;
ia>>it;
BOOST_CHECK(it==hs2.end());
for(std::size_t buc=0;buc<hs2.bucket_count();++buc){
for(std::size_t k=0;k<hs2.bucket_size(buc);++k){
int n;
local_iterator it;
ia>>n;
ia>>it;
BOOST_CHECK(*it==n);
}
local_iterator it2;
ia>>it2;
BOOST_CHECK(it2==hs2.end(buc));
}
}
void test_serialization2()
{
{
@ -113,7 +34,8 @@ void test_serialization2()
>,
random_access<>,
sequenced<>
>
>,
non_std_allocator<pair_of_ints>
> multi_index_t;
multi_index_t m;
@ -156,5 +78,4 @@ void test_serialization2()
m.insert(pair_of_ints(3,2));
test_serialization(m);
}
test_hashed_index_serialization();
}

View File

@ -0,0 +1,99 @@
/* Boost.MultiIndex test for serialization, part 3.
*
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#include "test_serialization3.hpp"
#include "test_serialization_template.hpp"
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include "non_std_allocator.hpp"
using namespace boost::multi_index;
void test_serialization3()
{
const int N=100;
const int SHUFFLE=10232;
typedef multi_index_container<
int,
indexed_by<
hashed_unique<identity<int> >,
sequenced<>
>,
non_std_allocator<int>
> hashed_set;
typedef hashed_set::iterator iterator;
typedef hashed_set::local_iterator local_iterator;
hashed_set hs;
for(int i=0;i<N;++i){
hs.insert(i*SHUFFLE);
}
std::ostringstream oss;
{
boost::archive::text_oarchive oa(oss);
oa<<const_cast<const hashed_set&>(hs);
std::vector<iterator> its(N);
for(int i=0;i<N;++i){
iterator it=hs.find(i*SHUFFLE);
its.push_back(it);
oa<<const_cast<const iterator&>(its.back());
}
iterator it=hs.end();
oa<<const_cast<const iterator&>(it);
std::vector<local_iterator> lits(2*N);
for(std::size_t buc=0;buc<hs.bucket_count();++buc){
for(local_iterator lit=hs.begin(buc),lit_end=hs.end(buc);
lit!=lit_end;++lit){
oa<<*lit;
lits.push_back(lit);
oa<<const_cast<const local_iterator&>(lits.back());
}
local_iterator lit2=hs.end(buc);
lits.push_back(lit2);
oa<<const_cast<const local_iterator&>(lits.back());
}
}
hashed_set hs2;
std::istringstream iss(oss.str());
boost::archive::text_iarchive ia(iss);
ia>>hs2;
BOOST_CHECK(boost::multi_index::get<1>(hs)==boost::multi_index::get<1>(hs2));
for(int j=0;j<N;++j){
iterator it;
ia>>it;
BOOST_CHECK(*it==j*SHUFFLE);
}
iterator it;
ia>>it;
BOOST_CHECK(it==hs2.end());
for(std::size_t buc=0;buc<hs2.bucket_count();++buc){
for(std::size_t k=0;k<hs2.bucket_size(buc);++k){
int n;
local_iterator it;
ia>>n;
ia>>it;
BOOST_CHECK(*it==n);
}
local_iterator it2;
ia>>it2;
BOOST_CHECK(it2==hs2.end(buc));
}
}

View File

@ -0,0 +1,11 @@
/* Boost.MultiIndex test for serialization, part 3.
*
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
void test_serialization3();

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex serialization tests template.
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -26,9 +26,7 @@ struct all_indices_equal_helper
static bool compare(
const MultiIndexContainer& m1,const MultiIndexContainer& m2)
{
using namespace boost::multi_index;
if(!(get<N>(m1)==get<N>(m2))){
if(!(boost::multi_index::get<N>(m1)==boost::multi_index::get<N>(m2))){
return false;
}
return all_indices_equal_helper<N-1>::compare(m1,m2);
@ -60,8 +58,6 @@ bool all_indices_equal(
template<class MultiIndexContainer>
void test_serialization(const MultiIndexContainer& m)
{
using namespace boost::multi_index;
typedef typename MultiIndexContainer::iterator iterator;
typedef typename MultiIndexContainer::const_iterator const_iterator;
@ -100,10 +96,10 @@ void test_serialization(const MultiIndexContainer& m)
iterator it4;
it4=--it2;
BOOST_CHECK(it==it4);
BOOST_CHECK(it==project<0>(m2,it4));
BOOST_CHECK(it==boost::multi_index::project<0>(m2,it4));
}
iterator it2;
ia>>it2;
BOOST_CHECK(it_end==it2);
BOOST_CHECK(it_end==project<0>(m2,it2));
BOOST_CHECK(it_end==boost::multi_index::project<0>(m2,it2));
}

View File

@ -1,6 +1,6 @@
/* Boost.MultiIndex test for replace(), modify() and modify_key().
*
* Copyright 2003-2006 Joaquín M López Muñoz.
* Copyright 2003-2007 Joaquín M López Muñoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -15,6 +15,7 @@
#include "pre_multi_index.hpp"
#include "employee.hpp"
#include "pair_of_ints.hpp"
#include <boost/next_prior.hpp>
#include <boost/test/test_tools.hpp>
using namespace boost::multi_index;
@ -64,34 +65,44 @@ void test_update()
BOOST_CHECK(!ii2.replace(ii2.begin(),pair_of_ints(0,5)));
BOOST_CHECK(!ii1.replace(project<1>(iis,iis.begin()),pair_of_ints(5,11)));
BOOST_CHECK(!iis.replace(iis.begin(),pair_of_ints(11,5)));
BOOST_CHECK(!iis.replace(++iis.begin(),pair_of_ints(10,5)));
BOOST_CHECK(!iis.replace(boost::next(iis.begin()),pair_of_ints(10,5)));
BOOST_CHECK(!ii1.replace(
project<1>(iis,++iis.begin()),pair_of_ints(5,10)));
BOOST_CHECK(!iis.replace(--iis.end(),pair_of_ints(5,10)));
BOOST_CHECK(!ii2.replace(--ii2.end(),pair_of_ints(10,5)));
project<1>(iis,boost::next(iis.begin())),pair_of_ints(5,10)));
BOOST_CHECK(!iis.replace(boost::prior(iis.end()),pair_of_ints(5,10)));
BOOST_CHECK(!ii2.replace(boost::prior(ii2.end()),pair_of_ints(10,5)));
BOOST_CHECK(iis.modify(iis.begin(),increment_first));
BOOST_CHECK(ii2.modify(ii2.begin(),increment_first));
BOOST_CHECK(ii1.modify(project<1>(iis,iis.begin()),increment_first));
BOOST_CHECK(ii2.modify(ii2.begin(),increment_first));
BOOST_CHECK(ii2.modify(ii2.begin(),increment_first,decrement_first));
BOOST_CHECK(!iis.modify(iis.begin(),increment_first,decrement_first));
BOOST_CHECK(iis.size()==3);
BOOST_CHECK(!iis.modify(iis.begin(),increment_first));
BOOST_CHECK(iis.size()==2);
iis.insert(pair_of_ints(0,0));
BOOST_CHECK(ii2.modify(--ii2.end(),increment_second));
BOOST_CHECK(iis.modify(iis.begin(),increment_second));
BOOST_CHECK(ii2.modify(--ii2.end(),increment_second));
BOOST_CHECK(ii2.modify(boost::prior(ii2.end()),increment_second));
BOOST_CHECK(iis.modify(iis.begin(),increment_second));
BOOST_CHECK(ii2.modify(boost::prior(ii2.end()),increment_second));
BOOST_CHECK(iis.modify(iis.begin(),increment_second,decrement_second));
BOOST_CHECK(!ii2.modify(--ii2.end(),increment_second));
BOOST_CHECK(!ii2.modify(
boost::prior(ii2.end()),increment_second,decrement_second));
BOOST_CHECK(ii2.size()==3);
BOOST_CHECK(!ii2.modify(boost::prior(ii2.end()),increment_second));
BOOST_CHECK(ii2.size()==2);
iis.insert(pair_of_ints(0,0));
BOOST_CHECK(iis.modify_key(iis.begin(),increment_int));
BOOST_CHECK(iis.modify_key(iis.begin(),increment_int,decrement_int));
BOOST_CHECK(iis.modify_key(iis.begin(),increment_int));
BOOST_CHECK(iis.modify_key(iis.begin(),increment_int));
BOOST_CHECK(iis.modify_key(iis.begin(),increment_int));
BOOST_CHECK(!iis.modify_key(iis.begin(),increment_int,decrement_int));
BOOST_CHECK(iis.size()==3);
BOOST_CHECK(!iis.modify_key(iis.begin(),increment_int));
BOOST_CHECK(iis.size()==2);
@ -99,8 +110,11 @@ void test_update()
nth_index_iterator<int_int_set,1>::type it=ii1.find(5);
BOOST_CHECK(ii1.modify_key(it,increment_int));
BOOST_CHECK(ii1.modify_key(it,increment_int));
BOOST_CHECK(ii1.modify_key(it,increment_int,decrement_int));
BOOST_CHECK(ii1.modify_key(it,increment_int));
BOOST_CHECK(ii1.modify_key(it,increment_int));
BOOST_CHECK(!ii1.modify_key(it,increment_int,decrement_int));
BOOST_CHECK(ii1.size()==2);
BOOST_CHECK(!ii1.modify_key(it,increment_int));
BOOST_CHECK(ii1.size()==1);
@ -127,23 +141,30 @@ void test_update()
BOOST_CHECK(!iis.replace(p2,pair_of_ints(10,5)));
BOOST_CHECK(!iis.replace(p2,pair_of_ints(5,10)));
BOOST_CHECK(!iis.replace(p3,pair_of_ints(5,10)));
BOOST_CHECK(!ii1.replace(--ii1.end(),pair_of_ints(10,5)));
BOOST_CHECK(!ii1.replace(boost::prior(ii1.end()),pair_of_ints(10,5)));
BOOST_CHECK(iis.modify(p1,increment_first));
BOOST_CHECK(ii1.modify(ii1.begin(),increment_first));
BOOST_CHECK(iis.modify(p1,increment_first));
BOOST_CHECK(ii1.modify(ii1.begin(),increment_first));
BOOST_CHECK(ii1.modify(ii1.begin(),increment_first,decrement_first));
BOOST_CHECK(!iis.modify(p1,increment_first,decrement_first));
BOOST_CHECK(iis.size()==3);
BOOST_CHECK(!iis.modify(p1,increment_first));
BOOST_CHECK(iis.size()==2);
p1=iis.insert(pair_of_ints(0,0)).first;
BOOST_CHECK(ii1.modify(--ii1.end(),increment_second));
BOOST_CHECK(iis.modify(p1,increment_second));
BOOST_CHECK(ii1.modify(--ii1.end(),increment_second));
BOOST_CHECK(ii1.modify(boost::prior(ii1.end()),increment_second));
BOOST_CHECK(iis.modify(p1,increment_second,decrement_second));
BOOST_CHECK(ii1.modify(boost::prior(ii1.end()),increment_second));
BOOST_CHECK(iis.modify(p1,increment_second));
BOOST_CHECK(!ii1.modify(--ii1.end(),increment_second));
BOOST_CHECK(!ii1.modify(
boost::prior(ii1.end()),increment_second,decrement_second));
BOOST_CHECK(ii1.size()==3);
BOOST_CHECK(!ii1.modify(boost::prior(ii1.end()),increment_second));
BOOST_CHECK(ii1.size()==2);
}
}