mirror of
https://github.com/boostorg/multi_index.git
synced 2026-07-21 13:23:43 +00:00
Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a29d4ac2f | |||
| b35a722129 | |||
| 67f9c5b3ab | |||
| 026fab85aa | |||
| 71fbbf1754 | |||
| 84e34e45c3 | |||
| 768432afcb | |||
| 48eab15fc0 | |||
| 13842a23dc | |||
| e4771a0fae | |||
| eb1f2a98b7 | |||
| 215d795984 | |||
| efce67f27b | |||
| 5fd288b095 | |||
| 588e7657f3 | |||
| d2efd9d5ed | |||
| b185884ffe | |||
| f88fb07ae8 | |||
| 718559b87f | |||
| 180f64dc11 | |||
| ff51956131 | |||
| 3199ff1b44 | |||
| 6d2c3985f0 | |||
| d3e74bc941 | |||
| f5976c1695 | |||
| b61b58abfa | |||
| d026f22be0 | |||
| 8c5ac57c6a | |||
| df5eb5b646 | |||
| c2d5785ae8 | |||
| ebf92487ae | |||
| bd8ea1bc86 | |||
| 93da3b3f29 | |||
| faf18a55f0 | |||
| 0468378c0d | |||
| 9b4c07478c | |||
| 1434c7d727 | |||
| 33e19c4ce1 | |||
| 47079d4620 | |||
| 543fbad471 | |||
| 5d2015ed2e | |||
| add267a90a | |||
| de9febb387 | |||
| 93d21ea64c | |||
| 28930f64c0 | |||
| 6418bd5e83 | |||
| e46279d9ec | |||
| 99284aa1c5 | |||
| c41ded0890 | |||
| 0c0acfaa3f | |||
| 5c5ca84a23 | |||
| 48764f7801 | |||
| f91af5453c | |||
| 87383bcc10 | |||
| d7f2c3606b | |||
| 3a663bd7c4 | |||
| 37ac7c0377 | |||
| 75de04b6f8 |
@@ -1,16 +0,0 @@
|
||||
# Boost.MultiIndex examples and tests Jamfile
|
||||
#
|
||||
# Copyright 2003-2004 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.
|
||||
|
||||
subproject libs/multi_index ;
|
||||
|
||||
# please order by name to ease maintenance
|
||||
|
||||
subinclude libs/multi_index/example ;
|
||||
subinclude libs/multi_index/test ;
|
||||
subinclude libs/multi_index/perf ;
|
||||
@@ -135,7 +135,10 @@ Maxim Yegorushkin proposed a valuable
|
||||
for ordered indices and provided figures of its impact on performance
|
||||
for containers with large numbers of elements.
|
||||
Caleb Epstein performed the tests under MSVC++ 8.0 described in the
|
||||
performance section.
|
||||
performance section. The following people have reported bugs and problems with
|
||||
previous versions and prereleases of the library: Alexei Alexandrov,
|
||||
Matías Capeletto, John Eddy, Martin Eigel, Guillaume Lazzara,
|
||||
Felipe Magno de Almeida, Julien Pervillé, Hubert Schmid, Toby Smith.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -145,6 +148,30 @@ 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í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ías Capeletto. Steven Watanabe spotted an
|
||||
include guard bug present from the first release of the library.
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_36">Boost 1.36 release</a></h2>
|
||||
|
||||
<p>
|
||||
Thanks to Amit Jain for reporting a problem with allocator management.
|
||||
Michael Fawcett proposed the addition of an allocator constructor to
|
||||
<code>multi_index_container</code>.
|
||||
A report from Zachary Zhou has led to
|
||||
<a href="release_notes.html#stable_update">enhancing the behavior of
|
||||
hashed indices update functions</a> so that they meet some intuitive expectations.
|
||||
Grzegorz Jakacki spotted some internal dead code.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="release_notes.html"><img src="prev.gif" alt="release notes" border="0"><br>
|
||||
@@ -158,9 +185,9 @@ Index
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised June 25th 2008</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2008 Joaquín M López Muñ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">
|
||||
|
||||
+177
-95
@@ -36,9 +36,9 @@ along with suitable workarounds when available.
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#bcb_64">Borland C++ Builder 6.4</a></li>
|
||||
<li><a href="#comeau_433_win_vc7_71">Comeau C/C++ 4.3.3 for Windows (VC++ 7.0/7.1 backend)</a></li>
|
||||
<li><a href="#compaq_65">Compaq C++ 6.5-042 for Tru64 UNIX and later</a></li>
|
||||
<li><a href="#bcb_64">Borland C++ Builder 6.4 and later</a></li>
|
||||
<li><a href="#comeau_43101_win_vc7_71">Comeau C/C++ 4.3.10.1 for Windows (VC++ 9.0 backend)</a></li>
|
||||
<li><a href="#compaq_65">Compaq C++ 6.5-042 and later for Tru64 UNIX</a></li>
|
||||
<li>
|
||||
<a href="#gcc_32">GNU GCC 3.2 and later</a>
|
||||
<ul>
|
||||
@@ -46,21 +46,31 @@ along with suitable workarounds when available.
|
||||
<li><a href="#gcc_4_darwin">Darwin GCC 4.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#acc_60">HP aC++ A.06.00 for HP-UX</a></li>
|
||||
<li><a href="#acc_612_ia64">HP aC++ A.06.12 and later for HP-UX IA64</a></li>
|
||||
<li><a href="#acc_380_pa_risc">HP aC++ A.03.80 for HP-UX PA-RISC</a></li>
|
||||
<li><a href="#va_60">IBM VisualAge C++ V6.0 for AIX</a></li>
|
||||
<li><a href="#intel_71_lin">Intel C++ Compiler for Linux 7.1 and later</a></li>
|
||||
<li><a href="#intel_em64t_81_lin">Intel C++ Compiler Extended Memory 64 Technology 8.1 for Linux</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_71_win_stlport_453">Intel C++ Compiler for Windows 32-bit 7.1 + STLport 4.5.3</a></li>
|
||||
<li><a href="#xl_90">IBM XL C/C++ V9.0 for AIX and later</a></li>
|
||||
<li><a href="#intel_81_lin">Intel C++ Compiler for Linux 8.1 and later</a></li>
|
||||
<li><a href="#intel_91_mac">Intel C++ Compiler for Mac OS 9.1 and later</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_100_win64">Intel C++ Compiler for Windows 64-bit 10.0 and later</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><a href="#msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a></li>
|
||||
<li><a href="#msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5 + STLport 4.5.3</a></li>
|
||||
<li><a href="#msvc_70">Microsoft Visual C++ 7.0</a></li>
|
||||
<li>
|
||||
<a href="#msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a>
|
||||
<ul>
|
||||
<li><a href="#msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5 + STLport 4.5.3 and later</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#msvc_70">Microsoft Visual C++ 7.0</a>
|
||||
<ul>
|
||||
<li><a href="#msvc_70_stlport_501">Microsoft Visual C++ 7.0 + STLport 5.0.1</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#msvc_71">Microsoft Visual C++ 7.1</a></li>
|
||||
<li><a href="#msvc_71_stlport_462">Microsoft Visual C++ 7.1 + STLport 4.6.2</a></li>
|
||||
<li><a href="#msvc_80">Microsoft Visual C++ 8.0</a></li>
|
||||
<li><a href="#msvc_80">Microsoft Visual C++ 8.0 and later</a></li>
|
||||
<li><a href="#sun_10">Sun Studio 10 and later for Solaris</a></li>
|
||||
<li><a href="#portability">Portability techniques</a>
|
||||
<ul>
|
||||
<li><a href="#member_offset">Use of <code>member_offset</code></a></li>
|
||||
@@ -78,27 +88,36 @@ along with suitable workarounds when available.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="bcb_64">Borland C++ Builder 6.4</a></h2>
|
||||
<h2><a name="bcb_64">Borland C++ Builder 6.4 and later</a></h2>
|
||||
|
||||
<p>
|
||||
Currently, Boost.MultiIndex cannot be used with BCB 6.4. The
|
||||
number of problems encountered during the tests makes it unlikely that
|
||||
future versions of the library can be made to work under
|
||||
this compiler.
|
||||
Currently, Boost.MultiIndex cannot be used with any of BCB 6.4 up to BCB 2006
|
||||
and CodeGear C++Builder 2010.
|
||||
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>
|
||||
<h2><a name="comeau_43101_win_vc7_71">Comeau C/C++ 4.3.10.1 for Windows (VC++ 9.0 backend)</a></h2>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.38. 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.
|
||||
however, when Microsoft Visual C++ 6.0 is used as the backend. Last time they were
|
||||
tested (Boost.1.34.1), VC++ 7.0/7.1 backends worked correctly. The beta 2 version of
|
||||
the Comeau compiler 4.3.10.1 has been used.
|
||||
</p>
|
||||
|
||||
<h2><a name="compaq_65">Compaq C++ 6.5-042 for Tru64 UNIX and later</a></h2>
|
||||
<h2><a name="compaq_65">Compaq C++ 6.5-042 and later for Tru64 UNIX</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.
|
||||
<b>Note:</b> Last tested in Boost 1.38. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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>
|
||||
@@ -106,23 +125,18 @@ No problems have been detected with this compiler. Versions 6.5-042,
|
||||
<p>
|
||||
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 20020903 under Linux,</li>
|
||||
<li>GCC 3.2 20020927 (prerelease) under Cygwin 1.5.7,</li>
|
||||
<li>GCC 3.2.3 under Linux, (mingw special 20030504-1) under Win32,</li>
|
||||
<li>GCC 3.3 20030304 (Apple builds 1666 and 1671) under Mac OS,</li>
|
||||
<li>GCC 3.3.3 (cygwin special) under Cygwin 1.5.7,</li>
|
||||
<li>GCC 3.3.5 under Linux,</li>
|
||||
<li>GCC 3.3.6 under Linux and Tru64 (see <a href="#gcc_tru64">below</a>),</li>
|
||||
<li>GCC 3.4.2 (mingw-special) under Win32,</li>
|
||||
<li>GCC 3.4.3 under Linux, Solaris and Tru64 (see <a href="#gcc_tru64">below</a>),</li>
|
||||
<li>GCC 3.4.4 (cygming special) under Cygwin, under Gentoo Linux PPC64, under Linux,
|
||||
under Tru64 (see <a href="#gcc_tru64">below</a>), (mingw special) under Win32,</li>
|
||||
<li>GCC 4.0.0 20041026 (Apple build 4061) under Mac OS
|
||||
(see <a href="#gcc_4_darwin">below</a>),</li>
|
||||
<li>GCC 4.0.0 under Linux, (Apple build 5026) under Mac OS,</li>
|
||||
<li>GCC 4.0.1 under Linux and Tru64 (see <a href="#gcc_tru64">below</a>),</li>
|
||||
<li>GCC 4.0.2 under Linux.</li>
|
||||
<ul>
|
||||
<li>GCC 3.4.3 under Linux x86-64,</li>
|
||||
<li>GCC 4.0.1 (Apple Computer, Inc. build 5370), (Apple Inc. build 5490), (Apple Inc. build 5493) under Mac OS,</li>
|
||||
<li>GCC 4.1.2 20080704 (Red Hat 4.1.2-44) under Linux x86-64,</li>
|
||||
<li>GCC 4.2.1 20070719 [FreeBSD] under FreeBSD,</li>
|
||||
<li>GCC 4.2.4 under Linux x86-64,</li>
|
||||
<li>GCC 4.3.2 under Linux x86-64,</li>
|
||||
<li>GCC 4.3.3 under Linux x86-64,</li>
|
||||
<li>GCC 4.3.3 gnu++0x under Linux x86-64,</li>
|
||||
<li>GCC 4.3.4 under Linux x86-64,</li>
|
||||
<li>GCC 4.4.1 under Linux, Linux x86-64 and MinGW,</li>
|
||||
<li>GCC 4.4.1 gnu++0x under Linux x86-64 and MinGW.</li>
|
||||
</ul>
|
||||
Boost.MultiIndex does not work with versions 3.1 and prior of GCC.
|
||||
</p>
|
||||
@@ -155,14 +169,36 @@ release of GNU GCC 4.0.0, so the invariant-checking mode is available from this
|
||||
upgrade.
|
||||
</p>
|
||||
|
||||
<h2><a name="acc_60">HP aC++ A.06.00 for HP-UX</a></h2>
|
||||
<h2><a name="acc_612_ia64">HP aC++ A.06.12 and later for HP-UX IA64</a></h2>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.38. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
Last tested for version A.06.17.
|
||||
</p>
|
||||
|
||||
<h2><a name="acc_380_pa_risc">HP aC++ A.03.80 for HP-UX PA-RISC</a></h2>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.38. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
Last tested for version A.03.85.
|
||||
</p>
|
||||
|
||||
<h2><a name="va_60">IBM VisualAge C++ V6.0 for AIX</a></h2>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.33.1. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
|
||||
refer to the section on
|
||||
@@ -189,44 +225,41 @@ Serialization capabilities are not available as Boost.Serialization is not
|
||||
supported on this platform.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_71_lin">Intel C++ Compiler for Linux 7.1 and later</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compilers from version 7.1 up to 9.0.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_em64t_81_lin">Intel C++ Compiler Extended Memory 64 Technology 8.1
|
||||
for Linux</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_7x_win">Intel C++ Compiler for Windows 32-bit 7.0/7.1</a></h2>
|
||||
<h2><a name="xl_90">IBM XL C/C++ V9.0 for AIX and later</a></h2>
|
||||
|
||||
<p>
|
||||
<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><hr></blockquote>
|
||||
<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>
|
||||
When used on top of MSVC++ 7.0 or prior, argument dependent lookup is
|
||||
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.
|
||||
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.
|
||||
Last tested for version V10.1.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_71_win_stlport_453">
|
||||
Intel C++ Compiler for Windows 32-bit 7.1 + STLport 4.5.3</a></h2>
|
||||
<h2><a name="intel_81_lin">Intel C++ Compiler for Linux 8.1 and later</a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex works for this configuration. The same limitations apply as
|
||||
in Intel C++ 7.1 with its original Dinkumware standard library. STLport 4.6.2 has
|
||||
also been confirmed to work correctly.
|
||||
No problems have been detected with this compiler.
|
||||
Last tested for compiler versions 10.0 to 11.1.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_91_mac">Intel C++ Compiler for Mac OS 9.1 and later</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
Tested from version 10.1 to 11.0.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_80_win">Intel C++ Compiler for Windows 32-bit 8.0 and later</a></h2>
|
||||
@@ -237,12 +270,23 @@ 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.0 have been tested.
|
||||
Other than this, Boost.MultiIndex works without problems.
|
||||
Last tested for compiler version 11.1.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_100_win64">Intel C++ Compiler for Windows 64-bit 10.0 and later</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
Last tested for compiler version 11.1.
|
||||
</p>
|
||||
|
||||
<h2><a name="cw_83">Metrowerks CodeWarrior 8.3</a></h2>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.36. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Predefined key extractors instantiated on a given type do not accept
|
||||
objects of derived types. For instance:
|
||||
@@ -261,19 +305,36 @@ 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.
|
||||
9.5, both under Mac OS and Windows.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a></h2>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.36. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
Beginning with Boost.1.36, Boost.Serialization is no longer supported in this
|
||||
compiler, thus the serialization capabilities cannot be used.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
|
||||
refer to the section on
|
||||
@@ -400,7 +461,7 @@ This problem is a recurrent bug of the compiler, and has been reported in
|
||||
other unrelated libraries, like the
|
||||
<a href="../../../libs/graph/doc/table_of_contents.html">Boost Graph Library</a>,
|
||||
<a href="../../../libs/multi_array/doc/index.html">Boost.MultiArray</a>,
|
||||
<a href="../../../libs/regex/doc/index.html">Boost.Regex</a>,
|
||||
<a href="../../../libs/regex/index.html">Boost.Regex</a>,
|
||||
<a href="http://www.cgal.org/">CGAL</a> and
|
||||
<a href="http://www.mysql.com/downloads/api-mysql++.html">MySQL++</a>.
|
||||
The error is triggered, though not in a systematic manner, by the use
|
||||
@@ -425,7 +486,7 @@ with equivalent operations:
|
||||
<p>
|
||||
The second workaround has not been confirmed by the author, but it is given
|
||||
on the Internet in connection with this error appearing in other libraries.
|
||||
Replace line 84 of <code><xlocnum></code>
|
||||
Replace line 84 of <code><xlocnum></code>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span> <span class=keyword>virtual</span>
|
||||
@@ -469,27 +530,35 @@ The following measures can help alleviate these problems:
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<h3>
|
||||
<a name="msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5
|
||||
+ STLport 4.5.3</a>
|
||||
</h2>
|
||||
+ STLport 4.5.3 and later</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.36. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex works for this configuration. The same limitations apply as
|
||||
in MSVC++ 6.0 with its original Dinkumware standard library. STLport 4.6.2 has
|
||||
also been confirmed to work correctly.
|
||||
in MSVC++ 6.0 with its original Dinkumware standard library. STLport 4.6.2 and
|
||||
5.0.1 has also been confirmed to work correctly.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_70">Microsoft Visual C++ 7.0</a></h2>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.35. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
It is not possible to use the serialization capabilities of Boost.MultiIndex
|
||||
along with the dynamic version of STLport, as some linking errors result.
|
||||
Use instead the static version of STLport. This bug is reportedly fixed in
|
||||
STLport 5.0 (in beta stage as of this writing.)
|
||||
Beginning with Boost.1.36, Boost.Serialization is no longer supported in this
|
||||
compiler, thus the serialization capabilities cannot be used.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_70">Microsoft Visual C++ 7.0</a></h2>
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
|
||||
@@ -584,30 +653,43 @@ objects of derived types. For instance:
|
||||
<span class=identifier>key_extractor</span><span class=special>(</span><span class=identifier>x</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="msvc_70_stlport_501">Microsoft Visual C++ 7.0 + STLport 5.0.1</a></h3>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Last tested in Boost 1.35. The information might be no longer accurate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex works for this configuration. The same issues apply as in
|
||||
MSVC++ 7.0 with its original Dinkumware standard library.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_71">Microsoft Visual C++ 7.1</a></h2>
|
||||
|
||||
<p>
|
||||
Problems have been reported when compiling the library with the <code>/Gm</code>
|
||||
option (Enable Minimal Rebuild.) Seemingly, this is due to an
|
||||
internal defect of the compiler (see for instance
|
||||
<a href="http://lists.boost.org/MailArchives/boost-users/msg05988.php">
|
||||
<a href="http://lists.boost.org/boost-users/2004/02/5987.php">
|
||||
this mention of a similar issue</a> in the Boost Users mailing list.)
|
||||
If <code>/Gm</code> is turned off, Boost.MultiIndex compiles and runs
|
||||
without further problems.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_71_stlport_462">Microsoft Visual C++ 7.1 + STLport 4.6.2</a></h2>
|
||||
<h2><a name="msvc_80">Microsoft Visual C++ 8.0 and later</a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex works for this configuration. The same issues apply as in
|
||||
MSVC++ 7.1 with its original Dinkumware standard library.
|
||||
No problems have been detected with this compiler, both in 32-bit and 64-bit modes.
|
||||
Last tested for compiler versions 8.0 to 10.0.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_80">Microsoft Visual C++ 8.0</a></h2>
|
||||
<h2><a name="sun_10">Sun Studio 10 and later for Solaris</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler. The Beta 2 version of
|
||||
this product was used for the testing.
|
||||
No problems have been detected with this platform. Last tested for compiler version
|
||||
Sun C++ 5.10 (Sun Studio 12 Update 1).
|
||||
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>
|
||||
@@ -625,7 +707,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:
|
||||
@@ -921,7 +1003,7 @@ Consider a typical instantiation of <code>multi_index_container</code>:
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Then, for instance, the type <code>employee_set::nth_type<0>::type</code>
|
||||
Then, for instance, the type <code>employee_set::nth_index<0>::type</code>
|
||||
resolves to the following in GCC:
|
||||
</p>
|
||||
|
||||
@@ -984,7 +1066,7 @@ in the final type by encapsulating it into another, shorter-named construct:
|
||||
<code>employee_set_indices</code> works as a conventional <code>typedef</code>
|
||||
in all respects, save for a detail: its name does not explicitly
|
||||
include the information contained in the <code>indexed_by</code> instantiation.
|
||||
Applying this technique, <code>employee_set::nth_type<0>::type</code>
|
||||
Applying this technique, <code>employee_set::nth_index<0>::type</code>
|
||||
now becomes:
|
||||
</p>
|
||||
|
||||
@@ -1030,9 +1112,9 @@ Performance
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised October 14th 2009</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2009 Joaquín M López Muñ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">
|
||||
|
||||
+36
-12
@@ -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
|
||||
@@ -103,14 +104,20 @@ See <a href="../example/bimap.cpp">source code</a>.
|
||||
<p>
|
||||
This example shows how to construct a bidirectional map with
|
||||
<code>multi_index_container</code>. By a <i>bidirectional map</i> we mean
|
||||
a container of elements of <code>std::pair<const FromType,const ToType></code>
|
||||
such that no two elements exists with the same <code>first</code>
|
||||
<i>or</i> <code>second</code> value (<code>std::map</code> only
|
||||
guarantees uniqueness of the first member). Fast lookup is provided
|
||||
a container of <code>(const FromType,const ToType)</code> pairs
|
||||
such that no two elements exists with the same first
|
||||
<i>or</i> second component (<code>std::map</code> only
|
||||
guarantees uniqueness of the first component). Fast lookup is provided
|
||||
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 May 26th 2009</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2009 Joaquín M López Muñ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">
|
||||
|
||||
+2
-16
@@ -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>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2007 Joaquín M López Muñ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">
|
||||
|
||||
+13
-13
@@ -397,9 +397,9 @@ which is functionally equivalent to <code>std::set<int></code>.
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">80%</td>
|
||||
@@ -457,9 +457,9 @@ which is functionally equivalent to <code>std::list<int></code>.
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">100%</td>
|
||||
@@ -512,9 +512,9 @@ The following instantiation of <code>multi_index_container</code> was tested:
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">70%</td>
|
||||
@@ -568,9 +568,9 @@ The following instantiation of <code>multi_index_container</code> was tested:
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">75%</td>
|
||||
@@ -631,9 +631,9 @@ The following instantiation of <code>multi_index_container</code> was tested:
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">66.7%</td>
|
||||
@@ -685,9 +685,9 @@ The following instantiation of <code>multi_index_container</code> was tested:
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">GCC 3.4.5</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
<th width="33%">MSVC 8.0</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">69.2%</td>
|
||||
@@ -749,7 +749,7 @@ Examples
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised May 9th 2006</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
+128
-42
@@ -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>
|
||||
@@ -218,6 +220,7 @@ do not exactly conform to the requirements for unordered associative containers.
|
||||
<span class=keyword>typedef</span> <span class=identifier>Pred</span> <span class=identifier>key_equal</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>tuple</span><span class=special><</span>
|
||||
<span class=identifier>size_type</span><span class=special>,</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>hasher</span><span class=special>,</span><span class=identifier>key_equal</span><span class=special>></span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>pointer</span> <span class=identifier>pointer</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_pointer</span> <span class=identifier>const_pointer</span><span class=special>;</span>
|
||||
@@ -248,7 +251,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>&</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>&</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><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
@@ -262,7 +270,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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</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>></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><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></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><</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>></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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
@@ -313,6 +325,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>&</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>&</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>
|
||||
|
||||
@@ -370,7 +387,7 @@ following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided),</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag<></code> is assumed),</li>
|
||||
<li><code>KeyFromValue</code> from the index specifier,</li>
|
||||
<li><code>Hash</code> from the index specifier,</li>
|
||||
<li><code>Pred</code> from the index specifier.</li>
|
||||
@@ -434,6 +451,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 iterator_to(const value_type& x);<br>
|
||||
const_iterator iterator_to(const value_type& 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<iterator,bool> insert(const value_type& x);</code>
|
||||
@@ -459,7 +488,7 @@ one element can be causing insertion not to be allowed.<br>
|
||||
<code>iterator insert(iterator position,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
@@ -488,7 +517,7 @@ void insert(InputIterator first,InputIterator last);</code>
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>iterator</span> <span class=identifier>hint</span><span class=special>=</span><span class=identifier>end</span><span class=special>();</span>
|
||||
@@ -504,7 +533,7 @@ index of the <code>multi_index_container</code> to which this index belongs.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Deletes the element pointed to by <code>position</code>.<br>
|
||||
<b>Returns:</b> An iterator pointing to the element immediately following
|
||||
the one that was deleted, or <code>end()</code>
|
||||
@@ -540,7 +569,7 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
to by <code>position</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if, for the value <code>x</code>
|
||||
@@ -551,7 +580,8 @@ the index belongs if, for the value <code>x</code>
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved
|
||||
in all cases.<br>
|
||||
in all cases. If the key of the new value is equivalent to that of the replaced value,
|
||||
the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the replacement took place,
|
||||
<code>false</code> otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(R(n))</code>.<br>
|
||||
@@ -568,7 +598,7 @@ belongs remains in its original state.
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<code>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
iterator of the index.<br>
|
||||
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
|
||||
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
|
||||
@@ -580,7 +610,8 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
|
||||
</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>
|
||||
operation succeeds. If the key of the modified value is equivalent to that of the original
|
||||
value, the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
@@ -589,6 +620,42 @@ user-provided operation (except possibly <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
</blockquote>
|
||||
|
||||
<code>template<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&</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. If the key of the modified value
|
||||
is equivalent to that of the original value, the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
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<typename Modifier> bool modify_key(iterator position,Modifier mod);</code></a>
|
||||
|
||||
@@ -599,27 +666,32 @@ from <code>value_type</code>. <code>Modifier</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<code>key_type&</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.
|
||||
iterator of the index.<br>
|
||||
<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<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&</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>
|
||||
@@ -655,7 +727,7 @@ Consider a pair (<code>Hash</code>, <code>Pred</code>) where
|
||||
and <code>Pred</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
|
||||
<code>Binary Predicate</code></a> inducing an equivalence relation
|
||||
on <code>Key</code>, whit the additional constraint that equivalent
|
||||
on <code>Key</code>, with the additional constraint that equivalent
|
||||
keys have the same hash value.
|
||||
A triplet of types (<code>CompatibleKey</code>, <code>CompatibleHash</code>,
|
||||
<code>CompatiblePred</code>) is said to be a <i>compatible extension</i>
|
||||
@@ -706,7 +778,7 @@ In the context of a compatible extension or a compatible key, the expression
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
(<code>hasher</code>, <code>key_equal</code>).</br>
|
||||
(<code>hasher</code>, <code>key_equal</code>).<br>
|
||||
<b>Effects:</b> Returns a pointer to an element whose key is equivalent to
|
||||
<code>x</code>, or <code>end()</code> if such an element does not exist.<br>
|
||||
<b>Complexity:</b> Average case <code>O(1)</code> (constant), worst case
|
||||
@@ -724,7 +796,7 @@ iterator find(<br>
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleHash</code>,
|
||||
<code>CompatiblePred</code>) is a compatible extension of
|
||||
(<code>hasher</code>, <code>key_equal</code>).</br>
|
||||
(<code>hasher</code>, <code>key_equal</code>).<br>
|
||||
<b>Effects:</b> Returns a pointer to an element whose key is equivalent to
|
||||
<code>x</code>, or <code>end()</code> if such an element does not exist.<br>
|
||||
<b>Complexity:</b> Average case <code>O(1)</code> (constant), worst case
|
||||
@@ -737,7 +809,7 @@ size_type count(const CompatibleKey& x)const;
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
(<code>hasher</code>, <code>key_equal</code>).</br>
|
||||
(<code>hasher</code>, <code>key_equal</code>).<br>
|
||||
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Complexity:</b> Average case <code>O(count(x))</code>, worst case
|
||||
<code>O(n)</code>.<br>
|
||||
@@ -754,7 +826,7 @@ size_type count(<br>
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleHash</code>,
|
||||
<code>CompatiblePred</code>) is a compatible extension of
|
||||
(<code>hasher</code>, <code>key_equal</code>).</br>
|
||||
(<code>hasher</code>, <code>key_equal</code>).<br>
|
||||
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Complexity:</b> Average case <code>O(count(x,hash,eq))</code>, worst case
|
||||
<code>O(n)</code>.<br>
|
||||
@@ -766,9 +838,10 @@ std::pair<iterator,iterator> equal_range(const CompatibleKey& x)const;
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
(<code>hasher</code>, <code>key_equal</code>).</br>
|
||||
(<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>
|
||||
@@ -776,7 +849,7 @@ to <code>x</code> (and only those).<br>
|
||||
<code>template<<br>
|
||||
typename CompatibleKey,typename CompatibleHash, typename CompatiblePred<br>
|
||||
><br>
|
||||
std::pair<iterator,iterator> equal_range(</br>
|
||||
std::pair<iterator,iterator> equal_range(<br>
|
||||
const CompatibleKey& x,<br>
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const;
|
||||
</code>
|
||||
@@ -784,13 +857,26 @@ std::pair<iterator,iterator> equal_range(</br>
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleHash</code>,
|
||||
<code>CompatiblePred</code>) is a compatible extension of
|
||||
(<code>hasher</code>, <code>key_equal</code>).</br>
|
||||
(<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 local_iterator_to(const value_type& x);<br>
|
||||
const_local_iterator local_iterator_to(const value_type& 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>
|
||||
|
||||
@@ -804,7 +890,7 @@ load factor, and <code>bucket_count()>=n</code>.<br>
|
||||
elements contained is preserved.<br>
|
||||
<b>Complexity:</b> Average case <code>O(size())</code>, worst case
|
||||
<code>O(size(n)<sup>2</sup>)</code>.<br>
|
||||
<b>Exeption safety:</b> Strong.
|
||||
<b>Exception safety:</b> Strong.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="serialization">Serialization</a></h4>
|
||||
@@ -895,9 +981,9 @@ Sequenced indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised July 21st 2009</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2009 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2007 Joaquín M López Muñ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">
|
||||
|
||||
@@ -279,7 +279,10 @@ sequence of tags to be assigned to an index in instantiation time.
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>tag</span><span class=special>;</span>
|
||||
<span class=keyword>struct</span> <span class=identifier>tag</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
@@ -287,6 +290,13 @@ Elements of <code>tag</code> can be any type, though the user is expected
|
||||
to provide classes with mnemonic names. Duplicate elements are not allowed.
|
||||
The maximum number of elements of a <code>tag</code> instantiation is
|
||||
implementation defined.
|
||||
The nested
|
||||
<code>type</code> is a model of
|
||||
<a href="../../../../libs/mpl/doc/refmanual/random-access-sequence.html">
|
||||
<code>MPL Random Access Sequence</code></a> and
|
||||
<a href="../../../../libs/mpl/doc/refmanual/extensible-sequence.html">
|
||||
<code>MPL Extensible Sequence</code></a> containing the types <code>T0</code>, ... ,
|
||||
<code>Tn</code> in the same order as specified.
|
||||
</p>
|
||||
|
||||
<h2><a name="index_catalog">Indices provided by Boost.MultiIndex</a></h2>
|
||||
@@ -373,9 +383,9 @@ Ordered indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised July 21st 2009</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2009 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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&</code> or
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>member</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>mem_fun</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>global_fun</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>composite_key</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
@@ -215,7 +223,7 @@ that acts as a do-nothing identity functor.
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Type</span> <span class=identifier>result_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// only provided if const ChainedPtr is not convertible to const Type</span>
|
||||
<span class=comment>// only provided if const ChainedPtr& is not convertible to const Type&</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>></span> <span class=identifier>Type</span><span class=special>&</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -324,7 +332,7 @@ aimed at accessing a given member of a class.
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Type</span> <span class=identifier>result_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// only provided if const ChainedPtr is not convertible to const Class</span>
|
||||
<span class=comment>// only provided if const ChainedPtr& is not convertible to const Class&</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>></span> <span class=identifier>Type</span><span class=special>&</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -416,7 +424,7 @@ luckily enough, most compilers accept it nevertheless, so
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Type</span> <span class=identifier>result_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// only provided if const ChainedPtr is not convertible to const Class</span>
|
||||
<span class=comment>// only provided if const ChainedPtr& is not convertible to const Class&</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>></span> <span class=identifier>Type</span><span class=special>&</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -521,7 +529,7 @@ returning as key the result of invoking a given constant member function of a cl
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special><</span><span class=identifier>Type</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// only provided if const ChainedPtr is not convertible to const Class</span>
|
||||
<span class=comment>// only provided if const ChainedPtr& is not convertible to const Class&</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>></span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -593,7 +601,7 @@ returning as key the result of invoking a given member function of a class.
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special><</span><span class=identifier>Type</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// only provided if ChainedPtr is not convertible to Class</span>
|
||||
<span class=comment>// only provided if ChainedPtr& is not convertible to Class&</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>></span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Class</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -656,7 +664,7 @@ these pointers as an additional template parameter.
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special><</span><span class=identifier>Type</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// only provided if const ChainedPtr is not convertible to const Class</span>
|
||||
<span class=comment>// only provided if const ChainedPtr& is not convertible to const Class&</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>></span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -700,7 +708,7 @@ used for extraction.
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special><</span><span class=identifier>Type</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// only provided if ChainedPtr is not convertible to Class</span>
|
||||
<span class=comment>// only provided if ChainedPtr& is not convertible to Class&</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>></span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Class</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -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><</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>)></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><</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>)></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><</span><span class=identifier>Type</span><span class=special>>::</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& is not convertible to Value;
|
||||
// - if Value is a reference to a non-const type, only provided
|
||||
// when ChainedPtr& is not convertible to Value;
|
||||
// - else, only provided when const ChainedPtr& is not
|
||||
// convertible to const Value&.</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>&</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>&</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><</span><span class=keyword>const</span> <span class=identifier>Value</span><span class=special>>&</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><</span>
|
||||
<span class=identifier>remove_reference</span><span class=special><</span><span class=identifier>Value</span><span class=special>>::</span><span class=identifier>type</span><span class=special>>&</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><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>remove_const</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special><</span><span class=identifier>Value</span><span class=special>>::</span><span class=identifier>type</span><span class=special>>::</span><span class=identifier>type</span><span class=special>>&</span> <span class=identifier>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&)</code> (<code>Value</code> is <code>const BaseType&</code>),</li>
|
||||
<li><code>Type f(BaseType&)</code> (<code>Value</code> is <code>BaseType&</code>).</li>
|
||||
</ul>
|
||||
<code>global_fun<Type,Value,PtrToFunction></code> is a model of:
|
||||
<ul>
|
||||
<li><a href="#key_extractors"><code>Key Extractor</code></a>
|
||||
from <code>reference_wrapper<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&</code>,
|
||||
<code>global_fun<Type,Value,PtrToFunction></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<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<typename ChainedPtr> Type operator()(const ChainedPtr& 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& x)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Returns:</b> <code>PtrToFunction(x)</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>Type operator()(const reference_wrapper<const Value>& x)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Returns:</b> <code>PtrToFunction(x.get())</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>
|
||||
Type operator()(<br>
|
||||
const reference_wrapper<remove_reference<Value>::type>& x)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Returns:</b> <code>PtrToFunction(x.get())</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>Type operator()(<br>
|
||||
const reference_wrapper<<br>
|
||||
typename remove_const<<br>
|
||||
typename remove_reference<Value>::type>::type>& 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 =,<,!=,>,>=,<=</span>
|
||||
<span class=comment>// <b>OP</b> is any of ==,<,!=,>,>=,<=</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</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>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
|
||||
@@ -886,7 +1035,7 @@ at compile time. The returned object is of type
|
||||
<span class=keyword>const</span> <span class=identifier>key_extractor_tuple</span><span class=special>&</span> <span class=identifier>key_extractors</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>key_extractor_tuple</span><span class=special>&</span> <span class=identifier>key_extractors</span><span class=special>()</span>
|
||||
|
||||
<span class=comment>// only provided if const ChainedPtr is not convertible to const value_type</span>
|
||||
<span class=comment>// only provided if const ChainedPtr& is not convertible to const value_type&</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>></span>
|
||||
<span class=identifier>result_type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><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 =,<,!=,>,>=,<=</span>
|
||||
<span class=comment>// <b>OP</b> is any of ==,<,!=,>,>=,<=</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</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>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
|
||||
@@ -1079,7 +1228,7 @@ bool operator==(<br>
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>length(x)==length(y)</code>. The expression
|
||||
<code>x<sub>i</sub>==y<sub>i</sub></code> is valid for all <code>i</code>
|
||||
in <code>[0,length(x))</code>.</br>
|
||||
in <code>[0,length(x))</code>.<br>
|
||||
<b>Returns:</b> <code>true</code> if and only if
|
||||
<blockquote>
|
||||
<code>x<sub>i</sub>==y<sub>i</sub></code> for all <code>i</code>
|
||||
@@ -1109,7 +1258,7 @@ bool operator<(<br>
|
||||
<b>Requires:</b> The expressions
|
||||
<code>x<sub>i</sub><y<sub>i</sub></code> and
|
||||
<code>y<sub>i</sub><x<sub>i</sub></code> are valid for all <code>i</code>
|
||||
in <code>[0,min(length(x),length(y)))</code>.</br>
|
||||
in <code>[0,min(length(x),length(y)))</code>.<br>
|
||||
<b>Returns:</b> <code>true</code> if and only if there exists some
|
||||
<code>j</code> in the range <code>[0,min(length(x),length(y)))</code>
|
||||
such that
|
||||
@@ -1145,7 +1294,7 @@ bool operator <b><i>OP</i></b>(<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> The expressions given below are valid (for the particular
|
||||
<code><b><i>OP</i></b></code> considered.)</br>
|
||||
<code><b><i>OP</i></b></code> considered.)<br>
|
||||
<b>Returns:</b> <code>true</code> if and only if
|
||||
<blockquote>
|
||||
<code>!(x==y)</code> (<code><b><i>OP</i></b></code> is <code>!=</code>),<br>
|
||||
@@ -1286,7 +1435,7 @@ bool operator()(<br>
|
||||
<b>Requires:</b> <code>length(x)==length(y)</code>. The expressions
|
||||
<code>key_eqs().get<i>()(x<sub>i</sub>,y<sub>i</sub>)</code> and
|
||||
<code>key_eqs().get<i>()(y<sub>i</sub>,x<sub>i</sub>)</code>
|
||||
are valid for all <code>i</code> in <code>[0,length(x))</code>.</br>
|
||||
are valid for all <code>i</code> in <code>[0,length(x))</code>.<br>
|
||||
<b>Returns:</b> <code>true</code> if and only
|
||||
<blockquote>
|
||||
<code>key_eqs().get<i>()(x<sub>i</sub>,y<sub>i</sub>)</code>
|
||||
@@ -1534,7 +1683,7 @@ bool operator()(<br>
|
||||
<code>key_comps().get<i>()(x<sub>i</sub>,y<sub>i</sub>)</code> and
|
||||
<code>key_comps().get<i>()(y<sub>i</sub>,x<sub>i</sub>)</code>
|
||||
are valid for all <code>i</code>
|
||||
in <code>[0,min(length(x),length(y)))</code>.</br>
|
||||
in <code>[0,min(length(x),length(y)))</code>.<br>
|
||||
<b>Returns:</b> <code>true</code> if and only if there exists some
|
||||
<code>j</code> in the range <code>[0,min(length(x),length(y)))</code>
|
||||
such that
|
||||
@@ -2072,9 +2221,22 @@ is lexicographical. Also, the following types are
|
||||
<code>composite_key_result<composite_key<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 February 6th 2006</p>
|
||||
<p>Revised June 25th 2008</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2008 Joaquín M López Muñ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">
|
||||
|
||||
@@ -99,10 +99,15 @@ synopsis</a>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
|
||||
|
||||
<span class=comment>// multi_index_container global functions for index retrieval:</span>
|
||||
|
||||
@@ -144,9 +149,9 @@ synopsis</a>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
@@ -155,9 +160,9 @@ synopsis</a>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
@@ -166,9 +171,9 @@ synopsis</a>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
@@ -177,9 +182,9 @@ synopsis</a>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
@@ -265,19 +270,26 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span><span class=keyword>typedef</span> <b><span class=identifier>implementation</span> <span class=identifier>defined</span></b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
|
||||
<span class=comment>// construct/copy/destroy:</span>
|
||||
|
||||
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(
|
||||
</span><span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
|
||||
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
|
||||
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>,</span>
|
||||
@@ -303,13 +315,13 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=comment>// projection of iterators</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=comment>// multi_index_container associated global class templates:</span>
|
||||
@@ -324,22 +336,26 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>nth_index_const_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=comment><b>// deprecated</b></span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index_const_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
@@ -396,56 +412,56 @@ operators and functions associated with the index (vg. comparison and
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>const_iterator</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=keyword>template</span> <span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// comparison:</span>
|
||||
@@ -493,7 +509,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 +520,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<T>::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
|
||||
@@ -589,7 +625,7 @@ the same order as they were specified.<br>
|
||||
|
||||
<blockquote>
|
||||
<code>index<Tag>::type</code> yields the type of the index which
|
||||
has <code>Tag</code> as an associated <a href="indices.html#tags">tag type</a>.</br>
|
||||
has <code>Tag</code> as an associated <a href="indices.html#tags">tag type</a>.<br>
|
||||
<b>Requires:</b> Some index of the <code>multi_index_container</code> has <code>Tag</code>
|
||||
as an associated tag type.
|
||||
</blockquote>
|
||||
@@ -599,6 +635,7 @@ as an associated tag type.
|
||||
<blockquote>
|
||||
<code>nth_index_iterator<N>::type</code> is equivalent to
|
||||
<code>nth_index<N>::type::iterator</code>.<br>
|
||||
<b>Note:</b> The use of <code>nth_index_iterator</code> is deprecated.
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N> struct nth_index_const_iterator</code>
|
||||
@@ -606,6 +643,7 @@ as an associated tag type.
|
||||
<blockquote>
|
||||
<code>nth_index_const_iterator<N>::type</code> is equivalent to
|
||||
<code>nth_index<N>::type::const_iterator</code>.<br>
|
||||
<b>Note:</b> The use of <code>nth_index_const_iterator</code> is deprecated.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> struct index_iterator</code>
|
||||
@@ -613,6 +651,7 @@ as an associated tag type.
|
||||
<blockquote>
|
||||
<code>index_iterator<Tag>::type</code> is equivalent to
|
||||
<code>index<Tag>::type::iterator</code>.<br>
|
||||
<b>Note:</b> The use of <code>index_iterator</code> is deprecated.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> struct index_const_iterator</code>
|
||||
@@ -620,12 +659,13 @@ as an associated tag type.
|
||||
<blockquote>
|
||||
<code>index_const_iterator<Tag>::type</code> is equivalent to
|
||||
<code>index<Tag>::type::const_iterator</code>.<br>
|
||||
<b>Note:</b> The use of <code>index_const_iterator</code> is deprecated.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<code>explicit multi_index_container(<br>
|
||||
const ctor_args_list& comp=ctor_args_list(),<br>
|
||||
const ctor_args_list& args_list=ctor_args_list(),<br>
|
||||
const allocator_type& al=allocator_type());</code>
|
||||
|
||||
<blockquote>
|
||||
@@ -634,6 +674,14 @@ specified argument list and allocator.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<code>explicit multi_index_container(const allocator_type& al);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Constructs an empty <code>multi_index_container</code> using the
|
||||
specified allocator and the default value of <code>ctor_args_list</code>.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename InputIterator><br>
|
||||
multi_index_container(<br>
|
||||
InputIterator first,InputIterator last,<br>
|
||||
@@ -645,7 +693,7 @@ multi_index_container(<br>
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>Value</code> or a type convertible to <code>Value</code>.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b> Constructs and empty <code>multi_index_container</code> using the
|
||||
specified argument list and allocator and fills it with
|
||||
the elements in the range [<code>first</code>,<code>last</code>).
|
||||
@@ -758,21 +806,21 @@ are <i>equivalent</i> if:
|
||||
</p>
|
||||
|
||||
<code>template<int N,typename IteratorType><br>
|
||||
typename nth_index_iterator<N>::type project(IteratorType it);</code>
|
||||
typename nth_index<N>::type::iterator project(IteratorType it);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>. <code>IteratorType</code>
|
||||
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
iterator of some index of <code>*this</code> (i.e. does not refer to some
|
||||
other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>nth_index_iterator<N>::type</code> iterator
|
||||
<b>Effects:</b> Returns an <code>nth_index<N>::type::iterator</code>
|
||||
equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N,typename IteratorType><br>
|
||||
typename nth_index_const_iterator<N>::type project(IteratorType it)const;</code>
|
||||
typename nth_index<N>::type::const_iterator project(IteratorType it)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>. <code>IteratorType</code>
|
||||
@@ -780,38 +828,38 @@ belongs to <code>const_iterator_type_list</code> or
|
||||
<code>iterator_type_list</code>. <code>it</code> is a
|
||||
valid (constant or non-constant) iterator of some index of <code>*this</code>
|
||||
(i.e. does not refer to some other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>nth_index_const_iterator<N>::type</code>
|
||||
iterator equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag,typename IteratorType><br>
|
||||
typename index_iterator<Tag>::type project(IteratorType it);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that
|
||||
<code>index_iterator<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
iterator of some index of <code>*this</code> (i.e. does not refer to some
|
||||
other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>index_iterator<Tag>::type</code> iterator
|
||||
<b>Effects:</b> Returns an <code>nth_index<N>::type::const_iterator</code>
|
||||
equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag,typename IteratorType><br>
|
||||
typename index_const_iterator<Tag>::type project(IteratorType it)const;</code>
|
||||
typename index<Tag>::type::iterator project(IteratorType it);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that
|
||||
<code>index_const_iterator<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
<code>index<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
iterator of some index of <code>*this</code> (i.e. does not refer to some
|
||||
other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>index<Tag>::type::iterator</code>
|
||||
equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag,typename IteratorType><br>
|
||||
typename index<Tag>::type::const_iterator project(IteratorType it)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that
|
||||
<code>index<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
belongs to <code>const_iterator_type_list</code> or
|
||||
<code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
(constant or non-constant) iterator of some index of <code>*this</code>
|
||||
(i.e. does not refer to some other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>index_const_iterator<Tag>::type</code>
|
||||
<b>Effects:</b> Returns an <code>index<Tag>::type::const_iterator</code>
|
||||
iterator equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
@@ -882,9 +930,9 @@ Index reference
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised November 6th 2008</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2008 Joaquín M López Muñ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">
|
||||
|
||||
+117
-47
@@ -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>
|
||||
|
||||
@@ -222,6 +223,7 @@ requirements for these types of containers.
|
||||
<span class=keyword>typedef</span> <span class=identifier>Compare</span> <span class=identifier>key_compare</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>value_compare</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>tuple</span><span class=special><</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>></span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
|
||||
@@ -252,7 +254,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>&</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>&</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 +281,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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</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>></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><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></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><</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>></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>&</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,8 +408,8 @@ 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>
|
||||
<li>deletion: <code>d(n)=1</code> (constant),</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>
|
||||
<li>modifying: <code>m(n)=1</code> (constant) if the element position does not
|
||||
@@ -414,7 +427,7 @@ following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided),</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag<></code> is assumed),</li>
|
||||
<li><code>KeyFromValue</code> from the index specifier,</li>
|
||||
<li><code>Compare</code> from the index specifier.</li>
|
||||
</ul>
|
||||
@@ -448,6 +461,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 iterator_to(const value_type& x);<br>
|
||||
const_iterator iterator_to(const value_type& 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<iterator,bool> insert(const value_type& x);</code>
|
||||
@@ -473,7 +498,7 @@ one element can be causing insertion not to be allowed.<br>
|
||||
<code>iterator insert(iterator position,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
@@ -483,7 +508,8 @@ the index belongs if
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<code>position</code> is used as a hint to improve the efficiency of the
|
||||
operation.<br>
|
||||
operation. If succesful, insertion happens as close as possible to the
|
||||
location just prior to <code>position</code>.<br>
|
||||
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
|
||||
element. Otherwise, an iterator to an element that caused the insertion to be
|
||||
banned. Note that more than one element can be causing insertion not to be
|
||||
@@ -502,7 +528,7 @@ void insert(InputIterator first,InputIterator last);</code>
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>iterator</span> <span class=identifier>hint</span><span class=special>=</span><span class=identifier>end</span><span class=special>();</span>
|
||||
@@ -518,7 +544,7 @@ index of the <code>multi_index_container</code> to which this index belongs.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Deletes the element pointed to by <code>position</code>.<br>
|
||||
<b>Returns:</b> An iterator pointing to the element immediately following
|
||||
the one that was deleted, or <code>end()</code>
|
||||
@@ -553,7 +579,7 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
to by <code>position</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if, for the value <code>x</code>
|
||||
@@ -564,7 +590,8 @@ the index belongs if, for the value <code>x</code>
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved
|
||||
in all cases.<br>
|
||||
in all cases. If the key of the new value is equivalent to that of the
|
||||
replaced value, the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the replacement took place,
|
||||
<code>false</code> otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(R(n))</code>.<br>
|
||||
@@ -581,7 +608,7 @@ belongs remains in its original state.
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<code>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
iterator of the index.<br>
|
||||
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
|
||||
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
|
||||
@@ -593,7 +620,8 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
|
||||
</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>
|
||||
operation succeeds. If the key of the modified value is equivalent to that of the
|
||||
original value, the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
@@ -602,6 +630,43 @@ user-provided operation (except possibly <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
</blockquote>
|
||||
|
||||
<code>template<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&</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.
|
||||
If the key of the modified value is equivalent to that of the
|
||||
original value, the position of the element does not change.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
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<typename Modifier> bool modify_key(iterator position,Modifier mod);</code></a>
|
||||
|
||||
@@ -612,27 +677,32 @@ from <code>value_type</code>. <code>Modifier</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<code>key_type&</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.
|
||||
iterator of the index.<br>
|
||||
<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<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&</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>
|
||||
@@ -715,7 +785,7 @@ interpretations.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns a pointer to an element whose key is equivalent to
|
||||
<code>x</code>, or <code>end()</code> if such an element does not exist.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
@@ -727,7 +797,7 @@ iterator find(const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns a pointer to an element whose key is equivalent to
|
||||
<code>x</code>, or <code>end()</code> if such an element does not exist.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
@@ -739,7 +809,7 @@ count(const CompatibleKey& x)const;
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n) + count(x))</code>.<br>
|
||||
</blockquote>
|
||||
@@ -750,7 +820,7 @@ size_type count(const CompatibleKey& x,const CompatibleCompare& comp)con
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns the number of elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n) + count(x,comp))</code>.<br>
|
||||
</blockquote>
|
||||
@@ -761,7 +831,7 @@ iterator lower_bound(const CompatibleKey& x)const;
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns an iterator pointing to the first element with
|
||||
key not less than <code>x</code>, or <code>end()</code> if such an element does
|
||||
not exist.<br>
|
||||
@@ -774,7 +844,7 @@ iterator lower_bound(const CompatibleKey& x,const CompatibleCompare& com
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns an iterator pointing to the first element with
|
||||
key not less than <code>x</code>, or <code>end()</code> if such an element does
|
||||
not exist.<br>
|
||||
@@ -787,7 +857,7 @@ iterator upper_bound(const CompatibleKey& x)const;
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns an iterator pointing to the first element with
|
||||
key greater than <code>x</code>, or <code>end()</code> if such an element does
|
||||
not exist.<br>
|
||||
@@ -800,7 +870,7 @@ iterator upper_bound(const CompatibleKey& x,const CompatibleCompare& com
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Returns an iterator pointing to the first element with
|
||||
key greater than <code>x</code>, or <code>end()</code> if such an element does
|
||||
not exist.<br>
|
||||
@@ -814,19 +884,19 @@ std::pair<iterator,iterator> equal_range(<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to <code>make_pair(lower_bound(x),upper_bound(x))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
std::pair<iterator,iterator> equal_range(</br>
|
||||
std::pair<iterator,iterator> equal_range(<br>
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
is a compatible extension of <code>key_compare</code>.<br>
|
||||
<b>Effects:</b> Equivalent to
|
||||
<code>make_pair(lower_bound(x,comp),upper_bound(x,comp))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
@@ -878,7 +948,7 @@ std::pair<iterator,iterator> range(<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>LowerBounder</code> and <code>UpperBounder</code> are
|
||||
a lower and upper bounder of <code>key_compare</code>, respectively.</br>
|
||||
a lower and upper bounder of <code>key_compare</code>, respectively.<br>
|
||||
<b>Effects:</b> Returns a pair of iterators pointing to the beginning and one
|
||||
past the end of the subsequence of elements satisfying <code>lower</code> and
|
||||
<code>upper</code> simultaneously. If no such elements exist, the iterators
|
||||
@@ -954,9 +1024,9 @@ Hashed indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised December 21st 2009</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2009 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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>
|
||||
@@ -204,7 +205,8 @@ to the requirements for these types of containers.
|
||||
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>node_type</span><span class=special>::</span><span class=identifier>value_type</span> <span class=identifier>value_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>allocator_type</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>allocator_type</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>iterator</span><span class=special>;</span>
|
||||
@@ -238,6 +240,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>&</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>&</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 +282,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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</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>></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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
@@ -396,7 +407,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>
|
||||
@@ -408,7 +419,7 @@ index specifier. Instantiations are dependent on the following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided).</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag<></code> is assumed).</li>
|
||||
</ul>
|
||||
<code>TagList</code> must be an instantiation of
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
@@ -444,7 +455,7 @@ void assign(InputIterator first,InputIterator last);</code>
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>clear</span><span class=special>();</span>
|
||||
@@ -462,6 +473,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 iterator_to(const value_type& x);<br>
|
||||
const_iterator iterator_to(const value_type& 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>
|
||||
@@ -533,7 +556,7 @@ Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<code>std::pair<iterator,bool> insert(iterator position,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion
|
||||
is allowed by all other indices of the <code>multi_index_container</code>.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
@@ -548,7 +571,7 @@ Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<code>void insert(iterator position,size_type m,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>i</span><span class=special>=</span><span class=number>0</span><span class=special>;</span><span class=identifier>i</span><span class=special><</span><span class=identifier>m</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span>
|
||||
@@ -567,7 +590,7 @@ void insert(iterator position,InputIterator first,InputIterator last);</code>
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
|
||||
@@ -582,7 +605,7 @@ where <code>m</code> is the number of elements in
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Deletes the element pointed to by <code>position</code>.<br>
|
||||
<b>Returns:</b> An iterator pointing to the element immediately following
|
||||
the one that was deleted, or <code>end()</code>
|
||||
@@ -607,7 +630,7 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
to by <code>position</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if replacing is allowed by all other indices of the
|
||||
@@ -630,12 +653,12 @@ belongs remains in its original state.
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<code>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
iterator of the index.<br>
|
||||
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
|
||||
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 +670,37 @@ user-provided operation (except possibly <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
</blockquote>
|
||||
|
||||
<code>template<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&</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>
|
||||
@@ -660,7 +714,7 @@ of sequenced indices, but the associated complexity bounds differ in general.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>&x!=this</code>.</br>
|
||||
<code>&x!=this</code>.<br>
|
||||
<b>Effects:</b> Inserts the contents of <code>x</code> before <code>position</code>,
|
||||
in the same order as they were in <code>x</code>. Those elements succesfully
|
||||
inserted are erased from <code>x</code>.<br>
|
||||
@@ -946,9 +1000,9 @@ Key extraction
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised July 21st 2009</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2009 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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>
|
||||
@@ -195,7 +196,8 @@ types of containers.
|
||||
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>node_type</span><span class=special>::</span><span class=identifier>value_type</span> <span class=identifier>value_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>allocator_type</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>allocator_type</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>iterator</span><span class=special>;</span>
|
||||
@@ -229,6 +231,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>&</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>&</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 +269,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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</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>></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>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
@@ -382,7 +393,7 @@ index specifier. Instantiations are dependent on the following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided).</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided, otherwise <code>tag<></code> is assumed).</li>
|
||||
</ul>
|
||||
<code>TagList</code> must be an instantiation of
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
@@ -418,7 +429,7 @@ void assign(InputIterator first,InputIterator last);</code>
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>clear</span><span class=special>();</span>
|
||||
@@ -436,6 +447,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 iterator_to(const value_type& x);<br>
|
||||
const_iterator iterator_to(const value_type& 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& x=value_type());</code>
|
||||
@@ -487,7 +510,7 @@ Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<code>std::pair<iterator,bool> insert(iterator position,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion
|
||||
is allowed by all other indices of the <code>multi_index_container</code>.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
@@ -502,7 +525,7 @@ Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<code>void insert(iterator position,size_type n,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>i</span><span class=special>=</span><span class=number>0</span><span class=special>;</span><span class=identifier>i</span><span class=special><</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span>
|
||||
@@ -520,7 +543,7 @@ void insert(iterator position,InputIterator first,InputIterator last);</code>
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<code>last</code> is reachable from <code>first</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
|
||||
@@ -534,7 +557,7 @@ number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Deletes the element pointed to by <code>position</code>.<br>
|
||||
<b>Returns:</b> An iterator pointing to the element immediately following
|
||||
the one that was deleted, or <code>end()</code>
|
||||
@@ -559,7 +582,7 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
of the index.<br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
to by <code>position</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if replacing is allowed by all other indices of the
|
||||
@@ -582,12 +605,12 @@ belongs remains in its original state.
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<code>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
iterator of the index.<br>
|
||||
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
|
||||
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 +622,37 @@ user-provided operation (except possibly <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
</blockquote>
|
||||
|
||||
<code>template<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&</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>
|
||||
@@ -614,7 +668,7 @@ same <code>multi_index_container</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>&x!=this</code>.</br>
|
||||
<code>&x!=this</code>.<br>
|
||||
<b>Effects:</b> Inserts the contents of <code>x</code> before <code>position</code>,
|
||||
in the same order as they were in <code>x</code>. Those elements succesfully
|
||||
inserted are erased from <code>x</code>.<br>
|
||||
@@ -901,9 +955,9 @@ Random access indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised July 21st 2009</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2009 Joaquín M López Muñ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">
|
||||
|
||||
+221
-2
@@ -31,11 +31,230 @@ Acknowledgements
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#boost_1_49">Boost 1.49 release</a></li>
|
||||
<li><a href="#boost_1_48">Boost 1.48 release</a></li>
|
||||
<li><a href="#boost_1_47">Boost 1.47 release</a></li>
|
||||
<li><a href="#boost_1_44">Boost 1.44 release</a></li>
|
||||
<li><a href="#boost_1_43">Boost 1.43 release</a></li>
|
||||
<li><a href="#boost_1_42">Boost 1.42 release</a></li>
|
||||
<li><a href="#boost_1_41">Boost 1.41 release</a></li>
|
||||
<li><a href="#boost_1_38">Boost 1.38 release</a></li>
|
||||
<li><a href="#boost_1_37">Boost 1.37 release</a></li>
|
||||
<li><a href="#boost_1_36">Boost 1.36 release</a></li>
|
||||
<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_49">Boost 1.49 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Suppressed a potential narrow conversion warning described in
|
||||
ticket <a href="https://svn.boost.org/trac/boost/ticket/3365">#3365</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_48">Boost 1.48 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed a compatibility problem with
|
||||
<a href="../../../doc/html/foreach.html">Boost.Foreach</a>
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/5741">#5741</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_47">Boost 1.47 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed an ADL problem in
|
||||
<a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>
|
||||
related with <a href="../../../doc/html/ref.html">Boost.Ref</a>.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_44">Boost 1.44 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
Fixed a bug preventing the use of <code>modify_key</code> with
|
||||
rollback in <a href="reference/ord_indices.html#modify_key">ordered</a> and
|
||||
<a href="reference/hash_indices.html#modify_key">hashed</a> indices when
|
||||
<code>Modifier</code> and <code>Rollback</code> are different types
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/4130">#4130</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_43">Boost 1.43 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="../../serialization/doc/serialization.html#constructors">Serialization
|
||||
of non default constructible values</a> is now properly supported
|
||||
through user-provided facilities <code>save_construct_data</code> and
|
||||
<code>load_construct_data</code>.
|
||||
<code>multi_index_container</code> serialization
|
||||
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
|
||||
bumped from 1 to 2.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_42">Boost 1.42 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_41">Boost 1.41 release</a></h2>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Serialization now uses the portable
|
||||
<a href="../../serialization/doc/wrappers.html#collection_size_type"><code>collection_size_type</code></a>
|
||||
type instead of the original <code>std::size_t</code> (ticket
|
||||
<a href="https://svn.boost.org/trac/boost/ticket/3365">#3365</a>).
|
||||
<code>multi_index_container</code> serialization
|
||||
<a href="../../serialization/doc/tutorial.html#versioning">class version</a> has been
|
||||
bumped from 0 to 1.
|
||||
</li>
|
||||
<li>Fixed a concurrency bug in the implementation of
|
||||
<a href="tutorial/debug.html#safe_mode">safe mode</a>
|
||||
(ticket <a href="https://svn.boost.org/trac/boost/ticket/3462">#3462</a>).
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_38">Boost 1.38 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>These constructs are deprecated:
|
||||
<ul>
|
||||
<li><code>nth_index_iterator<MultiIndexContainer,N>::type</code>,</li>
|
||||
<li><code>multi_index_container<...>::nth_index_iterator<N>::type</code>,</li>
|
||||
<li><code>nth_index_const_iterator<MultiIndexContainer,N>::type</code>,</li>
|
||||
<li><code>multi_index_container<...>::nth_index_const_iterator<N>::type</code>,</li>
|
||||
<li><code>index_iterator<MultiIndexContainer,Tag>::type</code>,</li>
|
||||
<li><code>multi_index_container<...>::index_iterator<Tag>::type</code>,</li>
|
||||
<li><code>index_const_iterator<MultiIndexContainer,Tag>::type</code>,</li>
|
||||
<li><code>multi_index_container<...>::index_const_iterator<Tag>::type</code>.</li>
|
||||
</ul>
|
||||
Use the following instead:
|
||||
<ul>
|
||||
<li><code>nth_index<MultiIndexContainer,N>::type::iterator</code>,</li>
|
||||
<li><code>multi_index_container<...>::nth_index<N>::type::iterator</code>,</li>
|
||||
<li><code>nth_index<MultiIndexContainer,N>::type::const_iterator</code>,</li>
|
||||
<li><code>multi_index_container<...>::nth_index<N>::type::const_iterator</code>,</li>
|
||||
<li><code>index<MultiIndexContainer,Tag>::type::iterator</code>,</li>
|
||||
<li><code>multi_index_container<...>::index<Tag>::type::iterator</code>,</li>
|
||||
<li><code>index<MultiIndexContainer,Tag>::type::const_iterator</code>,</li>
|
||||
<li><code>multi_index_container<...>::index<Tag>::type::const_iterator</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_37">Boost 1.37 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_36">Boost 1.36 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li><a name="stable_update">On prior versions of the library, the <a href="tutorial/indices.html#hash_updating">update
|
||||
member functions</a> of hashed indices could alter the position of an element even if the
|
||||
associated key did not change with the update. This is legal but probably unexpected behavior.
|
||||
The functions have been rewritten to provide the additional guarantee that elements with
|
||||
unmodified key will not change position in hashed indices, just as always was the case with
|
||||
ordered indices. These guarantees are now documented in the reference.</a></li>
|
||||
<li>Added the constructor <code>multi_index_container::multi_index_container(const allocator_type&)</code>
|
||||
to mimic the equivalent interface in STL sequence containers.
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<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><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span><span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span>
|
||||
<span class=special>></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><</span><span class=keyword>int</span><span class=special>></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<sequenced_container::size_type>(10),100);
|
||||
// that is, "10" and "100" 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 +359,9 @@ Acknowledgements
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised November 24th 2011</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2011 Joaquín M López Muñ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">
|
||||
|
||||
+4
-3
@@ -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>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2007 Joaquín M López Muñ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">
|
||||
|
||||
+69
-34
@@ -153,7 +153,8 @@ thus can be solved with Boost.MultiIndex as follows:
|
||||
|
||||
<p>
|
||||
Instead of a single comparison predicate type, as it happens for STL associative
|
||||
containers, <code>multi_index_container</code> is passed a <i>typelist</i> of index
|
||||
containers, <code>multi_index_container</code> is passed a
|
||||
<a href="../reference/multi_index_container.html#multi_index_container">list</a> of index
|
||||
specifications (<code>indexed_by</code>), each one inducing the corresponding index.
|
||||
Indices are accessed via
|
||||
<a href="../reference/multi_index_container.html#index_retrieval"><code>get</code></a><code><N>()</code>
|
||||
@@ -473,26 +474,6 @@ means of user-defined <code>typedef</code>s:
|
||||
<span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=number>1</span><span class=special>>().</span><span class=identifier>find</span><span class=special>(</span><span class=string>"Judy Smith"</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Additionally, <code>multi_index_container</code>s provide shortcut
|
||||
definitions to the iterator types of their constituent indices:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>it</span><span class=special>=</span>
|
||||
<span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=number>1</span><span class=special>>().</span><span class=identifier>find</span><span class=special>(</span><span class=string>"Judy Smith"</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
There is a variation of the expression above for use with
|
||||
<a href="#tagging">tags</a>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>index_iterator</span><span class=special><</span><span class=identifier>name</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>it</span><span class=special>=</span>
|
||||
<span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=identifier>name</span><span class=special>>().</span><span class=identifier>find</span><span class=special>(</span><span class=string>"Judy Smith"</span><span class=special>);</span> <span class=comment>// get<1> would also work</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h2>
|
||||
<a name="index_types">Index types</a>
|
||||
</h2>
|
||||
@@ -956,15 +937,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>&</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>-></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 +1025,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:
|
||||
@@ -1034,10 +1069,10 @@ indices with respect to <code>std::list</code>s, namely that elements of an
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>s</span><span class=special>;</span> <span class=comment>// list-like container</span>
|
||||
<span class=special>></span> <span class=identifier>s</span><span class=special>;</span> <span class=comment>// list-like container</span>
|
||||
|
||||
<span class=identifier>s</span><span class=special>.</span><span class=identifier>push_front</span><span class=special>(</span><span class=number>0</span><span class=special>);</span>
|
||||
<span class=special>*(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>())==</span><span class=number>1</span><span class=special>;</span> <span class=comment>// ERROR: the element cannot be changed</span>
|
||||
<span class=special>*(</span><span class=identifier>s</span><span class=special>.</span><span class=identifier>begin</span><span class=special>())=</span><span class=number>1</span><span class=special>;</span> <span class=comment>// ERROR: the element cannot be changed</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
@@ -1154,7 +1189,7 @@ A slightly more interesting example:
|
||||
|
||||
<span class=comment>// prepend "older" to all occurrences of "sister"</span>
|
||||
|
||||
<span class=identifier>text_container</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>it1</span><span class=special>=</span>
|
||||
<span class=identifier>text_container</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it1</span><span class=special>=</span>
|
||||
<span class=identifier>sorted_index</span><span class=special>.</span><span class=identifier>lower_bound</span><span class=special>(</span><span class=string>"sister"</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>while</span><span class=special>(</span><span class=identifier>it1</span><span class=special>!=</span><span class=identifier>sorted_index</span><span class=special>.</span><span class=identifier>end</span><span class=special>()&&*</span><span class=identifier>it1</span><span class=special>==</span><span class=string>"sister"</span><span class=special>){</span>
|
||||
@@ -1205,9 +1240,9 @@ Index types
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 21st 2006</p>
|
||||
<p>Revised November 7th 2008</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2008 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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><</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>></span>
|
||||
<span class=preprocessor>#include</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=identifier>managed_shared_memory</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></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><</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>></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><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>sequenced</span><span class=special><>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>shared_int_allocator</span>
|
||||
<span class=special>></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>"SharedMemoryID"</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><</span><span class=identifier>unique_int_list</span><span class=special>></span>
|
||||
<span class=special>(</span><span class=string>"UniqueIntListID"</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>
|
||||
@@ -263,7 +318,7 @@ an equality operator.
|
||||
<p>
|
||||
Iterators to indices of a <code>multi_index_container</code> can also be
|
||||
serialized. Serialization of iterators must be done only after serializing
|
||||
its corresponding container.
|
||||
their corresponding container.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -285,9 +340,9 @@ Debugging support
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised July 17th 2007</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2007 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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> random_access </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><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span>
|
||||
<span class=special>></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>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2007 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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><</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>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>global_fun</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></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>&</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><</span>
|
||||
<span class=identifier>rectangle</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=comment>// sort by increasing area</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>global_fun</span><span class=special><</span><span class=keyword>const</span> <span class=identifier>rectangle</span><span class=special>&,</span><span class=keyword>unsigned</span> <span class=keyword>long</span><span class=special>,&</span><span class=identifier>area</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></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><</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>></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&</code>, without omitting the "<code>const</code>"
|
||||
and "<code>&</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>&);</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>&);</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<T,int,&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<const T&,int,&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<T&,int,&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<T></code></td>
|
||||
<td align="center" rowspan="6"><code>reference_wrapper<T></code></td>
|
||||
<td><code>i</code></td>
|
||||
<td><code>member<T,int,&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<const T&,int,&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<T&,int,&T::gg></code></td>
|
||||
<td align="center">yes</td>
|
||||
<td align="center">no</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" rowspan="4"><code>reference_wrapper<const T></code></td>
|
||||
<td align="center" rowspan="6"><code>reference_wrapper<const T></code></td>
|
||||
<td><code>i</code></td>
|
||||
<td><code>member<T,const int,&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"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>gf()</code></td>
|
||||
<td><code>global_fun<const T&,int,&T::gf></code></td>
|
||||
<td align="center">yes</td>
|
||||
<td align="center">no</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>gg()</code></td>
|
||||
<td colspan="3"> </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<T></code></td>
|
||||
<td><code>i</code></td>
|
||||
<td><code>member<T,int,&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<const T&,int,&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<T&,int,&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<const T></code></td>
|
||||
<td><code>i</code></td>
|
||||
<td><code>member<T,const int,&T::i></code></td>
|
||||
@@ -782,6 +893,16 @@ each of its members.
|
||||
<td><code>g()</code></td>
|
||||
<td colspan="3"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>gf()</code></td>
|
||||
<td><code>global_fun<const T&,int,&T::gf></code></td>
|
||||
<td align="center">yes</td>
|
||||
<td align="center">no</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>gg()</code></td>
|
||||
<td colspan="3"> </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>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2007 Joaquín M López Muñ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">
|
||||
|
||||
@@ -285,7 +285,7 @@ definition of the <code>multi_index_container</code>:
|
||||
Each of these types is an MPL sequence with as many elements as indices
|
||||
comprise the <code>multi_index_container</code>: for instance, the <code>n</code>-th
|
||||
element of <code>iterator_type_list</code> is the same as
|
||||
<code>nth_index_iterator<n>::type</code>.
|
||||
<code>nth_index<n>::type::iterator</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -392,9 +392,9 @@ Boost.MultiIndex reference
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised February 6th 2006</p>
|
||||
<p>Revised November 7th 2008</p>
|
||||
|
||||
<p>© Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2008 Joaquín M López Muñ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">
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# 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)
|
||||
#
|
||||
# See http://www.boost.org/libs/multi_index for library home page.
|
||||
|
||||
subproject libs/multi_index/example ;
|
||||
|
||||
exe basic
|
||||
: basic.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
@@ -29,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
|
||||
@@ -61,7 +64,6 @@ exe sequenced
|
||||
|
||||
exe serialization
|
||||
: serialization.cpp
|
||||
<lib>../../serialization/build/boost_serialization
|
||||
/boost/serialization//boost_serialization
|
||||
: <include>$(BOOST_ROOT)
|
||||
std::locale-support
|
||||
;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex basic example.
|
||||
*
|
||||
* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
+12
-5
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of a bidirectional map.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2009 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
@@ -35,7 +34,15 @@ struct to{};
|
||||
template<typename FromType,typename ToType>
|
||||
struct bidirectional_map
|
||||
{
|
||||
typedef std::pair<FromType,ToType> value_type;
|
||||
struct value_type
|
||||
{
|
||||
value_type(const FromType& first_,const ToType& second_):
|
||||
first(first_),second(second_)
|
||||
{}
|
||||
|
||||
FromType first;
|
||||
ToType second;
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) ||\
|
||||
defined(BOOST_MSVC)&&(BOOST_MSVC<1300) ||\
|
||||
@@ -108,7 +115,7 @@ int main()
|
||||
std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
|
||||
}
|
||||
else{
|
||||
nth_index_iterator<dictionary,1>::type it2=get<1>(d).find(word);
|
||||
nth_index<dictionary,1>::type::iterator it2=get<1>(d).find(word);
|
||||
if(it2!=get<1>(d).end()){
|
||||
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
|
||||
}
|
||||
@@ -129,7 +136,7 @@ int main()
|
||||
else{
|
||||
/* word not found in Spanish, try our luck in English */
|
||||
|
||||
dictionary::index_iterator<to>::type it2=d.get<to>().find(word);
|
||||
dictionary::index<to>::type::iterator it2=d.get<to>().find(word);
|
||||
if(it2!=d.get<to>().end()){
|
||||
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example: complex searches and foreign keys.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -245,7 +245,7 @@ int main()
|
||||
|
||||
/* find all the cars for the manufacturer given */
|
||||
|
||||
index_iterator<car_table,manufacturer>::type ic0,ic1;
|
||||
boost::multi_index::index<car_table,manufacturer>::type::iterator ic0,ic1;
|
||||
boost::tuples::tie(ic0,ic1)=get<manufacturer>(ct).equal_range(cm);
|
||||
|
||||
/* construct a view (indexed by price) with these */
|
||||
@@ -280,7 +280,7 @@ int main()
|
||||
|
||||
/* find the cars in the range given */
|
||||
|
||||
index_iterator<car_table,price>::type ic0,ic1;
|
||||
boost::multi_index::index<car_table,price>::type::iterator ic0,ic1;
|
||||
ic0=get<price>(ct).lower_bound(min_price);
|
||||
ic1=get<price>(ct).upper_bound(max_price);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of composite keys.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -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;
|
||||
|
||||
@@ -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-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,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>
|
||||
@@ -29,8 +30,8 @@ using namespace boost::multi_index;
|
||||
|
||||
struct name_record
|
||||
{
|
||||
name_record(std::string given_name,std::string family_name):
|
||||
given_name(given_name),family_name(family_name)
|
||||
name_record(std::string given_name_,std::string family_name_):
|
||||
given_name(given_name_),family_name(family_name_)
|
||||
{}
|
||||
|
||||
std::string name()const
|
||||
@@ -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<name_record_set,1>::type::iterator it1=get<1>(ns).begin();
|
||||
it1!=get<1>(ns).end();++it1){
|
||||
std::cout<<it1->name()<<std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+3
-1
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of use of hashed indices.
|
||||
*
|
||||
* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -66,6 +66,8 @@ typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
|
||||
|
||||
int main()
|
||||
{
|
||||
/* boostinspect:noascii */
|
||||
|
||||
std::string text=
|
||||
"En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha "
|
||||
"mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga "
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
/* Boost.MultiIndex example of use of Boost.Interprocess allocators.
|
||||
*
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of use of multi_index_container::ctor_args_list.
|
||||
*
|
||||
* Copyright 2003-2004 Joaqu匤 M L�ez Mu�z.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of use of random access indices.
|
||||
*
|
||||
* Copyright 2003-2006 Joaqu匤 M L�ez Mu�z.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of use of rearrange facilities.
|
||||
*
|
||||
* Copyright 2003-2006 Joaqu匤 M L�ez Mu�z.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of use of sequenced indices.
|
||||
*
|
||||
* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex example of serialization of a MRU list.
|
||||
*
|
||||
* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
typedef Item item_type;
|
||||
typedef typename item_list::iterator iterator;
|
||||
|
||||
mru_list(std::size_t max_num_items):max_num_items(max_num_items){}
|
||||
mru_list(std::size_t max_num_items_):max_num_items(max_num_items_){}
|
||||
|
||||
void insert(const item_type& item)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,6 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
@@ -106,7 +107,6 @@
|
||||
namespace boost{
|
||||
|
||||
template<class T> class reference_wrapper; /* fwd decl. */
|
||||
template<class T> struct hash; /* fwd decl. */
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
@@ -563,6 +563,11 @@ struct hash_cval:
|
||||
|
||||
/* composite_key_result */
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512)
|
||||
#endif
|
||||
|
||||
template<typename CompositeKey>
|
||||
struct composite_key_result
|
||||
{
|
||||
@@ -578,6 +583,10 @@ struct composite_key_result
|
||||
const value_type& value;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/* composite_key */
|
||||
|
||||
/* NB. Some overloads of operator() have an extra dummy parameter int=0.
|
||||
@@ -619,7 +628,7 @@ public:
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr,const value_type>,result_type>::type
|
||||
is_convertible<const ChainedPtr&,const value_type&>,result_type>::type
|
||||
#else
|
||||
result_type
|
||||
#endif
|
||||
@@ -989,7 +998,7 @@ public:
|
||||
const composite_key_result<CompositeKey>& x,
|
||||
const Value& y)const
|
||||
{
|
||||
return operator()(x,make_tuple(cref(y)));
|
||||
return operator()(x,boost::make_tuple(boost::cref(y)));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1024,7 +1033,7 @@ public:
|
||||
const Value& x,
|
||||
const composite_key_result<CompositeKey>& y)const
|
||||
{
|
||||
return operator()(make_tuple(cref(x)),y);
|
||||
return operator()(boost::make_tuple(boost::cref(x)),y);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -34,12 +34,19 @@
|
||||
* MSVC 7.1/8.0 seem to have a similar problem, though the conditions in
|
||||
* which the error happens are not that simple. I have yet to isolate this
|
||||
* into a snippet suitable for bug reporting.
|
||||
* Sun Studio also has this problem, which might be related, from the
|
||||
* information gathered at Sun forums, with a known issue notified at the
|
||||
* internal bug report 6421933. The bug is present up to Studio Express 2,
|
||||
* the latest preview version of the future Sun Studio 12. As of this writing
|
||||
* (October 2006) it is not known whether a fix will finally make it into the
|
||||
* official Sun Studio 12.
|
||||
*/
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, <3)||\
|
||||
BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\
|
||||
BOOST_WORKAROUND(BOOST_MSVC,==1310)||\
|
||||
BOOST_WORKAROUND(BOOST_MSVC,==1400)
|
||||
BOOST_WORKAROUND(BOOST_MSVC,==1400)||\
|
||||
BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590))
|
||||
#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS public
|
||||
#else
|
||||
#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS private
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename T>
|
||||
void adl_swap(T& x,T& y)
|
||||
{
|
||||
|
||||
#if !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
|
||||
using std::swap;
|
||||
swap(x,y);
|
||||
#else
|
||||
std::swap(x,y);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/multi_index/detail/adl_swap.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <memory>
|
||||
|
||||
@@ -44,8 +46,15 @@ namespace detail{
|
||||
template<typename T,typename Allocator=std::allocator<T> >
|
||||
struct auto_space:private noncopyable
|
||||
{
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,T
|
||||
>::type
|
||||
>::type::pointer pointer;
|
||||
|
||||
explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1):
|
||||
al_(al),n_(n),data_(n_?al_.allocate(n_):0)
|
||||
al_(al),n_(n),data_(n_?al_.allocate(n_):pointer(0))
|
||||
{}
|
||||
|
||||
~auto_space()
|
||||
@@ -55,10 +64,11 @@ struct auto_space:private noncopyable
|
||||
|
||||
Allocator get_allocator()const{return al_;}
|
||||
|
||||
T* data()const{return data_;}
|
||||
pointer data()const{return data_;}
|
||||
|
||||
void swap(auto_space& x)
|
||||
{
|
||||
if(al_!=x.al_)adl_swap(al_,x.al_);
|
||||
std::swap(n_,x.n_);
|
||||
std::swap(data_,x.data_);
|
||||
}
|
||||
@@ -67,7 +77,7 @@ private:
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,T>::type al_;
|
||||
std::size_t n_;
|
||||
T* data_;
|
||||
pointer data_;
|
||||
};
|
||||
|
||||
template<typename T,typename Allocator>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -31,10 +31,10 @@ namespace detail{
|
||||
* iterators (ordered and sequenced indices.)
|
||||
*/
|
||||
|
||||
template<typename Node,typename Derived=mpl::na>
|
||||
template<typename Node>
|
||||
class bidir_node_iterator:
|
||||
public bidirectional_iterator_helper<
|
||||
bidir_node_iterator<Node,Derived>,
|
||||
bidir_node_iterator<Node>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
const typename Node::value_type*,
|
||||
@@ -49,12 +49,6 @@ public:
|
||||
return node->value();
|
||||
}
|
||||
|
||||
friend bool operator==(
|
||||
const bidir_node_iterator& x,const bidir_node_iterator& y)
|
||||
{
|
||||
return x.node==y.node;
|
||||
}
|
||||
|
||||
bidir_node_iterator& operator++()
|
||||
{
|
||||
Node::increment(node);
|
||||
@@ -77,14 +71,14 @@ public:
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive& ar,const unsigned int version)const
|
||||
void save(Archive& ar,const unsigned int)const
|
||||
{
|
||||
node_base_type* bnode=node;
|
||||
ar<<serialization::make_nvp("pointer",bnode);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int version)
|
||||
void load(Archive& ar,const unsigned int)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
@@ -102,6 +96,14 @@ private:
|
||||
Node* node;
|
||||
};
|
||||
|
||||
template<typename Node>
|
||||
bool operator==(
|
||||
const bidir_node_iterator<Node>& x,
|
||||
const bidir_node_iterator<Node>& y)
|
||||
{
|
||||
return x.get_node()==y.get_node();
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <algorithm>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/hash_index_node.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <cstddef>
|
||||
#include <limits.h>
|
||||
@@ -84,8 +85,20 @@ protected:
|
||||
template<typename Allocator>
|
||||
class bucket_array:public bucket_array_base
|
||||
{
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
hashed_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type node_impl_type;
|
||||
|
||||
public:
|
||||
bucket_array(const Allocator& al,hashed_index_node_impl* end_,std::size_t size):
|
||||
typedef typename node_impl_type::pointer pointer;
|
||||
|
||||
bucket_array(const Allocator& al,pointer end_,std::size_t size):
|
||||
size_(bucket_array_base::next_prime(size)),
|
||||
spc(al,size_+1)
|
||||
{
|
||||
@@ -104,21 +117,21 @@ public:
|
||||
return hash%size_;
|
||||
}
|
||||
|
||||
hashed_index_node_impl* begin()const{return &buckets()[0];}
|
||||
hashed_index_node_impl* end()const{return &buckets()[size_];}
|
||||
hashed_index_node_impl* at(std::size_t n)const{return &buckets()[n];}
|
||||
pointer begin()const{return buckets();}
|
||||
pointer end()const{return buckets()+size_;}
|
||||
pointer at(std::size_t n)const{return buckets()+n;}
|
||||
|
||||
std::size_t first_nonempty(std::size_t n)const
|
||||
{
|
||||
for(;;++n){
|
||||
hashed_index_node_impl* x=at(n);
|
||||
pointer x=at(n);
|
||||
if(x->next()!=x)return n;
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for(hashed_index_node_impl* x=begin(),*y=end();x!=y;++x)x->next()=x;
|
||||
for(pointer x=begin(),y=end();x!=y;++x)x->next()=x;
|
||||
}
|
||||
|
||||
void swap(bucket_array& x)
|
||||
@@ -128,10 +141,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t size_;
|
||||
auto_space<hashed_index_node_impl,Allocator> spc;
|
||||
std::size_t size_;
|
||||
auto_space<node_impl_type,Allocator> spc;
|
||||
|
||||
hashed_index_node_impl* buckets()const
|
||||
pointer buckets()const
|
||||
{
|
||||
return spc.data();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <algorithm>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
@@ -69,31 +70,31 @@ public:
|
||||
{
|
||||
if(!released){
|
||||
for(std::size_t i=0;i<n;++i){
|
||||
boost::detail::allocator::destroy(&spc.data()[i].second->value());
|
||||
deallocate(spc.data()[i].second);
|
||||
boost::detail::allocator::destroy(&(spc.data()+i)->second->value());
|
||||
deallocate((spc.data()+i)->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const_iterator begin()const{return spc.data();}
|
||||
const_iterator end()const{return spc.data()+n;}
|
||||
const_iterator begin()const{return &*spc.data();}
|
||||
const_iterator end()const{return &*(spc.data()+n);}
|
||||
|
||||
void clone(Node* node)
|
||||
{
|
||||
spc.data()[n].first=node;
|
||||
spc.data()[n].second=al_.allocate(1);
|
||||
(spc.data()+n)->first=node;
|
||||
(spc.data()+n)->second=&*al_.allocate(1);
|
||||
BOOST_TRY{
|
||||
boost::detail::allocator::construct(
|
||||
&spc.data()[n].second->value(),node->value());
|
||||
&(spc.data()+n)->second->value(),node->value());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
deallocate(spc.data()[n].second);
|
||||
deallocate((spc.data()+n)->second);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
++n;
|
||||
|
||||
if(n==size_)std::sort(spc.data(),spc.data()+size_);
|
||||
if(n==size_)std::sort(&*spc.data(),&*spc.data()+size_);
|
||||
}
|
||||
|
||||
Node* find(Node* node)const
|
||||
@@ -109,18 +110,24 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,Node>::type al_;
|
||||
std::size_t size_;
|
||||
auto_space<copy_map_entry<Node>,Allocator> spc;
|
||||
std::size_t n;
|
||||
Node* header_org_;
|
||||
Node* header_cpy_;
|
||||
bool released;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,Node>::type
|
||||
>::type allocator_type;
|
||||
typedef typename allocator_type::pointer allocator_pointer;
|
||||
|
||||
allocator_type al_;
|
||||
std::size_t size_;
|
||||
auto_space<copy_map_entry<Node>,Allocator> spc;
|
||||
std::size_t n;
|
||||
Node* header_org_;
|
||||
Node* header_cpy_;
|
||||
bool released;
|
||||
|
||||
void deallocate(Node* node)
|
||||
{
|
||||
al_.deallocate(node,1);
|
||||
al_.deallocate(static_cast<allocator_pointer>(node),1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/* Copyright 2003-2005 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_DETAIL_DEF_CTOR_TUPLE_CONS_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_DEF_CTOR_TUPLE_CONS_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
/* In MSVC, tuples::cons is not default constructible. We provide a
|
||||
* tiny wrapper around tuple::cons filling that hole.
|
||||
*/
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename Cons>
|
||||
struct default_constructible_tuple_cons:Cons
|
||||
{
|
||||
default_constructible_tuple_cons():
|
||||
Cons(
|
||||
Cons::head_type(),
|
||||
static_cast<const Cons::tail_type&>(
|
||||
default_constructible_tuple_cons<Cons::tail_type>()))
|
||||
{}
|
||||
|
||||
default_constructible_tuple_cons(const Cons& cons):Cons(cons){}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct default_constructible_tuple_cons<tuples::null_type>:tuples::null_type
|
||||
{
|
||||
default_constructible_tuple_cons(){}
|
||||
default_constructible_tuple_cons(const tuples::null_type&){}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif /* BOOST_MSVC */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -37,14 +37,14 @@ public:
|
||||
typedef const typename Node::value_type& reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
duplicates_iterator(Node* node,Node* end,Predicate pred):
|
||||
node(node),begin_chunk(0),end(end),pred(pred)
|
||||
duplicates_iterator(Node* node_,Node* end_,Predicate pred_):
|
||||
node(node_),begin_chunk(0),end(end_),pred(pred_)
|
||||
{
|
||||
advance();
|
||||
}
|
||||
|
||||
duplicates_iterator(Node* end,Predicate pred):
|
||||
node(end),begin_chunk(end),end(end),pred(pred)
|
||||
duplicates_iterator(Node* end_,Predicate pred_):
|
||||
node(end_),begin_chunk(end_),end(end_),pred(pred_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,7 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/mpl/aux_/na.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
@@ -26,8 +26,6 @@
|
||||
|
||||
namespace boost{
|
||||
|
||||
template<class T> struct hash; /* fwd decl. */
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -30,10 +30,10 @@ namespace detail{
|
||||
/* Iterator class for hashed indices.
|
||||
*/
|
||||
|
||||
template<typename Node,typename BucketArray,typename Derived=mpl::na>
|
||||
template<typename Node,typename BucketArray>
|
||||
class hashed_index_iterator:
|
||||
public forward_iterator_helper<
|
||||
hashed_index_iterator<Node,BucketArray,Derived>,
|
||||
hashed_index_iterator<Node,BucketArray>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
const typename Node::value_type*,
|
||||
@@ -50,12 +50,6 @@ public:
|
||||
return node->value();
|
||||
}
|
||||
|
||||
friend bool operator==(
|
||||
const hashed_index_iterator& x,const hashed_index_iterator& y)
|
||||
{
|
||||
return x.node==y.node;
|
||||
}
|
||||
|
||||
hashed_index_iterator& operator++()
|
||||
{
|
||||
Node::increment(node,buckets->begin(),buckets->end());
|
||||
@@ -72,7 +66,7 @@ public:
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive& ar,const unsigned int version)const
|
||||
void save(Archive& ar,const unsigned int)const
|
||||
{
|
||||
node_base_type* bnode=node;
|
||||
ar<<serialization::make_nvp("pointer",bnode);
|
||||
@@ -80,7 +74,7 @@ public:
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int version)
|
||||
void load(Archive& ar,const unsigned int)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
@@ -100,6 +94,14 @@ private:
|
||||
BucketArray* buckets;
|
||||
};
|
||||
|
||||
template<typename Node,typename BucketArray>
|
||||
bool operator==(
|
||||
const hashed_index_iterator<Node,BucketArray>& x,
|
||||
const hashed_index_iterator<Node,BucketArray>& y)
|
||||
{
|
||||
return x.get_node()==y.get_node();
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,6 +14,8 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace boost{
|
||||
@@ -24,21 +26,33 @@ namespace detail{
|
||||
|
||||
/* singly-linked node for use by hashed_index */
|
||||
|
||||
template<typename Allocator>
|
||||
struct hashed_index_node_impl
|
||||
{
|
||||
hashed_index_node_impl*& next(){return next_;}
|
||||
hashed_index_node_impl* next()const{return next_;}
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,hashed_index_node_impl
|
||||
>::type
|
||||
>::type::pointer pointer;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,hashed_index_node_impl
|
||||
>::type
|
||||
>::type::const_pointer const_pointer;
|
||||
|
||||
pointer& next(){return next_;}
|
||||
pointer next()const{return next_;}
|
||||
|
||||
/* algorithmic stuff */
|
||||
|
||||
static void increment(
|
||||
hashed_index_node_impl*& x,
|
||||
hashed_index_node_impl* bbegin,hashed_index_node_impl* bbend)
|
||||
static void increment(pointer& x,pointer bbegin,pointer bend)
|
||||
{
|
||||
std::less_equal<hashed_index_node_impl*> leq;
|
||||
std::less_equal<pointer> leq;
|
||||
|
||||
x=x->next();
|
||||
if(leq(bbegin,x)&&leq(x,bbend)){ /* bucket node */
|
||||
if(leq(bbegin,x)&&leq(x,bend)){ /* bucket node */
|
||||
do{
|
||||
++x;
|
||||
}while(x->next()==x);
|
||||
@@ -46,68 +60,100 @@ struct hashed_index_node_impl
|
||||
}
|
||||
}
|
||||
|
||||
static void link(
|
||||
hashed_index_node_impl* x,hashed_index_node_impl* pos)
|
||||
static void link(pointer x,pointer pos)
|
||||
{
|
||||
x->next()=pos->next();
|
||||
pos->next()=x;
|
||||
};
|
||||
|
||||
static void unlink(hashed_index_node_impl* x)
|
||||
static void unlink(pointer x)
|
||||
{
|
||||
hashed_index_node_impl* y=x->next();
|
||||
pointer y=x->next();
|
||||
while(y->next()!=x){y=y->next();}
|
||||
y->next()=x->next();
|
||||
}
|
||||
|
||||
static hashed_index_node_impl* prev(hashed_index_node_impl* x)
|
||||
static pointer prev(pointer x)
|
||||
{
|
||||
hashed_index_node_impl* y=x->next();
|
||||
pointer y=x->next();
|
||||
while(y->next()!=x){y=y->next();}
|
||||
return y;
|
||||
}
|
||||
|
||||
static void unlink_next(hashed_index_node_impl* x)
|
||||
static void unlink_next(pointer x)
|
||||
{
|
||||
x->next()=x->next()->next();
|
||||
}
|
||||
|
||||
private:
|
||||
hashed_index_node_impl();
|
||||
|
||||
hashed_index_node_impl* next_;
|
||||
pointer next_;
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct hashed_index_node_trampoline:hashed_index_node_impl{};
|
||||
struct hashed_index_node_trampoline:
|
||||
prevent_eti<
|
||||
Super,
|
||||
hashed_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typename Super::allocator_type,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type
|
||||
{
|
||||
typedef typename prevent_eti<
|
||||
Super,
|
||||
hashed_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typename Super::allocator_type,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type impl_type;
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct hashed_index_node:Super,hashed_index_node_trampoline<Super>
|
||||
{
|
||||
hashed_index_node_impl* impl()
|
||||
{return static_cast<impl_type*>(this);}
|
||||
const hashed_index_node_impl* impl()const
|
||||
{return static_cast<const impl_type*>(this);}
|
||||
private:
|
||||
typedef hashed_index_node_trampoline<Super> trampoline;
|
||||
|
||||
static hashed_index_node* from_impl(hashed_index_node_impl *x)
|
||||
{return static_cast<hashed_index_node*>(static_cast<impl_type*>(x));}
|
||||
static const hashed_index_node* from_impl(const hashed_index_node_impl* x)
|
||||
public:
|
||||
typedef typename trampoline::impl_type impl_type;
|
||||
typedef typename trampoline::pointer impl_pointer;
|
||||
typedef typename trampoline::const_pointer const_impl_pointer;
|
||||
|
||||
impl_pointer impl()
|
||||
{
|
||||
return static_cast<impl_pointer>(
|
||||
static_cast<impl_type*>(static_cast<trampoline*>(this)));
|
||||
}
|
||||
|
||||
const_impl_pointer impl()const
|
||||
{
|
||||
return static_cast<const_impl_pointer>(
|
||||
static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
|
||||
}
|
||||
|
||||
static hashed_index_node* from_impl(impl_pointer x)
|
||||
{
|
||||
return static_cast<hashed_index_node*>(
|
||||
static_cast<trampoline*>(&*x));
|
||||
}
|
||||
|
||||
static const hashed_index_node* from_impl(const_impl_pointer x)
|
||||
{
|
||||
return static_cast<const hashed_index_node*>(
|
||||
static_cast<const impl_type*>(x));
|
||||
static_cast<const trampoline*>(&*x));
|
||||
}
|
||||
|
||||
static void increment(
|
||||
hashed_index_node*& x,
|
||||
hashed_index_node_impl* bbegin,hashed_index_node_impl* bend)
|
||||
hashed_index_node*& x,impl_pointer bbegin,impl_pointer bend)
|
||||
{
|
||||
hashed_index_node_impl* xi=x->impl();
|
||||
impl_type::increment(xi,bbegin,bend);
|
||||
impl_pointer xi=x->impl();
|
||||
trampoline::increment(xi,bbegin,bend);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef hashed_index_node_trampoline<Super> impl_type;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -29,13 +29,13 @@ namespace detail{
|
||||
* to the base from member trick.
|
||||
*/
|
||||
|
||||
template<typename NodeType,typename Final>
|
||||
template<typename NodeTypePtr,typename Final>
|
||||
struct header_holder:private noncopyable
|
||||
{
|
||||
header_holder():member(final().allocate_node()){}
|
||||
~header_holder(){final().deallocate_node(member);}
|
||||
~header_holder(){final().deallocate_node(&*member);}
|
||||
|
||||
NodeType* member;
|
||||
NodeTypePtr member;
|
||||
|
||||
private:
|
||||
Final& final(){return *static_cast<Final*>(this);}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -46,7 +46,7 @@ template<typename Value,typename IndexSpecifierList,typename Allocator>
|
||||
class index_base
|
||||
{
|
||||
protected:
|
||||
typedef index_node_base<Value> node_type;
|
||||
typedef index_node_base<Value,Allocator> node_type;
|
||||
typedef typename multi_index_node_type<
|
||||
Value,IndexSpecifierList,Allocator>::type final_node_type;
|
||||
typedef multi_index_container<
|
||||
@@ -117,6 +117,8 @@ protected:
|
||||
|
||||
bool modify_(node_type*){return true;}
|
||||
|
||||
bool modify_rollback_(node_type*){return true;}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
|
||||
@@ -162,9 +164,13 @@ protected:
|
||||
{return final().replace_(k,x);}
|
||||
|
||||
template<typename Modifier>
|
||||
bool final_modify_(Modifier mod,final_node_type* x)
|
||||
bool final_modify_(Modifier& mod,final_node_type* x)
|
||||
{return final().modify_(mod,x);}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x)
|
||||
{return final().modify_(mod,back,x);}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
||||
void final_check_invariant_()const{final().check_invariant_();}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Node** entries()const{return spc.data();}
|
||||
Node** entries()const{return &*spc.data();}
|
||||
|
||||
/* We try to delay sorting as much as possible just in case it
|
||||
* is not necessary, hence this version of load_node.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -179,7 +179,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
entry* entries()const{return spc.data();}
|
||||
entry* entries()const{return &*spc.data();}
|
||||
|
||||
auto_space<entry,Allocator> spc;
|
||||
std::size_t size_;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -42,11 +42,12 @@ struct pod_value_holder
|
||||
>::type space;
|
||||
};
|
||||
|
||||
template<typename Value>
|
||||
template<typename Value,typename Allocator>
|
||||
struct index_node_base:private pod_value_holder<Value>
|
||||
{
|
||||
typedef index_node_base base_type; /* used for serialization purposes */
|
||||
typedef Value value_type;
|
||||
typedef Allocator allocator_type;
|
||||
|
||||
value_type& value()
|
||||
{
|
||||
@@ -68,9 +69,6 @@ struct index_node_base:private pod_value_holder<Value>
|
||||
}
|
||||
|
||||
private:
|
||||
index_node_base();
|
||||
/* this class is not intended to be cted, merely allocated */
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
friend class boost::serialization::access;
|
||||
|
||||
@@ -84,7 +82,6 @@ private:
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template<typename Node,typename Value>
|
||||
@@ -92,7 +89,9 @@ Node* node_from_value(
|
||||
const Value* p
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
|
||||
{
|
||||
return static_cast<Node*>(index_node_base<Value>::from_value(p));
|
||||
typedef typename Node::allocator_type allocator_type;
|
||||
return static_cast<Node*>(
|
||||
index_node_base<Value,allocator_type>::from_value(p));
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
@@ -113,9 +112,9 @@ namespace multi_index{
|
||||
namespace detail{
|
||||
#endif
|
||||
|
||||
template<class Archive,typename Value>
|
||||
template<class Archive,typename Value,typename Allocator>
|
||||
inline void load_construct_data(
|
||||
Archive&,boost::multi_index::detail::index_node_base<Value>*,
|
||||
Archive&,boost::multi_index::detail::index_node_base<Value,Allocator>*,
|
||||
const unsigned int)
|
||||
{
|
||||
throw_exception(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -30,6 +30,12 @@ namespace detail{
|
||||
* for internal consumption.
|
||||
*/
|
||||
|
||||
/* NB. The purpose of the (non-inclass) global operators ==, < and - defined
|
||||
* above is to partially alleviate a problem of MSVC++ 6.0 by * which
|
||||
* friend-injected operators on T are not visible if T is instantiated only
|
||||
* in template code where T is a dependent type.
|
||||
*/
|
||||
|
||||
class iter_adaptor_access
|
||||
{
|
||||
public:
|
||||
@@ -107,6 +113,15 @@ private:
|
||||
const Derived& final()const{return *static_cast<const Derived*>(this);}
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
bool operator==(
|
||||
const forward_iter_adaptor_base<Derived,Base>& x,
|
||||
const forward_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(
|
||||
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
|
||||
}
|
||||
|
||||
template<>
|
||||
struct iter_adaptor_selector<std::forward_iterator_tag>
|
||||
{
|
||||
@@ -156,6 +171,15 @@ private:
|
||||
const Derived& final()const{return *static_cast<const Derived*>(this);}
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
bool operator==(
|
||||
const bidirectional_iter_adaptor_base<Derived,Base>& x,
|
||||
const bidirectional_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(
|
||||
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
|
||||
}
|
||||
|
||||
template<>
|
||||
struct iter_adaptor_selector<std::bidirectional_iterator_tag>
|
||||
{
|
||||
@@ -228,6 +252,34 @@ private:
|
||||
const Derived& final()const{return *static_cast<const Derived*>(this);}
|
||||
};
|
||||
|
||||
template<class Derived,class Base>
|
||||
bool operator==(
|
||||
const random_access_iter_adaptor_base<Derived,Base>& x,
|
||||
const random_access_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::equal(
|
||||
static_cast<const Derived&>(x),static_cast<const Derived&>(y));
|
||||
}
|
||||
|
||||
template<class Derived,class Base>
|
||||
bool operator<(
|
||||
const random_access_iter_adaptor_base<Derived,Base>& x,
|
||||
const random_access_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::distance_to(
|
||||
static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0;
|
||||
}
|
||||
|
||||
template<class Derived,class Base>
|
||||
typename random_access_iter_adaptor_base<Derived,Base>::difference_type
|
||||
operator-(
|
||||
const random_access_iter_adaptor_base<Derived,Base>& x,
|
||||
const random_access_iter_adaptor_base<Derived,Base>& y)
|
||||
{
|
||||
return iter_adaptor_access::distance_to(
|
||||
static_cast<const Derived&>(y),static_cast<const Derived&>(x));
|
||||
}
|
||||
|
||||
template<>
|
||||
struct iter_adaptor_selector<std::random_access_iterator_tag>
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -24,19 +24,19 @@ namespace detail{
|
||||
* with references to references, dealing with function pointers, etc.
|
||||
*/
|
||||
|
||||
template<typename Modifier,typename Value,typename KeyFromValue>
|
||||
template<typename Fun,typename Value,typename KeyFromValue>
|
||||
struct modify_key_adaptor
|
||||
{
|
||||
|
||||
modify_key_adaptor(Modifier mod_,KeyFromValue kfv_):mod(mod_),kfv(kfv_){}
|
||||
modify_key_adaptor(Fun f_,KeyFromValue kfv_):f(f_),kfv(kfv_){}
|
||||
|
||||
void operator()(Value& x)
|
||||
{
|
||||
mod(kfv(x));
|
||||
f(kfv(x));
|
||||
}
|
||||
|
||||
private:
|
||||
Modifier mod;
|
||||
Fun f;
|
||||
KeyFromValue kfv;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -65,7 +65,7 @@ struct multi_index_node_type
|
||||
|
||||
typedef typename mpl::reverse_iter_fold<
|
||||
IndexSpecifierList,
|
||||
index_node_base<Value>,
|
||||
index_node_base<Value,Allocator>,
|
||||
mpl::bind2<index_node_applier,mpl::_2,mpl::_1>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -42,12 +42,15 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <cstddef>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/multi_index/detail/uintptr_type.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
@@ -61,29 +64,43 @@ namespace detail{
|
||||
enum ordered_index_color{red=false,black=true};
|
||||
enum ordered_index_side{to_left=false,to_right=true};
|
||||
|
||||
template<typename Allocator>
|
||||
struct ordered_index_node_impl; /* fwd decl. */
|
||||
|
||||
template<typename Allocator>
|
||||
struct ordered_index_node_std_base
|
||||
{
|
||||
typedef ordered_index_color& color_ref;
|
||||
typedef ordered_index_node_impl*& parent_ref;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
ordered_index_node_impl<Allocator>
|
||||
>::type
|
||||
>::type::pointer pointer;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
ordered_index_node_impl<Allocator>
|
||||
>::type
|
||||
>::type::const_pointer const_pointer;
|
||||
typedef ordered_index_color& color_ref;
|
||||
typedef pointer& parent_ref;
|
||||
|
||||
ordered_index_color& color(){return color_;}
|
||||
ordered_index_color color()const{return color_;}
|
||||
ordered_index_node_impl*& parent(){return parent_;}
|
||||
ordered_index_node_impl* parent()const{return parent_;}
|
||||
ordered_index_node_impl*& left(){return left_;}
|
||||
ordered_index_node_impl* left()const{return left_;}
|
||||
ordered_index_node_impl*& right(){return right_;}
|
||||
ordered_index_node_impl* right()const{return right_;}
|
||||
ordered_index_color& color(){return color_;}
|
||||
ordered_index_color color()const{return color_;}
|
||||
pointer& parent(){return parent_;}
|
||||
pointer parent()const{return parent_;}
|
||||
pointer& left(){return left_;}
|
||||
pointer left()const{return left_;}
|
||||
pointer& right(){return right_;}
|
||||
pointer right()const{return right_;}
|
||||
|
||||
private:
|
||||
ordered_index_node_std_base();
|
||||
|
||||
ordered_index_color color_;
|
||||
ordered_index_node_impl* parent_;
|
||||
ordered_index_node_impl* left_;
|
||||
ordered_index_node_impl* right_;
|
||||
ordered_index_color color_;
|
||||
pointer parent_;
|
||||
pointer left_;
|
||||
pointer right_;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
|
||||
@@ -93,11 +110,26 @@ private:
|
||||
* ordered_index_node_impl by 25%.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
/* This code casts pointers to an integer type that has been computed
|
||||
* to be large enough to hold the pointer, however the metaprogramming
|
||||
* logic is not always spotted by the VC++ code analyser that issues a
|
||||
* long list of warnings.
|
||||
*/
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4312 4311)
|
||||
#endif
|
||||
|
||||
template<typename Allocator>
|
||||
struct ordered_index_node_compressed_base
|
||||
{
|
||||
typedef ordered_index_node_impl<Allocator>* pointer;
|
||||
typedef const ordered_index_node_impl<Allocator>* const_pointer;
|
||||
|
||||
struct color_ref
|
||||
{
|
||||
color_ref(uintptr_type* r):r(r){}
|
||||
color_ref(uintptr_type* r_):r(r_){}
|
||||
|
||||
operator ordered_index_color()const
|
||||
{
|
||||
@@ -122,14 +154,14 @@ struct ordered_index_node_compressed_base
|
||||
|
||||
struct parent_ref
|
||||
{
|
||||
parent_ref(uintptr_type* r):r(r){}
|
||||
parent_ref(uintptr_type* r_):r(r_){}
|
||||
|
||||
operator ordered_index_node_impl*()const
|
||||
operator pointer()const
|
||||
{
|
||||
return (ordered_index_node_impl*)(void*)(*r&~uintptr_type(1));
|
||||
return (pointer)(void*)(*r&~uintptr_type(1));
|
||||
}
|
||||
|
||||
parent_ref& operator=(ordered_index_node_impl* p)
|
||||
parent_ref& operator=(pointer p)
|
||||
{
|
||||
*r=((uintptr_type)(void*)p)|(*r&uintptr_type(1));
|
||||
return *this;
|
||||
@@ -137,68 +169,92 @@ struct ordered_index_node_compressed_base
|
||||
|
||||
parent_ref& operator=(const parent_ref& x)
|
||||
{
|
||||
return operator=(x.operator ordered_index_node_impl*());
|
||||
return operator=(x.operator pointer());
|
||||
}
|
||||
|
||||
ordered_index_node_impl* operator->()const
|
||||
pointer operator->()const
|
||||
{
|
||||
return operator ordered_index_node_impl*();
|
||||
return operator pointer();
|
||||
}
|
||||
|
||||
private:
|
||||
uintptr_type* r;
|
||||
};
|
||||
|
||||
color_ref color(){return color_ref(&parentcolor_);}
|
||||
ordered_index_color color()const
|
||||
color_ref color(){return color_ref(&parentcolor_);}
|
||||
ordered_index_color color()const
|
||||
{
|
||||
return ordered_index_color(parentcolor_&std::size_t(1ul));
|
||||
}
|
||||
|
||||
parent_ref parent(){return parent_ref(&parentcolor_);}
|
||||
ordered_index_node_impl* parent()const
|
||||
parent_ref parent(){return parent_ref(&parentcolor_);}
|
||||
pointer parent()const
|
||||
{
|
||||
return (ordered_index_node_impl*)(void*)(parentcolor_&~uintptr_type(1));
|
||||
return (pointer)(void*)(parentcolor_&~uintptr_type(1));
|
||||
}
|
||||
|
||||
ordered_index_node_impl*& left(){return left_;}
|
||||
ordered_index_node_impl* left()const{return left_;}
|
||||
ordered_index_node_impl*& right(){return right_;}
|
||||
ordered_index_node_impl* right()const{return right_;}
|
||||
pointer& left(){return left_;}
|
||||
pointer left()const{return left_;}
|
||||
pointer& right(){return right_;}
|
||||
pointer right()const{return right_;}
|
||||
|
||||
private:
|
||||
ordered_index_node_compressed_base();
|
||||
|
||||
uintptr_type parentcolor_;
|
||||
ordered_index_node_impl* left_;
|
||||
ordered_index_node_impl* right_;
|
||||
uintptr_type parentcolor_;
|
||||
pointer left_;
|
||||
pointer right_;
|
||||
};
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct ordered_index_node_impl:
|
||||
template<typename Allocator>
|
||||
struct ordered_index_node_impl_base:
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
|
||||
mpl::if_c<
|
||||
!(has_uintptr_type::value)||
|
||||
(alignment_of<ordered_index_node_compressed_base>::value%2),
|
||||
ordered_index_node_std_base,
|
||||
ordered_index_node_compressed_base
|
||||
(alignment_of<ordered_index_node_compressed_base<Allocator> >::value%2)||
|
||||
!(is_same<
|
||||
typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
ordered_index_node_impl<Allocator>
|
||||
>::type
|
||||
>::type::pointer,
|
||||
ordered_index_node_impl<Allocator>*>::value),
|
||||
ordered_index_node_std_base<Allocator>,
|
||||
ordered_index_node_compressed_base<Allocator>
|
||||
>::type
|
||||
#else
|
||||
ordered_index_node_std_base
|
||||
ordered_index_node_std_base<Allocator>
|
||||
#endif
|
||||
|
||||
{};
|
||||
|
||||
template<typename Allocator>
|
||||
struct ordered_index_node_impl:ordered_index_node_impl_base<Allocator>
|
||||
{
|
||||
private:
|
||||
typedef ordered_index_node_impl_base<Allocator> super;
|
||||
|
||||
public:
|
||||
typedef typename super::color_ref color_ref;
|
||||
typedef typename super::parent_ref parent_ref;
|
||||
typedef typename super::pointer pointer;
|
||||
typedef typename super::const_pointer const_pointer;
|
||||
|
||||
/* interoperability with bidir_node_iterator */
|
||||
|
||||
static void increment(ordered_index_node_impl*& x)
|
||||
static void increment(pointer& x)
|
||||
{
|
||||
if(x->right()){
|
||||
if(x->right()!=pointer(0)){
|
||||
x=x->right();
|
||||
while(x->left())x=x->left();
|
||||
while(x->left()!=pointer(0))x=x->left();
|
||||
}
|
||||
else{
|
||||
ordered_index_node_impl* y=x->parent();
|
||||
pointer y=x->parent();
|
||||
while(x==y->right()){
|
||||
x=y;
|
||||
y=y->parent();
|
||||
@@ -207,17 +263,17 @@ struct ordered_index_node_impl:
|
||||
}
|
||||
}
|
||||
|
||||
static void decrement(ordered_index_node_impl*& x)
|
||||
static void decrement(pointer& x)
|
||||
{
|
||||
if(x->color()==red&&x->parent()->parent()==x){
|
||||
x=x->right();
|
||||
}
|
||||
else if(x->left()){
|
||||
ordered_index_node_impl* y=x->left();
|
||||
while(y->right())y=y->right();
|
||||
else if(x->left()!=pointer(0)){
|
||||
pointer y=x->left();
|
||||
while(y->right()!=pointer(0))y=y->right();
|
||||
x=y;
|
||||
}else{
|
||||
ordered_index_node_impl* y=x->parent();
|
||||
pointer y=x->parent();
|
||||
while(x==y->left()){
|
||||
x=y;
|
||||
y=y->parent();
|
||||
@@ -228,12 +284,11 @@ struct ordered_index_node_impl:
|
||||
|
||||
/* algorithmic stuff */
|
||||
|
||||
static void rotate_left(
|
||||
ordered_index_node_impl* x,parent_ref root)
|
||||
static void rotate_left(pointer x,parent_ref root)
|
||||
{
|
||||
ordered_index_node_impl* y=x->right();
|
||||
pointer y=x->right();
|
||||
x->right()=y->left();
|
||||
if(y->left())y->left()->parent()=x;
|
||||
if(y->left()!=pointer(0))y->left()->parent()=x;
|
||||
y->parent()=x->parent();
|
||||
|
||||
if(x==root) root=y;
|
||||
@@ -243,24 +298,23 @@ struct ordered_index_node_impl:
|
||||
x->parent()=y;
|
||||
}
|
||||
|
||||
static ordered_index_node_impl* minimum(ordered_index_node_impl* x)
|
||||
static pointer minimum(pointer x)
|
||||
{
|
||||
while(x->left())x=x->left();
|
||||
while(x->left()!=pointer(0))x=x->left();
|
||||
return x;
|
||||
}
|
||||
|
||||
static ordered_index_node_impl* maximum(ordered_index_node_impl* x)
|
||||
static pointer maximum(pointer x)
|
||||
{
|
||||
while(x->right())x=x->right();
|
||||
while(x->right()!=pointer(0))x=x->right();
|
||||
return x;
|
||||
}
|
||||
|
||||
static void rotate_right(
|
||||
ordered_index_node_impl* x,parent_ref root)
|
||||
static void rotate_right(pointer x,parent_ref root)
|
||||
{
|
||||
ordered_index_node_impl* y=x->left();
|
||||
pointer y=x->left();
|
||||
x->left()=y->right();
|
||||
if(y->right())y->right()->parent()=x;
|
||||
if(y->right()!=pointer(0))y->right()->parent()=x;
|
||||
y->parent()=x->parent();
|
||||
|
||||
if(x==root) root=y;
|
||||
@@ -270,14 +324,13 @@ struct ordered_index_node_impl:
|
||||
x->parent()=y;
|
||||
}
|
||||
|
||||
static void rebalance(
|
||||
ordered_index_node_impl* x,parent_ref root)
|
||||
static void rebalance(pointer x,parent_ref root)
|
||||
{
|
||||
x->color()=red;
|
||||
while(x!=root&&x->parent()->color()==red){
|
||||
if(x->parent()==x->parent()->parent()->left()){
|
||||
ordered_index_node_impl* y=x->parent()->parent()->right();
|
||||
if(y&&y->color()==red){
|
||||
pointer y=x->parent()->parent()->right();
|
||||
if(y!=pointer(0)&&y->color()==red){
|
||||
x->parent()->color()=black;
|
||||
y->color()=black;
|
||||
x->parent()->parent()->color()=red;
|
||||
@@ -294,8 +347,8 @@ struct ordered_index_node_impl:
|
||||
}
|
||||
}
|
||||
else{
|
||||
ordered_index_node_impl* y=x->parent()->parent()->left();
|
||||
if(y&&y->color()==red){
|
||||
pointer y=x->parent()->parent()->left();
|
||||
if(y!=pointer(0)&&y->color()==red){
|
||||
x->parent()->color()=black;
|
||||
y->color()=black;
|
||||
x->parent()->parent()->color()=red;
|
||||
@@ -316,9 +369,7 @@ struct ordered_index_node_impl:
|
||||
}
|
||||
|
||||
static void link(
|
||||
ordered_index_node_impl* x,
|
||||
ordered_index_side side,ordered_index_node_impl* position,
|
||||
ordered_index_node_impl* header)
|
||||
pointer x,ordered_index_side side,pointer position,pointer header)
|
||||
{
|
||||
if(side==to_left){
|
||||
position->left()=x; /* also makes leftmost=x when parent==header */
|
||||
@@ -337,28 +388,27 @@ struct ordered_index_node_impl:
|
||||
}
|
||||
}
|
||||
x->parent()=position;
|
||||
x->left()=0;
|
||||
x->right()=0;
|
||||
x->left()=pointer(0);
|
||||
x->right()=pointer(0);
|
||||
ordered_index_node_impl::rebalance(x,header->parent());
|
||||
}
|
||||
|
||||
static ordered_index_node_impl* rebalance_for_erase(
|
||||
ordered_index_node_impl* z,parent_ref root,
|
||||
ordered_index_node_impl*& leftmost,ordered_index_node_impl*& rightmost)
|
||||
static pointer rebalance_for_erase(
|
||||
pointer z,parent_ref root,pointer& leftmost,pointer& rightmost)
|
||||
{
|
||||
ordered_index_node_impl* y=z;
|
||||
ordered_index_node_impl* x=0;
|
||||
ordered_index_node_impl* x_parent=0;
|
||||
if(y->left()==0){ /* z has at most one non-null child. y==z. */
|
||||
x=y->right(); /* x might be null */
|
||||
pointer y=z;
|
||||
pointer x=pointer(0);
|
||||
pointer x_parent=pointer(0);
|
||||
if(y->left()==pointer(0)){ /* z has at most one non-null child. y==z. */
|
||||
x=y->right(); /* x might be null */
|
||||
}
|
||||
else{
|
||||
if(y->right()==0) { /* z has exactly one non-null child. y==z. */
|
||||
x=y->left(); /* x is not null */
|
||||
if(y->right()==pointer(0)){ /* z has exactly one non-null child. y==z. */
|
||||
x=y->left(); /* x is not null */
|
||||
}
|
||||
else{ /* z has two non-null children. Set y to */
|
||||
y=y->right(); /* z's successor. x might be null. */
|
||||
while(y->left())y=y->left();
|
||||
else{ /* z has two non-null children. Set y to */
|
||||
y=y->right(); /* z's successor. x might be null. */
|
||||
while(y->left()!=pointer(0))y=y->left();
|
||||
x=y->right();
|
||||
}
|
||||
}
|
||||
@@ -367,7 +417,7 @@ struct ordered_index_node_impl:
|
||||
y->left()=z->left();
|
||||
if(y!=z->right()){
|
||||
x_parent=y->parent();
|
||||
if(x) x->parent()=y->parent();
|
||||
if(x!=pointer(0))x->parent()=y->parent();
|
||||
y->parent()->left()=x; /* y must be a child of left */
|
||||
y->right()=z->right();
|
||||
z->right()->parent()=y;
|
||||
@@ -387,7 +437,7 @@ struct ordered_index_node_impl:
|
||||
}
|
||||
else{ /* y==z */
|
||||
x_parent=y->parent();
|
||||
if(x)x->parent()=y->parent();
|
||||
if(x!=pointer(0))x->parent()=y->parent();
|
||||
if(root==z){
|
||||
root=x;
|
||||
}
|
||||
@@ -396,15 +446,15 @@ struct ordered_index_node_impl:
|
||||
else z->parent()->right()=x;
|
||||
}
|
||||
if(leftmost==z){
|
||||
if(z->right()==0){ /* z->left() must be null also */
|
||||
if(z->right()==pointer(0)){ /* z->left() must be null also */
|
||||
leftmost=z->parent();
|
||||
}
|
||||
else{
|
||||
leftmost=minimum(x); /* makes leftmost==header if z==root */
|
||||
leftmost=minimum(x); /* makes leftmost==header if z==root */
|
||||
}
|
||||
}
|
||||
if(rightmost==z){
|
||||
if(z->left()==0){ /* z->right() must be null also */
|
||||
if(z->left()==pointer(0)){ /* z->right() must be null also */
|
||||
rightmost=z->parent();
|
||||
}
|
||||
else{ /* x==z->left() */
|
||||
@@ -413,75 +463,73 @@ struct ordered_index_node_impl:
|
||||
}
|
||||
}
|
||||
if(y->color()!=red){
|
||||
while(x!=root&&(x==0 || x->color()==black)){
|
||||
while(x!=root&&(x==pointer(0)|| x->color()==black)){
|
||||
if(x==x_parent->left()){
|
||||
ordered_index_node_impl* w=x_parent->right();
|
||||
pointer w=x_parent->right();
|
||||
if(w->color()==red){
|
||||
w->color()=black;
|
||||
x_parent->color()=red;
|
||||
rotate_left(x_parent,root);
|
||||
w=x_parent->right();
|
||||
}
|
||||
if((w->left()==0||w->left()->color()==black) &&
|
||||
(w->right()==0||w->right()->color()==black)){
|
||||
if((w->left()==pointer(0)||w->left()->color()==black) &&
|
||||
(w->right()==pointer(0)||w->right()->color()==black)){
|
||||
w->color()=red;
|
||||
x=x_parent;
|
||||
x_parent=x_parent->parent();
|
||||
}
|
||||
else{
|
||||
if(w->right()==0
|
||||
if(w->right()==pointer(0 )
|
||||
|| w->right()->color()==black){
|
||||
if(w->left()) w->left()->color()=black;
|
||||
if(w->left()!=pointer(0)) w->left()->color()=black;
|
||||
w->color()=red;
|
||||
rotate_right(w,root);
|
||||
w=x_parent->right();
|
||||
}
|
||||
w->color()=x_parent->color();
|
||||
x_parent->color()=black;
|
||||
if(w->right())w->right()->color()=black;
|
||||
if(w->right()!=pointer(0))w->right()->color()=black;
|
||||
rotate_left(x_parent,root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{ /* same as above,with right <-> left */
|
||||
ordered_index_node_impl* w=x_parent->left();
|
||||
pointer w=x_parent->left();
|
||||
if(w->color()==red){
|
||||
w->color()=black;
|
||||
x_parent->color()=red;
|
||||
rotate_right(x_parent,root);
|
||||
w=x_parent->left();
|
||||
}
|
||||
if((w->right()==0||w->right()->color()==black) &&
|
||||
(w->left()==0||w->left()->color()==black)){
|
||||
if((w->right()==pointer(0)||w->right()->color()==black) &&
|
||||
(w->left()==pointer(0)||w->left()->color()==black)){
|
||||
w->color()=red;
|
||||
x=x_parent;
|
||||
x_parent=x_parent->parent();
|
||||
}
|
||||
else{
|
||||
if(w->left()==0||w->left()->color()==black){
|
||||
if(w->right())w->right()->color()=black;
|
||||
if(w->left()==pointer(0)||w->left()->color()==black){
|
||||
if(w->right()!=pointer(0))w->right()->color()=black;
|
||||
w->color()=red;
|
||||
rotate_left(w,root);
|
||||
w=x_parent->left();
|
||||
}
|
||||
w->color()=x_parent->color();
|
||||
x_parent->color()=black;
|
||||
if(w->left())w->left()->color()=black;
|
||||
if(w->left()!=pointer(0))w->left()->color()=black;
|
||||
rotate_right(x_parent,root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(x)x->color()=black;
|
||||
if(x!=pointer(0))x->color()=black;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
static void restore(
|
||||
ordered_index_node_impl* x,ordered_index_node_impl* position,
|
||||
ordered_index_node_impl* header)
|
||||
static void restore(pointer x,pointer position,pointer header)
|
||||
{
|
||||
if(position->left()==0||position->left()==header){
|
||||
if(position->left()==pointer(0)||position->left()==header){
|
||||
link(x,to_left,position,header);
|
||||
}
|
||||
else{
|
||||
@@ -493,10 +541,9 @@ struct ordered_index_node_impl:
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
||||
/* invariant stuff */
|
||||
|
||||
static std::size_t black_count(
|
||||
ordered_index_node_impl* node,ordered_index_node_impl* root)
|
||||
static std::size_t black_count(pointer node,pointer root)
|
||||
{
|
||||
if(!node)return 0;
|
||||
if(node==pointer(0))return 0;
|
||||
std::size_t sum=0;
|
||||
for(;;){
|
||||
if(node->color()==black)++sum;
|
||||
@@ -509,54 +556,87 @@ struct ordered_index_node_impl:
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct ordered_index_node_trampoline:ordered_index_node_impl{};
|
||||
struct ordered_index_node_trampoline:
|
||||
prevent_eti<
|
||||
Super,
|
||||
ordered_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typename Super::allocator_type,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type
|
||||
{
|
||||
typedef typename prevent_eti<
|
||||
Super,
|
||||
ordered_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typename Super::allocator_type,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type impl_type;
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct ordered_index_node:Super,ordered_index_node_trampoline<Super>
|
||||
{
|
||||
private:
|
||||
typedef ordered_index_node_trampoline<Super> impl_type;
|
||||
typedef typename impl_type::color_ref color_ref;
|
||||
typedef typename impl_type::parent_ref parent_ref;
|
||||
typedef ordered_index_node_trampoline<Super> trampoline;
|
||||
|
||||
public:
|
||||
color_ref color(){return impl_type::color();}
|
||||
ordered_index_color color()const{return impl_type::color();}
|
||||
parent_ref parent(){return impl_type::parent();}
|
||||
ordered_index_node_impl* parent()const{return impl_type::parent();}
|
||||
ordered_index_node_impl*& left(){return impl_type::left();}
|
||||
ordered_index_node_impl* left()const{return impl_type::left();}
|
||||
ordered_index_node_impl*& right(){return impl_type::right();}
|
||||
ordered_index_node_impl* right()const{return impl_type::right();}
|
||||
typedef typename trampoline::impl_type impl_type;
|
||||
typedef typename trampoline::color_ref impl_color_ref;
|
||||
typedef typename trampoline::parent_ref impl_parent_ref;
|
||||
typedef typename trampoline::pointer impl_pointer;
|
||||
typedef typename trampoline::const_pointer const_impl_pointer;
|
||||
|
||||
ordered_index_node_impl* impl(){return static_cast<impl_type*>(this);}
|
||||
const ordered_index_node_impl* impl()const
|
||||
{return static_cast<const impl_type*>(this);}
|
||||
impl_color_ref color(){return trampoline::color();}
|
||||
ordered_index_color color()const{return trampoline::color();}
|
||||
impl_parent_ref parent(){return trampoline::parent();}
|
||||
impl_pointer parent()const{return trampoline::parent();}
|
||||
impl_pointer& left(){return trampoline::left();}
|
||||
impl_pointer left()const{return trampoline::left();}
|
||||
impl_pointer& right(){return trampoline::right();}
|
||||
impl_pointer right()const{return trampoline::right();}
|
||||
|
||||
static ordered_index_node* from_impl(ordered_index_node_impl *x)
|
||||
impl_pointer impl()
|
||||
{
|
||||
return static_cast<ordered_index_node*>(static_cast<impl_type*>(x));
|
||||
return static_cast<impl_pointer>(
|
||||
static_cast<impl_type*>(static_cast<trampoline*>(this)));
|
||||
}
|
||||
|
||||
static const ordered_index_node* from_impl(const ordered_index_node_impl* x)
|
||||
|
||||
const_impl_pointer impl()const
|
||||
{
|
||||
return static_cast<const_impl_pointer>(
|
||||
static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
|
||||
}
|
||||
|
||||
static ordered_index_node* from_impl(impl_pointer x)
|
||||
{
|
||||
return static_cast<ordered_index_node*>(
|
||||
static_cast<trampoline*>(&*x));
|
||||
}
|
||||
|
||||
static const ordered_index_node* from_impl(const_impl_pointer x)
|
||||
{
|
||||
return static_cast<const ordered_index_node*>(
|
||||
static_cast<const impl_type*>(x));
|
||||
static_cast<const trampoline*>(&*x));
|
||||
}
|
||||
|
||||
/* interoperability with bidir_node_iterator */
|
||||
|
||||
static void increment(ordered_index_node*& x)
|
||||
{
|
||||
ordered_index_node_impl* xi=x->impl();
|
||||
impl_type::increment(xi);
|
||||
impl_pointer xi=x->impl();
|
||||
trampoline::increment(xi);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
|
||||
static void decrement(ordered_index_node*& x)
|
||||
{
|
||||
ordered_index_node_impl* xi=x->impl();
|
||||
impl_type::decrement(xi);
|
||||
impl_pointer xi=x->impl();
|
||||
trampoline::decrement(xi);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -40,6 +40,9 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <utility>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
@@ -55,21 +58,20 @@ template<
|
||||
typename CompatibleKey,typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_find(
|
||||
Node* header,const KeyFromValue& key,const CompatibleKey& x,
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp)
|
||||
{
|
||||
Node* y=header;
|
||||
Node* z=Node::from_impl(header->parent());
|
||||
|
||||
while (z){
|
||||
if(!comp(key(z->value()),x)){
|
||||
y=z;
|
||||
z=Node::from_impl(z->left());
|
||||
Node* y0=y;
|
||||
|
||||
while (top){
|
||||
if(!comp(key(top->value()),x)){
|
||||
y=top;
|
||||
top=Node::from_impl(top->left());
|
||||
}
|
||||
else z=Node::from_impl(z->right());
|
||||
else top=Node::from_impl(top->right());
|
||||
}
|
||||
|
||||
return (y==header||comp(x,key(y->value())))?header:y;
|
||||
return (y==y0||comp(x,key(y->value())))?y0:y;
|
||||
}
|
||||
|
||||
template<
|
||||
@@ -77,18 +79,15 @@ template<
|
||||
typename CompatibleKey,typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_lower_bound(
|
||||
Node* header,const KeyFromValue& key,const CompatibleKey& x,
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp)
|
||||
{
|
||||
Node* y=header;
|
||||
Node* z=Node::from_impl(header->parent());
|
||||
|
||||
while(z){
|
||||
if(!comp(key(z->value()),x)){
|
||||
y=z;
|
||||
z=Node::from_impl(z->left());
|
||||
while(top){
|
||||
if(!comp(key(top->value()),x)){
|
||||
y=top;
|
||||
top=Node::from_impl(top->left());
|
||||
}
|
||||
else z=Node::from_impl(z->right());
|
||||
else top=Node::from_impl(top->right());
|
||||
}
|
||||
|
||||
return y;
|
||||
@@ -99,23 +98,46 @@ template<
|
||||
typename CompatibleKey,typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_upper_bound(
|
||||
Node* header,const KeyFromValue& key,const CompatibleKey& x,
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp)
|
||||
{
|
||||
Node* y=header;
|
||||
Node* z=Node::from_impl(header->parent());
|
||||
|
||||
while(z){
|
||||
if(comp(x,key(z->value()))){
|
||||
y=z;
|
||||
z=Node::from_impl(z->left());
|
||||
while(top){
|
||||
if(comp(x,key(top->value()))){
|
||||
y=top;
|
||||
top=Node::from_impl(top->left());
|
||||
}
|
||||
else z=Node::from_impl(z->right());
|
||||
else top=Node::from_impl(top->right());
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleKey,typename CompatibleCompare
|
||||
>
|
||||
inline std::pair<Node*,Node*> ordered_index_equal_range(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp)
|
||||
{
|
||||
while(top){
|
||||
if(comp(key(top->value()),x)){
|
||||
top=Node::from_impl(top->right());
|
||||
}
|
||||
else if(comp(x,key(top->value()))){
|
||||
y=top;
|
||||
top=Node::from_impl(top->left());
|
||||
}
|
||||
else{
|
||||
return std::pair<Node*,Node*>(
|
||||
ordered_index_lower_bound(Node::from_impl(top->left()),top,key,x,comp),
|
||||
ordered_index_upper_bound(Node::from_impl(top->right()),y,key,x,comp));
|
||||
}
|
||||
}
|
||||
|
||||
return std::pair<Node*,Node*>(y,y);
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,7 +15,9 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
#include <boost/multi_index/detail/rnd_index_ptr_array.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <cstddef>
|
||||
@@ -43,10 +45,19 @@ template<typename Allocator>
|
||||
class random_access_index_loader_base:private noncopyable
|
||||
{
|
||||
protected:
|
||||
typedef random_access_index_node_impl node_type;
|
||||
typedef random_access_index_ptr_array<Allocator> ptr_array_type;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
random_access_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type node_impl_type;
|
||||
typedef typename node_impl_type::pointer node_impl_pointer;
|
||||
typedef random_access_index_ptr_array<Allocator> ptr_array;
|
||||
|
||||
random_access_index_loader_base(const Allocator& al_,ptr_array_type& ptrs_):
|
||||
random_access_index_loader_base(const Allocator& al_,ptr_array& ptrs_):
|
||||
al(al_),
|
||||
ptrs(ptrs_),
|
||||
header(*ptrs.end()),
|
||||
@@ -58,14 +69,14 @@ protected:
|
||||
{
|
||||
if(preprocessed)
|
||||
{
|
||||
node_type* n=header;
|
||||
node_impl_pointer n=header;
|
||||
next(n)=n;
|
||||
|
||||
for(std::size_t i=ptrs.size();i--;){
|
||||
n=prev(n);
|
||||
std::size_t d=position(n);
|
||||
if(d!=i){
|
||||
node_type* m=prev(next_at(i));
|
||||
node_impl_pointer m=prev(next_at(i));
|
||||
std::swap(m->up(),n->up());
|
||||
next_at(d)=next_at(i);
|
||||
std::swap(prev_at(d),prev_at(i));
|
||||
@@ -75,10 +86,10 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
void rearrange(node_type* position,node_type *x)
|
||||
void rearrange(node_impl_pointer position,node_impl_pointer x)
|
||||
{
|
||||
preprocess(); /* only incur this penalty if rearrange() is ever called */
|
||||
if(!position)position=header;
|
||||
if(position==node_impl_pointer(0))position=header;
|
||||
next(prev(x))=next(x);
|
||||
prev(next(x))=prev(x);
|
||||
prev(x)=position;
|
||||
@@ -91,49 +102,50 @@ private:
|
||||
{
|
||||
if(!preprocessed){
|
||||
/* get space for the auxiliary prev array */
|
||||
auto_space<node_type*,Allocator> tmp(al,ptrs.size()+1);
|
||||
auto_space<node_impl_pointer,Allocator> tmp(al,ptrs.size()+1);
|
||||
prev_spc.swap(tmp);
|
||||
|
||||
/* prev_spc elements point to the prev nodes */
|
||||
std::rotate_copy(ptrs.begin(),ptrs.end(),ptrs.end()+1,prev_spc.data());
|
||||
std::rotate_copy(
|
||||
&*ptrs.begin(),&*ptrs.end(),&*ptrs.end()+1,&*prev_spc.data());
|
||||
|
||||
/* ptrs elements point to the next nodes */
|
||||
std::rotate(ptrs.begin(),ptrs.begin()+1,ptrs.end()+1);
|
||||
std::rotate(&*ptrs.begin(),&*ptrs.begin()+1,&*ptrs.end()+1);
|
||||
|
||||
preprocessed=true;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t position(node_type* x)const
|
||||
std::size_t position(node_impl_pointer x)const
|
||||
{
|
||||
return (std::size_t)(x->up()-ptrs.begin());
|
||||
}
|
||||
|
||||
node_type*& next_at(std::size_t n)const
|
||||
node_impl_pointer& next_at(std::size_t n)const
|
||||
{
|
||||
return *ptrs.at(n);
|
||||
}
|
||||
|
||||
node_type*& prev_at(std::size_t n)const
|
||||
node_impl_pointer& prev_at(std::size_t n)const
|
||||
{
|
||||
return prev_spc.data()[n];
|
||||
return *(prev_spc.data()+n);
|
||||
}
|
||||
|
||||
node_type*& next(node_type* x)const
|
||||
node_impl_pointer& next(node_impl_pointer x)const
|
||||
{
|
||||
return *(x->up());
|
||||
}
|
||||
|
||||
node_type*& prev(node_type* x)const
|
||||
node_impl_pointer& prev(node_impl_pointer x)const
|
||||
{
|
||||
return prev_at(position(x));
|
||||
}
|
||||
|
||||
Allocator al;
|
||||
ptr_array_type& ptrs;
|
||||
node_type* header;
|
||||
auto_space<node_type*,Allocator> prev_spc;
|
||||
bool preprocessed;
|
||||
Allocator al;
|
||||
ptr_array& ptrs;
|
||||
node_impl_pointer header;
|
||||
auto_space<node_impl_pointer,Allocator> prev_spc;
|
||||
bool preprocessed;
|
||||
};
|
||||
|
||||
template<typename Node,typename Allocator>
|
||||
@@ -141,16 +153,17 @@ class random_access_index_loader:
|
||||
private random_access_index_loader_base<Allocator>
|
||||
{
|
||||
typedef random_access_index_loader_base<Allocator> super;
|
||||
typedef typename super::ptr_array_type ptr_array_type;
|
||||
typedef typename super::node_impl_pointer node_impl_pointer;
|
||||
typedef typename super::ptr_array ptr_array;
|
||||
|
||||
public:
|
||||
random_access_index_loader(const Allocator& al_,ptr_array_type& ptrs_):
|
||||
random_access_index_loader(const Allocator& al_,ptr_array& ptrs_):
|
||||
super(al_,ptrs_)
|
||||
{}
|
||||
|
||||
void rearrange(Node* position,Node *x)
|
||||
{
|
||||
super::rearrange(position?position->impl():0,x->impl());
|
||||
super::rearrange(position?position->impl():node_impl_pointer(0),x->impl());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,7 +15,9 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/math/common_factor_rt.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
||||
@@ -25,42 +27,58 @@ namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename Allocator>
|
||||
struct random_access_index_node_impl
|
||||
{
|
||||
random_access_index_node_impl**& up(){return up_;}
|
||||
random_access_index_node_impl** up()const{return up_;}
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,random_access_index_node_impl
|
||||
>::type
|
||||
>::type::pointer pointer;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,random_access_index_node_impl
|
||||
>::type
|
||||
>::type::const_pointer const_pointer;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,pointer
|
||||
>::type
|
||||
>::type::pointer ptr_pointer;
|
||||
|
||||
ptr_pointer& up(){return up_;}
|
||||
ptr_pointer up()const{return up_;}
|
||||
|
||||
/* interoperability with rnd_node_iterator */
|
||||
|
||||
static void increment(random_access_index_node_impl*& x)
|
||||
static void increment(pointer& x)
|
||||
{
|
||||
x=*(x->up()+1);
|
||||
}
|
||||
|
||||
static void decrement(random_access_index_node_impl*& x)
|
||||
static void decrement(pointer& x)
|
||||
{
|
||||
x=*(x->up()-1);
|
||||
}
|
||||
|
||||
static void advance(
|
||||
random_access_index_node_impl*& x,std::ptrdiff_t n)
|
||||
static void advance(pointer& x,std::ptrdiff_t n)
|
||||
{
|
||||
x=*(x->up()+n);
|
||||
}
|
||||
|
||||
static std::ptrdiff_t distance(
|
||||
random_access_index_node_impl* x,random_access_index_node_impl* y)
|
||||
static std::ptrdiff_t distance(pointer x,pointer y)
|
||||
{
|
||||
return y->up()-x->up();
|
||||
}
|
||||
|
||||
/* algorithmic stuff */
|
||||
|
||||
static void relocate(
|
||||
random_access_index_node_impl** pos,
|
||||
random_access_index_node_impl** x)
|
||||
static void relocate(ptr_pointer pos,ptr_pointer x)
|
||||
{
|
||||
random_access_index_node_impl* n=*x;
|
||||
pointer n=*x;
|
||||
if(x<pos){
|
||||
extract(x,pos);
|
||||
*(pos-1)=n;
|
||||
@@ -77,12 +95,9 @@ struct random_access_index_node_impl
|
||||
}
|
||||
};
|
||||
|
||||
static void relocate(
|
||||
random_access_index_node_impl** pos,
|
||||
random_access_index_node_impl** first,
|
||||
random_access_index_node_impl** last)
|
||||
static void relocate(ptr_pointer pos,ptr_pointer first,ptr_pointer last)
|
||||
{
|
||||
random_access_index_node_impl** begin,**middle,**end;
|
||||
ptr_pointer begin,middle,end;
|
||||
if(pos<first){
|
||||
begin=pos;
|
||||
middle=first;
|
||||
@@ -100,38 +115,36 @@ struct random_access_index_node_impl
|
||||
std::ptrdiff_t p=math::gcd(n,m);
|
||||
|
||||
for(std::ptrdiff_t i=0;i<p;++i){
|
||||
random_access_index_node_impl* tmp=begin[i];
|
||||
pointer tmp=begin[i];
|
||||
for(std::ptrdiff_t j=i,k;;){
|
||||
if(j<n_m)k=j+m;
|
||||
else k=j-n_m;
|
||||
if(k==i){
|
||||
begin[j]=tmp;
|
||||
begin[j]->up()=&begin[j];
|
||||
*(begin+j)=tmp;
|
||||
(*(begin+j))->up()=begin+j;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
begin[j]=begin[k];
|
||||
begin[j]->up()=&begin[j];
|
||||
*(begin+j)=*(begin+k);
|
||||
(*(begin+j))->up()=begin+j;
|
||||
}
|
||||
|
||||
if(k<n_m)j=k+m;
|
||||
else j=k-n_m;
|
||||
if(j==i){
|
||||
begin[k]=tmp;
|
||||
begin[k]->up()=&begin[k];
|
||||
*(begin+k)=tmp;
|
||||
(*(begin+k))->up()=begin+k;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
begin[k]=begin[j];
|
||||
begin[k]->up()=&begin[k];
|
||||
*(begin+k)=*(begin+j);
|
||||
(*(begin+k))->up()=begin+k;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void extract(
|
||||
random_access_index_node_impl** x,
|
||||
random_access_index_node_impl** pend)
|
||||
static void extract(ptr_pointer x,ptr_pointer pend)
|
||||
{
|
||||
--pend;
|
||||
while(x!=pend){
|
||||
@@ -142,9 +155,7 @@ struct random_access_index_node_impl
|
||||
}
|
||||
|
||||
static void transfer(
|
||||
random_access_index_node_impl** pbegin0,
|
||||
random_access_index_node_impl** pend0,
|
||||
random_access_index_node_impl** pbegin1)
|
||||
ptr_pointer pbegin0,ptr_pointer pend0,ptr_pointer pbegin1)
|
||||
{
|
||||
while(pbegin0!=pend0){
|
||||
*pbegin1=*pbegin0++;
|
||||
@@ -153,9 +164,7 @@ struct random_access_index_node_impl
|
||||
}
|
||||
}
|
||||
|
||||
static void reverse(
|
||||
random_access_index_node_impl** pbegin,
|
||||
random_access_index_node_impl** pend)
|
||||
static void reverse(ptr_pointer pbegin,ptr_pointer pend)
|
||||
{
|
||||
std::ptrdiff_t d=(pend-pbegin)/2;
|
||||
for(std::ptrdiff_t i=0;i<d;++i){
|
||||
@@ -167,70 +176,100 @@ struct random_access_index_node_impl
|
||||
}
|
||||
|
||||
private:
|
||||
random_access_index_node_impl();
|
||||
|
||||
random_access_index_node_impl** up_;
|
||||
ptr_pointer up_;
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct random_access_index_node_trampoline:random_access_index_node_impl{};
|
||||
struct random_access_index_node_trampoline:
|
||||
prevent_eti<
|
||||
Super,
|
||||
random_access_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typename Super::allocator_type,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type
|
||||
{
|
||||
typedef typename prevent_eti<
|
||||
Super,
|
||||
random_access_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typename Super::allocator_type,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type impl_type;
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct random_access_index_node:
|
||||
Super,random_access_index_node_trampoline<Super>
|
||||
{
|
||||
random_access_index_node_impl**& up(){return impl_type::up();}
|
||||
random_access_index_node_impl** up()const{return impl_type::up();}
|
||||
private:
|
||||
typedef random_access_index_node_trampoline<Super> trampoline;
|
||||
|
||||
random_access_index_node_impl* impl()
|
||||
{return static_cast<impl_type*>(this);}
|
||||
const random_access_index_node_impl* impl()const
|
||||
{return static_cast<const impl_type*>(this);}
|
||||
public:
|
||||
typedef typename trampoline::impl_type impl_type;
|
||||
typedef typename trampoline::pointer impl_pointer;
|
||||
typedef typename trampoline::const_pointer const_impl_pointer;
|
||||
typedef typename trampoline::ptr_pointer impl_ptr_pointer;
|
||||
|
||||
static random_access_index_node* from_impl(random_access_index_node_impl *x)
|
||||
impl_ptr_pointer& up(){return trampoline::up();}
|
||||
impl_ptr_pointer up()const{return trampoline::up();}
|
||||
|
||||
impl_pointer impl()
|
||||
{
|
||||
return static_cast<random_access_index_node*>(
|
||||
static_cast<impl_type*>(x));
|
||||
return static_cast<impl_pointer>(
|
||||
static_cast<impl_type*>(static_cast<trampoline*>(this)));
|
||||
}
|
||||
|
||||
static const random_access_index_node* from_impl(
|
||||
const random_access_index_node_impl* x)
|
||||
const_impl_pointer impl()const
|
||||
{
|
||||
return static_cast<const_impl_pointer>(
|
||||
static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
|
||||
}
|
||||
|
||||
static random_access_index_node* from_impl(impl_pointer x)
|
||||
{
|
||||
return static_cast<random_access_index_node*>(
|
||||
static_cast<trampoline*>(&*x));
|
||||
}
|
||||
|
||||
static const random_access_index_node* from_impl(const_impl_pointer x)
|
||||
{
|
||||
return static_cast<const random_access_index_node*>(
|
||||
static_cast<const impl_type*>(x));
|
||||
static_cast<const trampoline*>(&*x));
|
||||
}
|
||||
|
||||
/* interoperability with rnd_node_iterator */
|
||||
|
||||
static void increment(random_access_index_node*& x)
|
||||
{
|
||||
random_access_index_node_impl* xi=x->impl();
|
||||
impl_type::increment(xi);
|
||||
impl_pointer xi=x->impl();
|
||||
trampoline::increment(xi);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
|
||||
static void decrement(random_access_index_node*& x)
|
||||
{
|
||||
random_access_index_node_impl* xi=x->impl();
|
||||
impl_type::decrement(xi);
|
||||
impl_pointer xi=x->impl();
|
||||
trampoline::decrement(xi);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
|
||||
static void advance(random_access_index_node*& x,std::ptrdiff_t n)
|
||||
{
|
||||
random_access_index_node_impl* xi=x->impl();
|
||||
impl_type::advance(xi,n);
|
||||
impl_pointer xi=x->impl();
|
||||
trampoline::advance(xi,n);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
|
||||
static std::ptrdiff_t distance(
|
||||
random_access_index_node* x,random_access_index_node* y)
|
||||
{
|
||||
return impl_type::distance(x->impl(),y->impl());
|
||||
return trampoline::distance(x->impl(),y->impl());
|
||||
}
|
||||
|
||||
private:
|
||||
typedef random_access_index_node_trampoline<Super> impl_type;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2009 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -34,10 +34,11 @@ Node* random_access_index_remove(
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
|
||||
{
|
||||
typedef typename Node::value_type value_type;
|
||||
typedef typename Node::impl_ptr_pointer impl_ptr_pointer;
|
||||
|
||||
random_access_index_node_impl** first=ptrs.begin(),
|
||||
** res=first,
|
||||
** last=ptrs.end();
|
||||
impl_ptr_pointer first=ptrs.begin(),
|
||||
res=first,
|
||||
last=ptrs.end();
|
||||
for(;first!=last;++first){
|
||||
if(!pred(
|
||||
const_cast<const value_type&>(Node::from_impl(*first)->value()))){
|
||||
@@ -57,11 +58,12 @@ Node* random_access_index_unique(
|
||||
random_access_index_ptr_array<Allocator>& ptrs,BinaryPredicate binary_pred
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
|
||||
{
|
||||
typedef typename Node::value_type value_type;
|
||||
typedef typename Node::value_type value_type;
|
||||
typedef typename Node::impl_ptr_pointer impl_ptr_pointer;
|
||||
|
||||
random_access_index_node_impl** first=ptrs.begin(),
|
||||
** res=first,
|
||||
** last=ptrs.end();
|
||||
impl_ptr_pointer first=ptrs.begin(),
|
||||
res=first,
|
||||
last=ptrs.end();
|
||||
if(first!=last){
|
||||
for(;++first!=last;){
|
||||
if(!binary_pred(
|
||||
@@ -84,17 +86,19 @@ template<typename Node,typename Allocator,typename Compare>
|
||||
void random_access_index_inplace_merge(
|
||||
const Allocator& al,
|
||||
random_access_index_ptr_array<Allocator>& ptrs,
|
||||
random_access_index_node_impl** first1,Compare comp
|
||||
BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
|
||||
{
|
||||
typedef typename Node::value_type value_type;
|
||||
typedef typename Node::value_type value_type;
|
||||
typedef typename Node::impl_pointer impl_pointer;
|
||||
typedef typename Node::impl_ptr_pointer impl_ptr_pointer;
|
||||
|
||||
auto_space<random_access_index_node_impl*,Allocator> spc(al,ptrs.size());
|
||||
auto_space<impl_pointer,Allocator> spc(al,ptrs.size());
|
||||
|
||||
random_access_index_node_impl** first0=ptrs.begin(),
|
||||
** last0=first1,
|
||||
** last1=ptrs.end(),
|
||||
** out=spc.data();
|
||||
impl_ptr_pointer first0=ptrs.begin(),
|
||||
last0=first1,
|
||||
last1=ptrs.end(),
|
||||
out=spc.data();
|
||||
while(first0!=last0&&first1!=last1){
|
||||
if(comp(
|
||||
const_cast<const value_type&>(Node::from_impl(*first1)->value()),
|
||||
@@ -105,8 +109,8 @@ void random_access_index_inplace_merge(
|
||||
*out++=*first0++;
|
||||
}
|
||||
}
|
||||
std::copy(first0,last0,out);
|
||||
std::copy(first1,last1,out);
|
||||
std::copy(&*first0,&*last0,&*out);
|
||||
std::copy(&*first1,&*last1,&*out);
|
||||
|
||||
first1=ptrs.begin();
|
||||
out=spc.data();
|
||||
@@ -124,13 +128,13 @@ void random_access_index_inplace_merge(
|
||||
template<typename Node,typename Compare>
|
||||
struct random_access_index_sort_compare:
|
||||
std::binary_function<
|
||||
const typename Node::value_type*,const typename Node::value_type*,bool>
|
||||
typename Node::impl_pointer,
|
||||
typename Node::impl_pointer,bool>
|
||||
{
|
||||
random_access_index_sort_compare(Compare comp_=Compare()):comp(comp_){}
|
||||
|
||||
bool operator()(
|
||||
random_access_index_node_impl* x,
|
||||
random_access_index_node_impl* y)const
|
||||
typename Node::impl_pointer x,typename Node::impl_pointer y)const
|
||||
{
|
||||
typedef typename Node::value_type value_type;
|
||||
|
||||
@@ -170,19 +174,23 @@ void random_access_index_sort(
|
||||
* solution adopted.
|
||||
*/
|
||||
|
||||
if(ptrs.size()<=1)return;
|
||||
|
||||
typedef typename Node::value_type value_type;
|
||||
typedef typename Node::impl_pointer impl_pointer;
|
||||
typedef typename Node::impl_ptr_pointer impl_ptr_pointer;
|
||||
typedef random_access_index_sort_compare<
|
||||
Node,Compare> ptr_compare;
|
||||
|
||||
random_access_index_node_impl** first=ptrs.begin();
|
||||
random_access_index_node_impl** last=ptrs.end();
|
||||
impl_ptr_pointer first=ptrs.begin();
|
||||
impl_ptr_pointer last=ptrs.end();
|
||||
auto_space<
|
||||
random_access_index_node_impl*,
|
||||
Allocator> spc(al,ptrs.size());
|
||||
random_access_index_node_impl** buf=spc.data();
|
||||
impl_pointer,
|
||||
Allocator> spc(al,ptrs.size());
|
||||
impl_ptr_pointer buf=spc.data();
|
||||
|
||||
std::copy(first,last,buf);
|
||||
std::stable_sort(buf,buf+ptrs.size(),ptr_compare(comp));
|
||||
std::copy(&*first,&*last,&*buf);
|
||||
std::stable_sort(&*buf,&*buf+ptrs.size(),ptr_compare(comp));
|
||||
|
||||
while(first!=last){
|
||||
*first=*buf++;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,7 +15,9 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
#include <boost/multi_index/detail/rnd_index_node.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <cstddef>
|
||||
@@ -31,8 +33,24 @@ namespace detail{
|
||||
template<typename Allocator>
|
||||
class random_access_index_ptr_array:private noncopyable
|
||||
{
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
random_access_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type node_impl_type;
|
||||
|
||||
public:
|
||||
typedef random_access_index_node_impl* value_type;
|
||||
typedef typename node_impl_type::pointer value_type;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,value_type
|
||||
>::type
|
||||
>::type::pointer pointer;
|
||||
|
||||
random_access_index_ptr_array(
|
||||
const Allocator& al,value_type end_,std::size_t size):
|
||||
@@ -58,15 +76,15 @@ public:
|
||||
{
|
||||
if(c>capacity_){
|
||||
auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1);
|
||||
random_access_index_node_impl::transfer(begin(),end()+1,spc1.data());
|
||||
node_impl_type::transfer(begin(),end()+1,spc1.data());
|
||||
spc.swap(spc1);
|
||||
capacity_=c;
|
||||
}
|
||||
}
|
||||
|
||||
value_type* begin()const{return &ptrs()[0];}
|
||||
value_type* end()const{return &ptrs()[size_];}
|
||||
value_type* at(std::size_t n)const{return &ptrs()[n];}
|
||||
pointer begin()const{return ptrs();}
|
||||
pointer end()const{return ptrs()+size_;}
|
||||
pointer at(std::size_t n)const{return ptrs()+n;}
|
||||
|
||||
void push_back(value_type x)
|
||||
{
|
||||
@@ -79,7 +97,7 @@ public:
|
||||
|
||||
void erase(value_type x)
|
||||
{
|
||||
random_access_index_node_impl::extract(x->up(),end()+1);
|
||||
node_impl_type::extract(x->up(),end()+1);
|
||||
--size_;
|
||||
}
|
||||
|
||||
@@ -102,7 +120,7 @@ private:
|
||||
std::size_t capacity_;
|
||||
auto_space<value_type,Allocator> spc;
|
||||
|
||||
value_type* ptrs()const
|
||||
pointer ptrs()const
|
||||
{
|
||||
return spc.data();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -29,10 +29,10 @@ namespace detail{
|
||||
|
||||
/* Iterator class for node-based indices with random access iterators. */
|
||||
|
||||
template<typename Node,typename Derived=mpl::na>
|
||||
template<typename Node>
|
||||
class rnd_node_iterator:
|
||||
public random_access_iterator_helper<
|
||||
rnd_node_iterator<Node,Derived>,
|
||||
rnd_node_iterator<Node>,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
const typename Node::value_type*,
|
||||
@@ -47,18 +47,6 @@ public:
|
||||
return node->value();
|
||||
}
|
||||
|
||||
friend bool operator==(
|
||||
const rnd_node_iterator& x,const rnd_node_iterator& y)
|
||||
{
|
||||
return x.node==y.node;
|
||||
}
|
||||
|
||||
friend bool operator<(
|
||||
const rnd_node_iterator& x,const rnd_node_iterator& y)
|
||||
{
|
||||
return Node::distance(x.node,y.node)>0;
|
||||
}
|
||||
|
||||
rnd_node_iterator& operator++()
|
||||
{
|
||||
Node::increment(node);
|
||||
@@ -83,12 +71,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend std::ptrdiff_t operator-(
|
||||
const rnd_node_iterator& x,const rnd_node_iterator& y)
|
||||
{
|
||||
return Node::distance(y.node,x.node);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* Serialization. As for why the following is public,
|
||||
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
|
||||
@@ -99,14 +81,14 @@ public:
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive& ar,const unsigned int version)const
|
||||
void save(Archive& ar,const unsigned int)const
|
||||
{
|
||||
node_base_type* bnode=node;
|
||||
ar<<serialization::make_nvp("pointer",bnode);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int version)
|
||||
void load(Archive& ar,const unsigned int)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
@@ -124,6 +106,30 @@ private:
|
||||
Node* node;
|
||||
};
|
||||
|
||||
template<typename Node>
|
||||
bool operator==(
|
||||
const rnd_node_iterator<Node>& x,
|
||||
const rnd_node_iterator<Node>& y)
|
||||
{
|
||||
return x.get_node()==y.get_node();
|
||||
}
|
||||
|
||||
template<typename Node>
|
||||
bool operator<(
|
||||
const rnd_node_iterator<Node>& x,
|
||||
const rnd_node_iterator<Node>& y)
|
||||
{
|
||||
return Node::distance(x.get_node(),y.get_node())>0;
|
||||
}
|
||||
|
||||
template<typename Node>
|
||||
std::ptrdiff_t operator-(
|
||||
const rnd_node_iterator<Node>& x,
|
||||
const rnd_node_iterator<Node>& y)
|
||||
{
|
||||
return Node::distance(y.get_node(),x.get_node());
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2009 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -237,20 +237,28 @@ template<typename Iterator>
|
||||
inline void detach_equivalent_iterators(Iterator& it)
|
||||
{
|
||||
if(it.valid()){
|
||||
Iterator *prev_,*next_;
|
||||
for(
|
||||
prev_=static_cast<Iterator*>(&it.cont->header);
|
||||
(next_=static_cast<Iterator*>(prev_->next))!=0;){
|
||||
if(next_!=&it&&*next_==it){
|
||||
prev_->next=next_->next;
|
||||
next_->cont=0;
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex);
|
||||
#endif
|
||||
|
||||
Iterator *prev_,*next_;
|
||||
for(
|
||||
prev_=static_cast<Iterator*>(&it.cont->header);
|
||||
(next_=static_cast<Iterator*>(prev_->next))!=0;){
|
||||
if(next_!=&it&&*next_==it){
|
||||
prev_->next=next_->next;
|
||||
next_->cont=0;
|
||||
}
|
||||
else prev_=next_;
|
||||
}
|
||||
else prev_=next_;
|
||||
}
|
||||
it.detach();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Container> class safe_container; /* fwd decl. */
|
||||
|
||||
} /* namespace multi_index::safe_mode */
|
||||
|
||||
namespace detail{
|
||||
@@ -308,6 +316,7 @@ BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
friend class safe_container_base;
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template<typename> friend class safe_mode::safe_container;
|
||||
template<typename Iterator> friend
|
||||
void safe_mode::detach_equivalent_iterators(Iterator&);
|
||||
#endif
|
||||
@@ -324,13 +333,20 @@ class safe_container_base:private noncopyable
|
||||
public:
|
||||
safe_container_base(){}
|
||||
|
||||
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
friend class safe_iterator_base;
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template<typename Iterator> friend
|
||||
void safe_mode::detach_equivalent_iterators(Iterator&);
|
||||
#endif
|
||||
|
||||
~safe_container_base()
|
||||
{
|
||||
detach_all_iterators();
|
||||
}
|
||||
/* Detaches all remaining iterators, which by now will
|
||||
* be those pointing to the end of the container.
|
||||
*/
|
||||
|
||||
void detach_all_iterators()
|
||||
{
|
||||
for(safe_iterator_base* it=header.next;it;it=it->next)it->cont=0;
|
||||
header.next=0;
|
||||
}
|
||||
@@ -343,14 +359,6 @@ public:
|
||||
std::swap(header.next,x.header.next);
|
||||
}
|
||||
|
||||
BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
friend class safe_iterator_base;
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template<typename Iterator> friend
|
||||
void safe_mode::detach_equivalent_iterators(Iterator&);
|
||||
#endif
|
||||
|
||||
safe_iterator_base header;
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
@@ -532,6 +540,23 @@ class safe_container:public detail::safe_container_base
|
||||
typedef detail::safe_container_base super;
|
||||
|
||||
public:
|
||||
void detach_dereferenceable_iterators()
|
||||
{
|
||||
typedef typename Container::iterator iterator;
|
||||
|
||||
iterator end_=static_cast<Container*>(this)->end();
|
||||
iterator *prev_,*next_;
|
||||
for(
|
||||
prev_=static_cast<iterator*>(&this->header);
|
||||
(next_=static_cast<iterator*>(prev_->next))!=0;){
|
||||
if(*next_!=end_){
|
||||
prev_->next=next_->next;
|
||||
next_->cont=0;
|
||||
}
|
||||
else prev_=next_;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(safe_container<Container>& x)
|
||||
{
|
||||
super::swap(x);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -13,6 +13,8 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
@@ -24,12 +26,10 @@ namespace detail{
|
||||
* ScopeGuard.h as defined in:
|
||||
* Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You
|
||||
* Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000,
|
||||
* http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/
|
||||
* http://www.drdobbs.com/184403758
|
||||
* with the following modifications:
|
||||
* - General pretty formatting (pretty to my taste at least.)
|
||||
* - Naming style changed to standard C++ library requirements.
|
||||
* - safe_execute does not feature a try-catch protection, so we can
|
||||
* use this even if BOOST_NO_EXCEPTIONS is defined.
|
||||
* - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex
|
||||
* needs them). A better design would provide guards for many more
|
||||
* arguments through the Boost Preprocessor Library.
|
||||
@@ -42,6 +42,18 @@ namespace detail{
|
||||
*
|
||||
* NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute
|
||||
* without an explicit qualification.
|
||||
*
|
||||
* We also define the following variants of the idiom:
|
||||
*
|
||||
* - make_guard_if_c<bool>( ... )
|
||||
* - make_guard_if<IntegralConstant>( ... )
|
||||
* - make_obj_guard_if_c<bool>( ... )
|
||||
* - make_obj_guard_if<IntegralConstant>( ... )
|
||||
* which may be used with a compile-time constant to yield
|
||||
* a "null_guard" if the boolean compile-time parameter is false,
|
||||
* or conversely, the guard is only constructed if the constant is true.
|
||||
* This is useful to avoid extra tagging, because the returned
|
||||
* null_guard can be optimzed comlpetely away by the compiler.
|
||||
*/
|
||||
|
||||
class scope_guard_impl_base
|
||||
@@ -65,7 +77,13 @@ protected:
|
||||
}
|
||||
|
||||
template<typename J>
|
||||
static void safe_execute(J& j){if(!j.dismissed_)j.execute();}
|
||||
static void safe_execute(J& j){
|
||||
BOOST_TRY{
|
||||
if(!j.dismissed_)j.execute();
|
||||
}
|
||||
BOOST_CATCH(...){}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
mutable bool dismissed_;
|
||||
|
||||
@@ -75,6 +93,35 @@ private:
|
||||
|
||||
typedef const scope_guard_impl_base& scope_guard;
|
||||
|
||||
struct null_guard : public scope_guard_impl_base
|
||||
{
|
||||
template< class T1 >
|
||||
null_guard( const T1& )
|
||||
{ }
|
||||
|
||||
template< class T1, class T2 >
|
||||
null_guard( const T1&, const T2& )
|
||||
{ }
|
||||
|
||||
template< class T1, class T2, class T3 >
|
||||
null_guard( const T1&, const T2&, const T3& )
|
||||
{ }
|
||||
|
||||
template< class T1, class T2, class T3, class T4 >
|
||||
null_guard( const T1&, const T2&, const T3&, const T4& )
|
||||
{ }
|
||||
|
||||
template< class T1, class T2, class T3, class T4, class T5 >
|
||||
null_guard( const T1&, const T2&, const T3&, const T4&, const T5& )
|
||||
{ }
|
||||
};
|
||||
|
||||
template< bool cond, class T >
|
||||
struct null_guard_return
|
||||
{
|
||||
typedef typename boost::mpl::if_c<cond,T,null_guard>::type type;
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
class scope_guard_impl0:public scope_guard_impl_base
|
||||
{
|
||||
@@ -94,6 +141,20 @@ inline scope_guard_impl0<F> make_guard(F fun)
|
||||
return scope_guard_impl0<F>(fun);
|
||||
}
|
||||
|
||||
template<bool cond, typename F>
|
||||
inline typename null_guard_return<cond,scope_guard_impl0<F> >::type
|
||||
make_guard_if_c(F fun)
|
||||
{
|
||||
return typename null_guard_return<cond,scope_guard_impl0<F> >::type(fun);
|
||||
}
|
||||
|
||||
template<typename C, typename F>
|
||||
inline typename null_guard_return<C::value,scope_guard_impl0<F> >::type
|
||||
make_guard_if(F fun)
|
||||
{
|
||||
return make_guard_if<C::value>(fun);
|
||||
}
|
||||
|
||||
template<typename F,typename P1>
|
||||
class scope_guard_impl1:public scope_guard_impl_base
|
||||
{
|
||||
@@ -113,6 +174,20 @@ inline scope_guard_impl1<F,P1> make_guard(F fun,P1 p1)
|
||||
return scope_guard_impl1<F,P1>(fun,p1);
|
||||
}
|
||||
|
||||
template<bool cond, typename F,typename P1>
|
||||
inline typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type
|
||||
make_guard_if_c(F fun,P1 p1)
|
||||
{
|
||||
return typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type(fun,p1);
|
||||
}
|
||||
|
||||
template<typename C, typename F,typename P1>
|
||||
inline typename null_guard_return<C::value,scope_guard_impl1<F,P1> >::type
|
||||
make_guard_if(F fun,P1 p1)
|
||||
{
|
||||
return make_guard_if_c<C::value>(fun,p1);
|
||||
}
|
||||
|
||||
template<typename F,typename P1,typename P2>
|
||||
class scope_guard_impl2:public scope_guard_impl_base
|
||||
{
|
||||
@@ -133,6 +208,20 @@ inline scope_guard_impl2<F,P1,P2> make_guard(F fun,P1 p1,P2 p2)
|
||||
return scope_guard_impl2<F,P1,P2>(fun,p1,p2);
|
||||
}
|
||||
|
||||
template<bool cond, typename F,typename P1,typename P2>
|
||||
inline typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type
|
||||
make_guard_if_c(F fun,P1 p1,P2 p2)
|
||||
{
|
||||
return typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type(fun,p1,p2);
|
||||
}
|
||||
|
||||
template<typename C, typename F,typename P1,typename P2>
|
||||
inline typename null_guard_return<C::value,scope_guard_impl2<F,P1,P2> >::type
|
||||
make_guard_if(F fun,P1 p1,P2 p2)
|
||||
{
|
||||
return make_guard_if_c<C::value>(fun,p1,p2);
|
||||
}
|
||||
|
||||
template<typename F,typename P1,typename P2,typename P3>
|
||||
class scope_guard_impl3:public scope_guard_impl_base
|
||||
{
|
||||
@@ -154,6 +243,20 @@ inline scope_guard_impl3<F,P1,P2,P3> make_guard(F fun,P1 p1,P2 p2,P3 p3)
|
||||
return scope_guard_impl3<F,P1,P2,P3>(fun,p1,p2,p3);
|
||||
}
|
||||
|
||||
template<bool cond,typename F,typename P1,typename P2,typename P3>
|
||||
inline typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type
|
||||
make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3)
|
||||
{
|
||||
return typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type(fun,p1,p2,p3);
|
||||
}
|
||||
|
||||
template<typename C,typename F,typename P1,typename P2,typename P3>
|
||||
inline typename null_guard_return< C::value,scope_guard_impl3<F,P1,P2,P3> >::type
|
||||
make_guard_if(F fun,P1 p1,P2 p2,P3 p3)
|
||||
{
|
||||
return make_guard_if_c<C::value>(fun,p1,p2,p3);
|
||||
}
|
||||
|
||||
template<typename F,typename P1,typename P2,typename P3,typename P4>
|
||||
class scope_guard_impl4:public scope_guard_impl_base
|
||||
{
|
||||
@@ -178,6 +281,22 @@ inline scope_guard_impl4<F,P1,P2,P3,P4> make_guard(
|
||||
return scope_guard_impl4<F,P1,P2,P3,P4>(fun,p1,p2,p3,p4);
|
||||
}
|
||||
|
||||
template<bool cond, typename F,typename P1,typename P2,typename P3,typename P4>
|
||||
inline typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type
|
||||
make_guard_if_c(
|
||||
F fun,P1 p1,P2 p2,P3 p3,P4 p4)
|
||||
{
|
||||
return typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type(fun,p1,p2,p3,p4);
|
||||
}
|
||||
|
||||
template<typename C, typename F,typename P1,typename P2,typename P3,typename P4>
|
||||
inline typename null_guard_return<C::value,scope_guard_impl4<F,P1,P2,P3,P4> >::type
|
||||
make_guard_if(
|
||||
F fun,P1 p1,P2 p2,P3 p3,P4 p4)
|
||||
{
|
||||
return make_guard_if_c<C::value>(fun,p1,p2,p3,p4);
|
||||
}
|
||||
|
||||
template<class Obj,typename MemFun>
|
||||
class obj_scope_guard_impl0:public scope_guard_impl_base
|
||||
{
|
||||
@@ -197,6 +316,20 @@ inline obj_scope_guard_impl0<Obj,MemFun> make_obj_guard(Obj& obj,MemFun mem_fun)
|
||||
return obj_scope_guard_impl0<Obj,MemFun>(obj,mem_fun);
|
||||
}
|
||||
|
||||
template<bool cond, class Obj,typename MemFun>
|
||||
inline typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type
|
||||
make_obj_guard_if_c(Obj& obj,MemFun mem_fun)
|
||||
{
|
||||
return typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type(obj,mem_fun);
|
||||
}
|
||||
|
||||
template<typename C, class Obj,typename MemFun>
|
||||
inline typename null_guard_return<C::value,obj_scope_guard_impl0<Obj,MemFun> >::type
|
||||
make_obj_guard_if(Obj& obj,MemFun mem_fun)
|
||||
{
|
||||
return make_obj_guard_if_c<C::value>(obj,mem_fun);
|
||||
}
|
||||
|
||||
template<class Obj,typename MemFun,typename P1>
|
||||
class obj_scope_guard_impl1:public scope_guard_impl_base
|
||||
{
|
||||
@@ -219,6 +352,20 @@ inline obj_scope_guard_impl1<Obj,MemFun,P1> make_obj_guard(
|
||||
return obj_scope_guard_impl1<Obj,MemFun,P1>(obj,mem_fun,p1);
|
||||
}
|
||||
|
||||
template<bool cond, class Obj,typename MemFun,typename P1>
|
||||
inline typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type
|
||||
make_obj_guard_if_c( Obj& obj,MemFun mem_fun,P1 p1)
|
||||
{
|
||||
return typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type(obj,mem_fun,p1);
|
||||
}
|
||||
|
||||
template<typename C, class Obj,typename MemFun,typename P1>
|
||||
inline typename null_guard_return<C::value,obj_scope_guard_impl1<Obj,MemFun,P1> >::type
|
||||
make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1)
|
||||
{
|
||||
return make_obj_guard_if_c<C::value>(obj,mem_fun,p1);
|
||||
}
|
||||
|
||||
template<class Obj,typename MemFun,typename P1,typename P2>
|
||||
class obj_scope_guard_impl2:public scope_guard_impl_base
|
||||
{
|
||||
@@ -243,6 +390,20 @@ make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
|
||||
return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2);
|
||||
}
|
||||
|
||||
template<bool cond, class Obj,typename MemFun,typename P1,typename P2>
|
||||
inline typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type
|
||||
make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
|
||||
{
|
||||
return typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type(obj,mem_fun,p1,p2);
|
||||
}
|
||||
|
||||
template<typename C, class Obj,typename MemFun,typename P1,typename P2>
|
||||
inline typename null_guard_return<C::value,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type
|
||||
make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
|
||||
{
|
||||
return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2);
|
||||
}
|
||||
|
||||
template<class Obj,typename MemFun,typename P1,typename P2,typename P3>
|
||||
class obj_scope_guard_impl3:public scope_guard_impl_base
|
||||
{
|
||||
@@ -268,6 +429,20 @@ make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
|
||||
return obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>(obj,mem_fun,p1,p2,p3);
|
||||
}
|
||||
|
||||
template<bool cond, class Obj,typename MemFun,typename P1,typename P2,typename P3>
|
||||
inline typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type
|
||||
make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
|
||||
{
|
||||
return typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type(obj,mem_fun,p1,p2,p3);
|
||||
}
|
||||
|
||||
template<typename C, class Obj,typename MemFun,typename P1,typename P2,typename P3>
|
||||
inline typename null_guard_return<C::value,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type
|
||||
make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
|
||||
{
|
||||
return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2,p3);
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -13,7 +13,10 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/multi_index/detail/prevent_eti.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -23,36 +26,48 @@ namespace detail{
|
||||
|
||||
/* doubly-linked node for use by sequenced_index */
|
||||
|
||||
template<typename Allocator>
|
||||
struct sequenced_index_node_impl
|
||||
{
|
||||
sequenced_index_node_impl*& prior(){return prior_;}
|
||||
sequenced_index_node_impl* prior()const{return prior_;}
|
||||
sequenced_index_node_impl*& next(){return next_;}
|
||||
sequenced_index_node_impl* next()const{return next_;}
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,sequenced_index_node_impl
|
||||
>::type
|
||||
>::type::pointer pointer;
|
||||
typedef typename prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,sequenced_index_node_impl
|
||||
>::type
|
||||
>::type::const_pointer const_pointer;
|
||||
|
||||
pointer& prior(){return prior_;}
|
||||
pointer prior()const{return prior_;}
|
||||
pointer& next(){return next_;}
|
||||
pointer next()const{return next_;}
|
||||
|
||||
/* interoperability with bidir_node_iterator */
|
||||
|
||||
static void increment(sequenced_index_node_impl*& x){x=x->next();}
|
||||
static void decrement(sequenced_index_node_impl*& x){x=x->prior();}
|
||||
static void increment(pointer& x){x=x->next();}
|
||||
static void decrement(pointer& x){x=x->prior();}
|
||||
|
||||
/* algorithmic stuff */
|
||||
|
||||
static void link(
|
||||
sequenced_index_node_impl* x,sequenced_index_node_impl* header)
|
||||
static void link(pointer x,pointer header)
|
||||
{
|
||||
x->prior()=header->prior();
|
||||
x->next()=header;
|
||||
x->prior()->next()=x->next()->prior()=x;
|
||||
};
|
||||
|
||||
static void unlink(sequenced_index_node_impl* x)
|
||||
static void unlink(pointer x)
|
||||
{
|
||||
x->prior()->next()=x->next();
|
||||
x->next()->prior()=x->prior();
|
||||
}
|
||||
|
||||
static void relink(
|
||||
sequenced_index_node_impl* position,sequenced_index_node_impl* x)
|
||||
static void relink(pointer position,pointer x)
|
||||
{
|
||||
unlink(x);
|
||||
x->prior()=position->prior();
|
||||
@@ -60,14 +75,12 @@ struct sequenced_index_node_impl
|
||||
x->prior()->next()=x->next()->prior()=x;
|
||||
}
|
||||
|
||||
static void relink(
|
||||
sequenced_index_node_impl* position,
|
||||
sequenced_index_node_impl* x,sequenced_index_node_impl* y)
|
||||
static void relink(pointer position,pointer x,pointer y)
|
||||
{
|
||||
/* position is assumed not to be in [x,y) */
|
||||
|
||||
if(x!=y){
|
||||
sequenced_index_node_impl* z=y->prior();
|
||||
pointer z=y->prior();
|
||||
x->prior()->next()=y;
|
||||
y->prior()=x->prior();
|
||||
x->prior()=position->prior();
|
||||
@@ -77,17 +90,17 @@ struct sequenced_index_node_impl
|
||||
}
|
||||
}
|
||||
|
||||
static void reverse(sequenced_index_node_impl* header)
|
||||
static void reverse(pointer header)
|
||||
{
|
||||
sequenced_index_node_impl* x=header;
|
||||
pointer x=header;
|
||||
do{
|
||||
sequenced_index_node_impl* y=x->next();
|
||||
pointer y=x->next();
|
||||
std::swap(x->prior(),x->next());
|
||||
x=y;
|
||||
}while(x!=header);
|
||||
}
|
||||
|
||||
static void swap(sequenced_index_node_impl* x,sequenced_index_node_impl* y)
|
||||
static void swap(pointer x,pointer y)
|
||||
{
|
||||
/* This swap function does not exchange the header nodes,
|
||||
* but rather their pointers. This is *not* used for implementing
|
||||
@@ -117,55 +130,88 @@ struct sequenced_index_node_impl
|
||||
}
|
||||
|
||||
private:
|
||||
sequenced_index_node_impl();
|
||||
|
||||
sequenced_index_node_impl* prior_;
|
||||
sequenced_index_node_impl* next_;
|
||||
pointer prior_;
|
||||
pointer next_;
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct sequenced_index_node_trampoline:sequenced_index_node_impl{};
|
||||
struct sequenced_index_node_trampoline:
|
||||
prevent_eti<
|
||||
Super,
|
||||
sequenced_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typename Super::allocator_type,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type
|
||||
{
|
||||
typedef typename prevent_eti<
|
||||
Super,
|
||||
sequenced_index_node_impl<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typename Super::allocator_type,
|
||||
char
|
||||
>::type
|
||||
>
|
||||
>::type impl_type;
|
||||
};
|
||||
|
||||
template<typename Super>
|
||||
struct sequenced_index_node:Super,sequenced_index_node_trampoline<Super>
|
||||
{
|
||||
sequenced_index_node_impl*& prior(){return impl_type::prior();}
|
||||
sequenced_index_node_impl* prior()const{return impl_type::prior();}
|
||||
sequenced_index_node_impl*& next(){return impl_type::next();}
|
||||
sequenced_index_node_impl* next()const{return impl_type::next();}
|
||||
private:
|
||||
typedef sequenced_index_node_trampoline<Super> trampoline;
|
||||
|
||||
sequenced_index_node_impl* impl()
|
||||
{return static_cast<impl_type*>(this);}
|
||||
const sequenced_index_node_impl* impl()const
|
||||
{return static_cast<const impl_type*>(this);}
|
||||
public:
|
||||
typedef typename trampoline::impl_type impl_type;
|
||||
typedef typename trampoline::pointer impl_pointer;
|
||||
typedef typename trampoline::const_pointer const_impl_pointer;
|
||||
|
||||
static sequenced_index_node* from_impl(sequenced_index_node_impl *x)
|
||||
{return static_cast<sequenced_index_node*>(static_cast<impl_type*>(x));}
|
||||
static const sequenced_index_node* from_impl(
|
||||
const sequenced_index_node_impl* x)
|
||||
impl_pointer& prior(){return trampoline::prior();}
|
||||
impl_pointer prior()const{return trampoline::prior();}
|
||||
impl_pointer& next(){return trampoline::next();}
|
||||
impl_pointer next()const{return trampoline::next();}
|
||||
|
||||
impl_pointer impl()
|
||||
{
|
||||
return static_cast<impl_pointer>(
|
||||
static_cast<impl_type*>(static_cast<trampoline*>(this)));
|
||||
}
|
||||
|
||||
const_impl_pointer impl()const
|
||||
{
|
||||
return static_cast<const_impl_pointer>(
|
||||
static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
|
||||
}
|
||||
|
||||
static sequenced_index_node* from_impl(impl_pointer x)
|
||||
{
|
||||
return static_cast<sequenced_index_node*>(
|
||||
static_cast<trampoline*>(&*x));
|
||||
}
|
||||
|
||||
static const sequenced_index_node* from_impl(const_impl_pointer x)
|
||||
{
|
||||
return static_cast<const sequenced_index_node*>(
|
||||
static_cast<const impl_type*>(x));
|
||||
static_cast<const trampoline*>(&*x));
|
||||
}
|
||||
|
||||
/* interoperability with bidir_node_iterator */
|
||||
|
||||
static void increment(sequenced_index_node*& x)
|
||||
{
|
||||
sequenced_index_node_impl* xi=x->impl();
|
||||
impl_type::increment(xi);
|
||||
impl_pointer xi=x->impl();
|
||||
trampoline::increment(xi);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
|
||||
static void decrement(sequenced_index_node*& x)
|
||||
{
|
||||
sequenced_index_node_impl* xi=x->impl();
|
||||
impl_type::decrement(xi);
|
||||
impl_pointer xi=x->impl();
|
||||
trampoline::decrement(xi);
|
||||
x=from_impl(xi);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef sequenced_index_node_trampoline<Super> impl_type;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -60,7 +60,7 @@ template <typename SequencedIndex,typename Compare>
|
||||
void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp)
|
||||
{
|
||||
typedef typename SequencedIndex::iterator iterator;
|
||||
if(x!=y){
|
||||
if(&x!=&y){
|
||||
iterator first0=x.begin(),last0=x.end();
|
||||
iterator first1=y.begin(),last1=y.end();
|
||||
while(first0!=last0&&first1!=last1){
|
||||
@@ -77,23 +77,28 @@ void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp)
|
||||
|
||||
template<typename Node,typename Compare>
|
||||
void sequenced_index_collate(
|
||||
sequenced_index_node_impl* x,sequenced_index_node_impl* y,Compare comp
|
||||
BOOST_DEDUCED_TYPENAME Node::impl_type* x,
|
||||
BOOST_DEDUCED_TYPENAME Node::impl_type* y,
|
||||
Compare comp
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
|
||||
{
|
||||
sequenced_index_node_impl* first0=x->next();
|
||||
sequenced_index_node_impl* last0=x;
|
||||
sequenced_index_node_impl* first1=y->next();
|
||||
sequenced_index_node_impl* last1=y;
|
||||
typedef typename Node::impl_type impl_type;
|
||||
typedef typename Node::impl_pointer impl_pointer;
|
||||
|
||||
impl_pointer first0=x->next();
|
||||
impl_pointer last0=x;
|
||||
impl_pointer first1=y->next();
|
||||
impl_pointer last1=y;
|
||||
while(first0!=last0&&first1!=last1){
|
||||
if(comp(
|
||||
Node::from_impl(first1)->value(),Node::from_impl(first0)->value())){
|
||||
sequenced_index_node_impl* tmp=first1->next();
|
||||
sequenced_index_node_impl::relink(first0,first1);
|
||||
impl_pointer tmp=first1->next();
|
||||
impl_type::relink(first0,first1);
|
||||
first1=tmp;
|
||||
}
|
||||
else first0=first0->next();
|
||||
}
|
||||
sequenced_index_node_impl::relink(last0,first1,last1);
|
||||
impl_type::relink(last0,first1,last1);
|
||||
}
|
||||
|
||||
/* Some versions of CGG require a bogus typename in counter_spc
|
||||
@@ -122,54 +127,64 @@ void sequenced_index_sort(Node* header,Compare comp)
|
||||
if(header->next()==header->impl()||
|
||||
header->next()->next()==header->impl())return;
|
||||
|
||||
aligned_storage<
|
||||
sizeof(sequenced_index_node_impl),
|
||||
alignment_of<
|
||||
sequenced_index_node_impl>::value
|
||||
>::type carry_spc;
|
||||
sequenced_index_node_impl& carry=
|
||||
*static_cast<sequenced_index_node_impl*>(static_cast<void*>(&carry_spc));
|
||||
aligned_storage<
|
||||
typedef typename Node::impl_type impl_type;
|
||||
typedef typename Node::impl_pointer impl_pointer;
|
||||
|
||||
typedef typename aligned_storage<
|
||||
sizeof(impl_type),
|
||||
alignment_of<impl_type>::value
|
||||
>::type carry_spc_type;
|
||||
carry_spc_type carry_spc;
|
||||
impl_type& carry=
|
||||
*static_cast<impl_type*>(static_cast<void*>(&carry_spc));
|
||||
typedef typename aligned_storage<
|
||||
sizeof(
|
||||
sequenced_index_node_impl
|
||||
impl_type
|
||||
[sequenced_index_sort_max_fill]),
|
||||
alignment_of<
|
||||
sequenced_index_node_impl
|
||||
impl_type
|
||||
[sequenced_index_sort_max_fill]
|
||||
>::value
|
||||
>::type counter_spc;
|
||||
sequenced_index_node_impl* counter=
|
||||
static_cast<sequenced_index_node_impl*>(static_cast<void*>(&counter_spc));
|
||||
std::size_t fill=0;
|
||||
>::type counter_spc_type;
|
||||
counter_spc_type counter_spc;
|
||||
impl_type* counter=
|
||||
static_cast<impl_type*>(static_cast<void*>(&counter_spc));
|
||||
std::size_t fill=0;
|
||||
|
||||
carry.prior()=carry.next()=&carry;
|
||||
counter[0].prior()=counter[0].next()=&counter[0];
|
||||
carry.prior()=carry.next()=static_cast<impl_pointer>(&carry);
|
||||
counter[0].prior()=counter[0].next()=static_cast<impl_pointer>(&counter[0]);
|
||||
|
||||
BOOST_TRY{
|
||||
while(header->next()!=header->impl()){
|
||||
sequenced_index_node_impl::relink(carry.next(),header->next());
|
||||
impl_type::relink(carry.next(),header->next());
|
||||
std::size_t i=0;
|
||||
while(i<fill&&counter[i].next()!=&counter[i]){
|
||||
while(i<fill&&counter[i].next()!=static_cast<impl_pointer>(&counter[i])){
|
||||
sequenced_index_collate<Node>(&carry,&counter[i++],comp);
|
||||
}
|
||||
sequenced_index_node_impl::swap(&carry,&counter[i]);
|
||||
impl_type::swap(
|
||||
static_cast<impl_pointer>(&carry),
|
||||
static_cast<impl_pointer>(&counter[i]));
|
||||
if(i==fill){
|
||||
++fill;
|
||||
counter[fill].prior()=counter[fill].next()=&counter[fill];
|
||||
counter[fill].prior()=counter[fill].next()=
|
||||
static_cast<impl_pointer>(&counter[fill]);
|
||||
}
|
||||
}
|
||||
|
||||
for(std::size_t i=1;i<fill;++i){
|
||||
sequenced_index_collate<Node>(&counter[i],&counter[i-1],comp);
|
||||
}
|
||||
sequenced_index_node_impl::swap(header->impl(),&counter[fill-1]);
|
||||
impl_type::swap(
|
||||
header->impl(),static_cast<impl_pointer>(&counter[fill-1]));
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
sequenced_index_node_impl::relink(header->impl(),carry.next(),&carry);
|
||||
impl_type::relink(
|
||||
header->impl(),carry.next(),static_cast<impl_pointer>(&carry));
|
||||
for(std::size_t i=0;i<=fill;++i){
|
||||
sequenced_index_node_impl::relink(
|
||||
header->impl(),counter[i].next(),&counter[i]);
|
||||
impl_type::relink(
|
||||
header->impl(),counter[i].next(),
|
||||
static_cast<impl_pointer>(&counter[i]));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/* Copyright 2003-2010 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Helper class for storing and retrieving a given type serialization class
|
||||
* version while avoiding saving the number multiple times in the same
|
||||
* archive.
|
||||
* Behavior undefined if template partial specialization is not supported.
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
struct serialization_version
|
||||
{
|
||||
serialization_version():
|
||||
value(boost::serialization::version<serialization_version>::value){}
|
||||
|
||||
serialization_version& operator=(unsigned int x){value=x;return *this;};
|
||||
|
||||
operator unsigned int()const{return value;}
|
||||
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive&,const unsigned int)const{}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive&,const unsigned int version)
|
||||
{
|
||||
this->value=version;
|
||||
}
|
||||
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
namespace serialization {
|
||||
template<typename T>
|
||||
struct version<boost::multi_index::detail::serialization_version<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int,value=version<T>::value);
|
||||
};
|
||||
} /* namespace serialization */
|
||||
#endif
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -33,15 +33,21 @@ namespace detail{
|
||||
*/
|
||||
|
||||
template<int N>struct uintptr_candidates;
|
||||
template<>struct uintptr_candidates<-1>{typedef unsigned int type;};
|
||||
template<>struct uintptr_candidates<0> {typedef unsigned int type;};
|
||||
template<>struct uintptr_candidates<1> {typedef unsigned short type;};
|
||||
template<>struct uintptr_candidates<2> {typedef unsigned long type;};
|
||||
template<>struct uintptr_candidates<-1>{typedef unsigned int type;};
|
||||
template<>struct uintptr_candidates<0> {typedef unsigned int type;};
|
||||
template<>struct uintptr_candidates<1> {typedef unsigned short type;};
|
||||
template<>struct uintptr_candidates<2> {typedef unsigned long type;};
|
||||
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
template<>struct uintptr_candidates<3> {typedef unsigned long long type;};
|
||||
template<>struct uintptr_candidates<3> {typedef boost::ulong_long_type type;};
|
||||
#else
|
||||
template<>struct uintptr_candidates<3> {typedef unsigned int type;};
|
||||
template<>struct uintptr_candidates<3> {typedef unsigned int type;};
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_MS_INT64)
|
||||
template<>struct uintptr_candidates<4> {typedef unsigned __int64 type;};
|
||||
#else
|
||||
template<>struct uintptr_candidates<4> {typedef unsigned int type;};
|
||||
#endif
|
||||
|
||||
struct uintptr_aux
|
||||
@@ -50,7 +56,8 @@ struct uintptr_aux
|
||||
sizeof(void*)==sizeof(uintptr_candidates<0>::type)?0:
|
||||
sizeof(void*)==sizeof(uintptr_candidates<1>::type)?1:
|
||||
sizeof(void*)==sizeof(uintptr_candidates<2>::type)?2:
|
||||
sizeof(void*)==sizeof(uintptr_candidates<3>::type)?3:-1);
|
||||
sizeof(void*)==sizeof(uintptr_candidates<3>::type)?3:
|
||||
sizeof(void*)==sizeof(uintptr_candidates<4>::type)?4:-1);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool,has_uintptr_type=(index>=0));
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -22,28 +22,59 @@ namespace multi_index{
|
||||
|
||||
/* dummy type and variable for use in ordered_index::range() */
|
||||
|
||||
namespace detail{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
/* The default branch actually works for MSVC 6.0, but seems like
|
||||
* this implementation of unbounded improves the performance of ordered
|
||||
* indices! This behavior is hard to explain and probably a test artifact,
|
||||
* but it does not hurt to have the workaround anyway.
|
||||
*/
|
||||
|
||||
struct unbounded_type{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
namespace detail{struct unbounded_type{};}
|
||||
|
||||
namespace{
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
/* The default branch actually works for MSVC 6.0, but seems like
|
||||
* the const qualifier reduces the performance of ordered indices! This
|
||||
* behavior is hard to explain and probably a test artifact, but it
|
||||
* does not hurt to have the workaround anyway.
|
||||
*/
|
||||
|
||||
static detail::unbounded_type unbounded_obj=detail::unbounded_type();
|
||||
static detail::unbounded_type& unbounded=unbounded_obj;
|
||||
#else
|
||||
const detail::unbounded_type unbounded=detail::unbounded_type();
|
||||
#endif
|
||||
|
||||
} /* unnamed */
|
||||
#else
|
||||
/* ODR-abiding technique shown at the example attached to
|
||||
* http://lists.boost.org/Archives/boost/2006/07/108355.php
|
||||
*/
|
||||
|
||||
namespace detail{class unbounded_helper;}
|
||||
|
||||
detail::unbounded_helper unbounded(detail::unbounded_helper);
|
||||
|
||||
namespace detail{
|
||||
|
||||
class unbounded_helper
|
||||
{
|
||||
unbounded_helper(){}
|
||||
unbounded_helper(const unbounded_helper&){}
|
||||
friend unbounded_helper multi_index::unbounded(unbounded_helper);
|
||||
};
|
||||
|
||||
typedef unbounded_helper (*unbounded_type)(unbounded_helper);
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
inline detail::unbounded_helper unbounded(detail::unbounded_helper)
|
||||
{
|
||||
return detail::unbounded_helper();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tags used in the implementation of range */
|
||||
|
||||
namespace detail{
|
||||
|
||||
struct none_unbounded_tag{};
|
||||
struct lower_unbounded_tag{};
|
||||
struct upper_unbounded_tag{};
|
||||
struct both_unbounded_tag{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -26,7 +26,8 @@ namespace detail{
|
||||
template<typename Value,typename KeyFromValue,typename Compare>
|
||||
struct value_comparison:std::binary_function<Value,Value,bool>
|
||||
{
|
||||
value_comparison(KeyFromValue key_=KeyFromValue(),Compare comp_=Compare()):
|
||||
value_comparison(
|
||||
const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()):
|
||||
key(key_),comp(comp_)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_GLOBAL_FUN_HPP
|
||||
#define BOOST_MULTI_INDEX_GLOBAL_FUN_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
template<class T> class reference_wrapper; /* fwd decl. */
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* global_fun is a read-only key extractor from Value based on a given global
|
||||
* (or static member) function with signature:
|
||||
*
|
||||
* Type f([const] Value [&]);
|
||||
*
|
||||
* Additionally, global_fun and const_global_fun are overloaded to support
|
||||
* referece_wrappers of Value and "chained pointers" to Value's. By chained
|
||||
* pointer to T we mean a type P such that, given a p of Type P
|
||||
* *...n...*x is convertible to T&, for some n>=1.
|
||||
* Examples of chained pointers are raw and smart pointers, iterators and
|
||||
* arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
|
||||
*/
|
||||
|
||||
/* NB. Some overloads of operator() have an extra dummy parameter int=0.
|
||||
* This disambiguator serves several purposes:
|
||||
* - Without it, MSVC++ 6.0 incorrectly regards some overloads as
|
||||
* specializations of a previous member function template.
|
||||
* - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
|
||||
* as if they have the same signature.
|
||||
* - If remove_const is broken due to lack of PTS, int=0 avoids the
|
||||
* declaration of memfuns with identical signature.
|
||||
*/
|
||||
|
||||
template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
||||
struct const_ref_global_fun_base
|
||||
{
|
||||
typedef typename remove_reference<Type>::type result_type;
|
||||
|
||||
template<typename ChainedPtr>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr&,Value>,Type>::type
|
||||
#else
|
||||
Type
|
||||
#endif
|
||||
|
||||
operator()(const ChainedPtr& x)const
|
||||
{
|
||||
return operator()(*x);
|
||||
}
|
||||
|
||||
Type operator()(Value x)const
|
||||
{
|
||||
return PtrToFunction(x);
|
||||
}
|
||||
|
||||
Type operator()(
|
||||
const reference_wrapper<
|
||||
typename remove_reference<Value>::type>& x)const
|
||||
{
|
||||
return operator()(x.get());
|
||||
}
|
||||
|
||||
Type operator()(
|
||||
const reference_wrapper<
|
||||
typename remove_const<
|
||||
typename remove_reference<Value>::type>::type>& x,int=0)const
|
||||
{
|
||||
return operator()(x.get());
|
||||
}
|
||||
};
|
||||
|
||||
template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
||||
struct non_const_ref_global_fun_base
|
||||
{
|
||||
typedef typename remove_reference<Type>::type result_type;
|
||||
|
||||
template<typename ChainedPtr>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<ChainedPtr&,Value>,Type>::type
|
||||
#else
|
||||
Type
|
||||
#endif
|
||||
|
||||
operator()(const ChainedPtr& x)const
|
||||
{
|
||||
return operator()(*x);
|
||||
}
|
||||
|
||||
Type operator()(Value x)const
|
||||
{
|
||||
return PtrToFunction(x);
|
||||
}
|
||||
|
||||
Type operator()(
|
||||
const reference_wrapper<
|
||||
typename remove_reference<Value>::type>& x)const
|
||||
{
|
||||
return operator()(x.get());
|
||||
}
|
||||
};
|
||||
|
||||
template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
||||
struct non_ref_global_fun_base
|
||||
{
|
||||
typedef typename remove_reference<Type>::type result_type;
|
||||
|
||||
template<typename ChainedPtr>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr&,const Value&>,Type>::type
|
||||
#else
|
||||
Type
|
||||
#endif
|
||||
|
||||
operator()(const ChainedPtr& x)const
|
||||
{
|
||||
return operator()(*x);
|
||||
}
|
||||
|
||||
Type operator()(const Value& x)const
|
||||
{
|
||||
return PtrToFunction(x);
|
||||
}
|
||||
|
||||
Type operator()(const reference_wrapper<const Value>& x)const
|
||||
{
|
||||
return operator()(x.get());
|
||||
}
|
||||
|
||||
Type operator()(
|
||||
const reference_wrapper<
|
||||
typename remove_const<Value>::type>& x,int=0)const
|
||||
{
|
||||
return operator()(x.get());
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
||||
struct global_fun:
|
||||
mpl::if_c<
|
||||
is_reference<Value>::value,
|
||||
typename mpl::if_c<
|
||||
is_const<typename remove_reference<Value>::type>::value,
|
||||
detail::const_ref_global_fun_base<Value,Type,PtrToFunction>,
|
||||
detail::non_const_ref_global_fun_base<Value,Type,PtrToFunction>
|
||||
>::type,
|
||||
detail::non_ref_global_fun_base<Value,Type,PtrToFunction>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -19,12 +19,15 @@
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/foreach_fwd.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/bucket_array.hpp>
|
||||
#include <boost/multi_index/detail/hash_index_iterator.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/modify_key_adaptor.hpp>
|
||||
#include <boost/multi_index/detail/safe_ctr_proxy.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
@@ -100,6 +103,10 @@ class hashed_index:
|
||||
protected:
|
||||
typedef hashed_index_node<
|
||||
typename super::node_type> node_type;
|
||||
|
||||
private:
|
||||
typedef typename node_type::impl_type node_impl_type;
|
||||
typedef typename node_impl_type::pointer node_impl_pointer;
|
||||
typedef bucket_array<
|
||||
typename super::final_allocator_type> bucket_array_type;
|
||||
|
||||
@@ -172,8 +179,7 @@ private:
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
typedef safe_ctr_proxy_impl<
|
||||
hashed_index_iterator<
|
||||
node_type,
|
||||
bucket_array_type>,
|
||||
node_type,bucket_array_type>,
|
||||
hashed_index> safe_super;
|
||||
#else
|
||||
typedef safe_mode::safe_container<
|
||||
@@ -227,6 +233,19 @@ public:
|
||||
iterator end(){return make_iterator(header());}
|
||||
const_iterator end()const{return make_iterator(header());}
|
||||
|
||||
const_iterator cbegin()const{return begin();}
|
||||
const_iterator cend()const{return end();}
|
||||
|
||||
iterator iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
/* modifiers */
|
||||
|
||||
std::pair<iterator,bool> insert(value_param_type x)
|
||||
@@ -263,20 +282,32 @@ public:
|
||||
this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
|
||||
return position;
|
||||
}
|
||||
|
||||
size_type erase(key_param_type x)
|
||||
|
||||
size_type erase(key_param_type k)
|
||||
{
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
|
||||
size_type s=0;
|
||||
iterator it=find(x); /* caveat: relies on find() returning */
|
||||
if(it!=end()){ /* the first element */
|
||||
do{
|
||||
it=erase(it);
|
||||
++s;
|
||||
}while(it!=end()&&eq(x,key(*it)));
|
||||
size_type s=0;
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
node_impl_pointer x=buckets.at(buc);
|
||||
node_impl_pointer y=x->next();
|
||||
while(y!=x){
|
||||
if(eq(k,key(node_type::from_impl(y)->value()))){
|
||||
bool b;
|
||||
do{
|
||||
node_impl_pointer z=y->next();
|
||||
b=z!=x&&eq(
|
||||
key(node_type::from_impl(y)->value()),
|
||||
key(node_type::from_impl(z)->value()));
|
||||
this->final_erase_(
|
||||
static_cast<final_node_type*>(node_type::from_impl(y)));
|
||||
y=z;
|
||||
++s;
|
||||
}while(b);
|
||||
break;
|
||||
}
|
||||
y=y->next();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -325,6 +356,27 @@ public:
|
||||
mod,static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool modify(iterator position,Modifier mod,Rollback back)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
/* MSVC++ 6.0 optimizer on safe mode code chokes if this
|
||||
* this is not added. Left it for all compilers as it does no
|
||||
* harm.
|
||||
*/
|
||||
|
||||
position.detach();
|
||||
#endif
|
||||
|
||||
return this->final_modify_(
|
||||
mod,back,static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
template<typename Modifier>
|
||||
bool modify_key(iterator position,Modifier mod)
|
||||
{
|
||||
@@ -336,6 +388,19 @@ public:
|
||||
position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
|
||||
}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool modify_key(iterator position,Modifier mod,Rollback back)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
return modify(
|
||||
position,
|
||||
modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
|
||||
modify_key_adaptor<Rollback,value_type,KeyFromValue>(back,key));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
@@ -373,9 +438,9 @@ public:
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const
|
||||
{
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
hashed_index_node_impl* x=buckets.at(buc);
|
||||
hashed_index_node_impl* y=x->next();
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
node_impl_pointer x=buckets.at(buc);
|
||||
node_impl_pointer y=x->next();
|
||||
while(y!=x){
|
||||
if(eq(k,key(node_type::from_impl(y)->value()))){
|
||||
return make_iterator(node_type::from_impl(y));
|
||||
@@ -398,10 +463,10 @@ public:
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const
|
||||
{
|
||||
size_type res=0;
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
hashed_index_node_impl* x=buckets.at(buc);
|
||||
hashed_index_node_impl* y=x->next();
|
||||
size_type res=0;
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
node_impl_pointer x=buckets.at(buc);
|
||||
node_impl_pointer y=x->next();
|
||||
while(y!=x){
|
||||
if(eq(k,key(node_type::from_impl(y)->value()))){
|
||||
do{
|
||||
@@ -428,12 +493,12 @@ public:
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const
|
||||
{
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
hashed_index_node_impl* x=buckets.at(buc);
|
||||
hashed_index_node_impl* y=x->next();
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
node_impl_pointer x=buckets.at(buc);
|
||||
node_impl_pointer y=x->next();
|
||||
while(y!=x){
|
||||
if(eq(k,key(node_type::from_impl(y)->value()))){
|
||||
hashed_index_node_impl* y0=y;
|
||||
node_impl_pointer y0=y;
|
||||
do{
|
||||
y=y->next();
|
||||
}while(y!=x&&eq(k,key(node_type::from_impl(y)->value())));
|
||||
@@ -459,9 +524,9 @@ public:
|
||||
|
||||
size_type bucket_size(size_type n)const
|
||||
{
|
||||
size_type res=0;
|
||||
hashed_index_node_impl* x=buckets.at(n);
|
||||
hashed_index_node_impl* y=x->next();
|
||||
size_type res=0;
|
||||
node_impl_pointer x=buckets.at(n);
|
||||
node_impl_pointer y=x->next();
|
||||
while(y!=x){
|
||||
++res;
|
||||
y=y->next();
|
||||
@@ -481,8 +546,8 @@ public:
|
||||
|
||||
const_local_iterator begin(size_type n)const
|
||||
{
|
||||
hashed_index_node_impl* x=buckets.at(n);
|
||||
hashed_index_node_impl* y=x->next();
|
||||
node_impl_pointer x=buckets.at(n);
|
||||
node_impl_pointer y=x->next();
|
||||
if(y==x)return end();
|
||||
return make_iterator(node_type::from_impl(y));
|
||||
}
|
||||
@@ -494,7 +559,7 @@ public:
|
||||
|
||||
const_local_iterator end(size_type n)const
|
||||
{
|
||||
hashed_index_node_impl* x=buckets.at(n);
|
||||
node_impl_pointer x=buckets.at(n);
|
||||
if(x==x->next())return end();
|
||||
do{
|
||||
++x;
|
||||
@@ -502,6 +567,19 @@ public:
|
||||
return make_iterator(node_type::from_impl(x->next()));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n)const{return begin(n);}
|
||||
const_local_iterator cend(size_type n)const{return end(n);}
|
||||
|
||||
local_iterator local_iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
const_local_iterator local_iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
/* hash policy */
|
||||
|
||||
float load_factor()const{return static_cast<float>(size())/bucket_count();}
|
||||
@@ -529,7 +607,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
hash(tuples::get<2>(args_list.get_head())),
|
||||
eq(tuples::get<3>(args_list.get_head())),
|
||||
buckets(al,header()->impl(),tuples::get<0>(args_list.get_head())),
|
||||
mlf(1.0),
|
||||
mlf(1.0f),
|
||||
first_bucket(buckets.size())
|
||||
{
|
||||
calculate_max_load();
|
||||
@@ -538,6 +616,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
hashed_index(
|
||||
const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x):
|
||||
super(x),
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
#endif
|
||||
|
||||
key(x.key),
|
||||
hash(x.hash),
|
||||
eq(x.eq),
|
||||
@@ -585,13 +668,13 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x,
|
||||
const copy_map_type& map)
|
||||
{
|
||||
for(hashed_index_node_impl* begin_org=x.buckets.begin(),
|
||||
* begin_cpy=buckets.begin(),
|
||||
* end_org=x.buckets.end();
|
||||
for(node_impl_pointer begin_org=x.buckets.begin(),
|
||||
begin_cpy=buckets.begin(),
|
||||
end_org=x.buckets.end();
|
||||
begin_org!=end_org;++begin_org,++begin_cpy){
|
||||
|
||||
hashed_index_node_impl* next_org=begin_org->next();
|
||||
hashed_index_node_impl* cpy=begin_cpy;
|
||||
node_impl_pointer next_org=begin_org->next();
|
||||
node_impl_pointer cpy=begin_cpy;
|
||||
while(next_org!=begin_org){
|
||||
cpy->next()=
|
||||
static_cast<node_type*>(
|
||||
@@ -611,8 +694,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
{
|
||||
reserve(size()+1);
|
||||
|
||||
std::size_t buc=find_bucket(v);
|
||||
hashed_index_node_impl* pos=buckets.at(buc);
|
||||
std::size_t buc=find_bucket(v);
|
||||
node_impl_pointer pos=buckets.at(buc);
|
||||
if(!link_point(v,pos,Category()))return node_type::from_impl(pos);
|
||||
|
||||
node_type* res=static_cast<node_type*>(super::insert_(v,x));
|
||||
@@ -627,8 +710,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
{
|
||||
reserve(size()+1);
|
||||
|
||||
std::size_t buc=find_bucket(v);
|
||||
hashed_index_node_impl* pos=buckets.at(buc);
|
||||
std::size_t buc=find_bucket(v);
|
||||
node_impl_pointer pos=buckets.at(buc);
|
||||
if(!link_point(v,pos,Category()))return node_type::from_impl(pos);
|
||||
|
||||
node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
|
||||
@@ -652,11 +735,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
void delete_all_nodes_()
|
||||
{
|
||||
for(hashed_index_node_impl* x=buckets.begin(),*x_end=buckets.end();
|
||||
for(node_impl_pointer x=buckets.begin(),x_end=buckets.end();
|
||||
x!=x_end;++x){
|
||||
hashed_index_node_impl* y=x->next();
|
||||
node_impl_pointer y=x->next();
|
||||
while(y!=x){
|
||||
hashed_index_node_impl* z=y->next();
|
||||
node_impl_pointer z=y->next();
|
||||
this->final_delete_node_(
|
||||
static_cast<final_node_type*>(node_type::from_impl(y)));
|
||||
y=z;
|
||||
@@ -671,7 +754,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
first_bucket=buckets.size();
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::detach_all_iterators();
|
||||
safe_super::detach_dereferenceable_iterators();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -699,12 +782,12 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
return super::replace_(v,x);
|
||||
}
|
||||
|
||||
hashed_index_node_impl* y=prev(x);
|
||||
node_impl_pointer y=prev(x);
|
||||
unlink_next(y);
|
||||
|
||||
BOOST_TRY{
|
||||
std::size_t buc=find_bucket(v);
|
||||
hashed_index_node_impl* pos=buckets.at(buc);
|
||||
std::size_t buc=find_bucket(v);
|
||||
node_impl_pointer pos=buckets.at(buc);
|
||||
if(link_point(v,pos,Category())&&super::replace_(v,x)){
|
||||
link(x,pos);
|
||||
if(first_bucket>buc){
|
||||
@@ -727,28 +810,65 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
bool modify_(node_type* x)
|
||||
{
|
||||
unlink(x);
|
||||
|
||||
std::size_t buc;
|
||||
hashed_index_node_impl* pos;
|
||||
BOOST_TRY
|
||||
{
|
||||
std::size_t buc;
|
||||
bool b;
|
||||
BOOST_TRY{
|
||||
buc=find_bucket(x->value());
|
||||
pos=buckets.at(buc);
|
||||
if(!link_point(x->value(),pos,Category())){
|
||||
b=in_place(x->impl(),key(x->value()),buc,Category());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
erase_(x);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
if(!b){
|
||||
unlink(x);
|
||||
BOOST_TRY{
|
||||
node_impl_pointer pos=buckets.at(buc);
|
||||
if(!link_point(x->value(),pos,Category())){
|
||||
first_bucket=buckets.first_nonempty(first_bucket);
|
||||
super::erase_(x);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
link(x,pos);
|
||||
if(first_bucket>buc){
|
||||
first_bucket=buc;
|
||||
}
|
||||
else if(first_bucket<buc){
|
||||
first_bucket=buckets.first_nonempty(first_bucket);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
first_bucket=buckets.first_nonempty(first_bucket);
|
||||
super::erase_(x);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
#endif
|
||||
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
BOOST_TRY{
|
||||
if(!super::modify_(x)){
|
||||
unlink(x);
|
||||
first_bucket=buckets.first_nonempty(first_bucket);
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
else return true;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
unlink(x);
|
||||
first_bucket=buckets.first_nonempty(first_bucket);
|
||||
super::erase_(x);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
@@ -757,9 +877,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_rollback_(node_type* x)
|
||||
{
|
||||
std::size_t buc=find_bucket(x->value());
|
||||
if(in_place(x->impl(),key(x->value()),buc,Category())){
|
||||
return super::modify_rollback_(x);
|
||||
}
|
||||
|
||||
node_impl_pointer y=prev(x);
|
||||
unlink_next(y);
|
||||
|
||||
BOOST_TRY{
|
||||
if(super::modify_(x)){
|
||||
node_impl_pointer pos=buckets.at(buc);
|
||||
if(link_point(x->value(),pos,Category())&&super::modify_rollback_(x)){
|
||||
link(x,pos);
|
||||
if(first_bucket>buc){
|
||||
first_bucket=buc;
|
||||
@@ -769,21 +901,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
first_bucket=buckets.first_nonempty(first_bucket);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
#endif
|
||||
link(x,y);
|
||||
return false;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
first_bucket=buckets.first_nonempty(first_bucket);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
#endif
|
||||
|
||||
link(x,y);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
@@ -855,9 +977,9 @@ private:
|
||||
}
|
||||
|
||||
bool link_point(
|
||||
value_param_type v,hashed_index_node_impl*& pos,hashed_unique_tag)
|
||||
value_param_type v,node_impl_pointer& pos,hashed_unique_tag)
|
||||
{
|
||||
hashed_index_node_impl* x=pos->next();
|
||||
node_impl_pointer x=pos->next();
|
||||
while(x!=pos){
|
||||
if(eq(key(v),key(node_type::from_impl(x)->value()))){
|
||||
pos=x;
|
||||
@@ -869,10 +991,10 @@ private:
|
||||
}
|
||||
|
||||
bool link_point(
|
||||
value_param_type v,hashed_index_node_impl*& pos,hashed_non_unique_tag)
|
||||
value_param_type v,node_impl_pointer& pos,hashed_non_unique_tag)
|
||||
{
|
||||
hashed_index_node_impl* prev=pos;
|
||||
hashed_index_node_impl* x=pos->next();
|
||||
node_impl_pointer prev=pos;
|
||||
node_impl_pointer x=pos->next();
|
||||
while(x!=pos){
|
||||
if(eq(key(v),key(node_type::from_impl(x)->value()))){
|
||||
pos=prev;
|
||||
@@ -884,29 +1006,34 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
void link(node_type* x,hashed_index_node_impl* pos)
|
||||
static void link(node_type* x,node_impl_pointer pos)
|
||||
{
|
||||
hashed_index_node_impl::link(x->impl(),pos);
|
||||
node_impl_type::link(x->impl(),pos);
|
||||
};
|
||||
|
||||
void link(hashed_index_node_impl* x,hashed_index_node_impl* pos)
|
||||
static void link(node_impl_pointer x,node_impl_pointer pos)
|
||||
{
|
||||
hashed_index_node_impl::link(x,pos);
|
||||
node_impl_type::link(x,pos);
|
||||
};
|
||||
|
||||
void unlink(node_type* x)
|
||||
static void unlink(node_type* x)
|
||||
{
|
||||
hashed_index_node_impl::unlink(x->impl());
|
||||
node_impl_type::unlink(x->impl());
|
||||
};
|
||||
|
||||
static hashed_index_node_impl* prev(node_type* x)
|
||||
static node_impl_pointer prev(node_type* x)
|
||||
{
|
||||
return hashed_index_node_impl::prev(x->impl());
|
||||
return node_impl_type::prev(x->impl());
|
||||
}
|
||||
|
||||
static void unlink_next(hashed_index_node_impl* x)
|
||||
static node_impl_pointer prev_from(node_type* x,node_impl_pointer y)
|
||||
{
|
||||
hashed_index_node_impl::unlink_next(x);
|
||||
return node_impl_type::prev_from(x->impl(),y);
|
||||
}
|
||||
|
||||
static void unlink_next(node_impl_pointer x)
|
||||
{
|
||||
node_impl_type::unlink_next(x);
|
||||
}
|
||||
|
||||
void calculate_max_load()
|
||||
@@ -932,10 +1059,10 @@ private:
|
||||
auto_space<std::size_t,allocator_type> hashes(get_allocator(),size());
|
||||
|
||||
std::size_t i=0;
|
||||
hashed_index_node_impl* x=buckets.begin();
|
||||
hashed_index_node_impl* x_end=buckets.end();
|
||||
node_impl_pointer x=buckets.begin();
|
||||
node_impl_pointer x_end=buckets.end();
|
||||
for(;x!=x_end;++x){
|
||||
hashed_index_node_impl* y=x->next();
|
||||
node_impl_pointer y=x->next();
|
||||
while(y!=x){
|
||||
hashes.data()[i++]=hash(key(node_type::from_impl(y)->value()));
|
||||
y=y->next();
|
||||
@@ -945,11 +1072,11 @@ private:
|
||||
i=0;
|
||||
x=buckets.begin();
|
||||
for(;x!=x_end;++x){
|
||||
hashed_index_node_impl* y=x->next();
|
||||
node_impl_pointer y=x->next();
|
||||
while(y!=x){
|
||||
hashed_index_node_impl* z=y->next();
|
||||
std::size_t buc1=buckets1.position(hashes.data()[i++]);
|
||||
hashed_index_node_impl* x1=buckets1.at(buc1);
|
||||
node_impl_pointer z=y->next();
|
||||
std::size_t buc1=buckets1.position(hashes.data()[i++]);
|
||||
node_impl_pointer x1=buckets1.at(buc1);
|
||||
link(y,x1);
|
||||
y=z;
|
||||
}
|
||||
@@ -960,6 +1087,68 @@ private:
|
||||
first_bucket=buckets.first_nonempty(0);
|
||||
}
|
||||
|
||||
bool in_place(
|
||||
node_impl_pointer x,key_param_type k,std::size_t buc,
|
||||
hashed_unique_tag)const
|
||||
{
|
||||
std::less_equal<node_impl_pointer> leq;
|
||||
node_impl_pointer bbegin=buckets.begin();
|
||||
node_impl_pointer bend=buckets.end();
|
||||
node_impl_pointer pbuc=x->next();
|
||||
|
||||
while(!leq(bbegin,pbuc)||!leq(pbuc,bend))pbuc=pbuc->next();
|
||||
if(buc!=static_cast<std::size_t>(pbuc-bbegin))return false;
|
||||
|
||||
node_impl_pointer y=x;
|
||||
while(y->next()!=x){
|
||||
y=y->next();
|
||||
if(y==pbuc)continue;
|
||||
if(eq(k,key(node_type::from_impl(y)->value())))return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool in_place(
|
||||
node_impl_pointer x,key_param_type k,std::size_t buc,
|
||||
hashed_non_unique_tag)const
|
||||
{
|
||||
std::less_equal<node_impl_pointer> leq;
|
||||
node_impl_pointer bbegin=buckets.begin();
|
||||
node_impl_pointer bend=buckets.end();
|
||||
node_impl_pointer pbuc=x->next();
|
||||
|
||||
while(!leq(bbegin,pbuc)||!leq(pbuc,bend))pbuc=pbuc->next();
|
||||
if(buc!=static_cast<std::size_t>(pbuc-bbegin))return false;
|
||||
|
||||
node_impl_pointer y=x->next();
|
||||
if(y!=pbuc){
|
||||
if(eq(k,key(node_type::from_impl(y)->value()))){
|
||||
/* adjacent to equivalent element -> in place */
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
y=y->next();
|
||||
while(y!=pbuc){
|
||||
if(eq(k,key(node_type::from_impl(y)->value())))return false;
|
||||
y=y->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
while(y->next()!=x){
|
||||
y=y->next();
|
||||
if(eq(k,key(node_type::from_impl(y)->value()))){
|
||||
while(y->next()!=x){
|
||||
y=y->next();
|
||||
if(!eq(k,key(node_type::from_impl(y)->value())))return false;
|
||||
}
|
||||
/* after a group of equivalent elements --> in place */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
void detach_iterators(node_type* x)
|
||||
{
|
||||
@@ -997,7 +1186,7 @@ void swap(
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
/* sequenced index specifiers */
|
||||
/* hashed index specifiers */
|
||||
|
||||
template<typename Arg1,typename Arg2,typename Arg3,typename Arg4>
|
||||
struct hashed_unique
|
||||
@@ -1053,6 +1242,20 @@ struct hashed_non_unique
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
/* Boost.Foreach compatibility */
|
||||
|
||||
template<
|
||||
typename KeyFromValue,typename Hash,typename Pred,
|
||||
typename SuperMeta,typename TagList,typename Category
|
||||
>
|
||||
inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
||||
boost::multi_index::detail::hashed_index<
|
||||
KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>*&,
|
||||
boost::foreach::tag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -60,7 +60,7 @@ struct const_identity_base
|
||||
template<typename ChainedPtr>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<is_convertible<const ChainedPtr,Type>,Type&>::type
|
||||
typename disable_if<is_convertible<const ChainedPtr&,Type&>,Type&>::type
|
||||
#else
|
||||
Type&
|
||||
#endif
|
||||
@@ -97,7 +97,8 @@ struct non_const_identity_base
|
||||
template<typename ChainedPtr>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<is_convertible<const ChainedPtr,const Type>,Type&>::type
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr&,const Type&>,Type&>::type
|
||||
#else
|
||||
Type&
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -6,8 +6,8 @@
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_IDENTITY_HPP
|
||||
#define BOOST_MULTI_INDEX_IDENTITY_HPP
|
||||
#ifndef BOOST_MULTI_INDEX_IDENTITY_FWD_HPP
|
||||
#define BOOST_MULTI_INDEX_IDENTITY_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#pragma once
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <boost/multi_index/composite_key.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/global_fun.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -39,16 +39,6 @@ namespace multi_index{
|
||||
* arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
|
||||
*/
|
||||
|
||||
/* NB. Some overloads of operator() have an extra dummy parameter int=0.
|
||||
* This disambiguator serves several purposes:
|
||||
* - Without it, MSVC++ 6.0 incorrectly regards some overloads as
|
||||
* specializations of a previous member function template.
|
||||
* - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
|
||||
* as if they have the same signature.
|
||||
* - If remove_const is broken due to lack of PTS, int=0 avoids the
|
||||
* declaration of memfuns with identical signature.
|
||||
*/
|
||||
|
||||
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
|
||||
struct const_mem_fun
|
||||
{
|
||||
@@ -58,7 +48,7 @@ struct const_mem_fun
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr,const Class>,Type>::type
|
||||
is_convertible<const ChainedPtr&,const Class&>,Type>::type
|
||||
#else
|
||||
Type
|
||||
#endif
|
||||
@@ -78,7 +68,7 @@ struct const_mem_fun
|
||||
return operator()(x.get());
|
||||
}
|
||||
|
||||
Type operator()(const reference_wrapper<Class>& x,int=0)const
|
||||
Type operator()(const reference_wrapper<Class>& x)const
|
||||
{
|
||||
return operator()(x.get());
|
||||
}
|
||||
@@ -93,7 +83,7 @@ struct mem_fun
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<ChainedPtr,Class>,Type>::type
|
||||
is_convertible<ChainedPtr&,Class&>,Type>::type
|
||||
#else
|
||||
Type
|
||||
#endif
|
||||
@@ -115,9 +105,9 @@ struct mem_fun
|
||||
};
|
||||
|
||||
/* MSVC++ 6.0 has problems with const member functions as non-type template
|
||||
* parameters, somehow it takes them as non-const. mem_fun_explicit workarounds
|
||||
* this defficiency by accepting an extra type parameter that specifies the
|
||||
* signature of he member function. The workaround was found at:
|
||||
* parameters, somehow it takes them as non-const. const_mem_fun_explicit
|
||||
* workarounds this deficiency by accepting an extra type parameter that
|
||||
* specifies the signature of the member function. The workaround was found at:
|
||||
* Daniel, C.:"Re: weird typedef problem in VC",
|
||||
* news:microsoft.public.vc.language, 21st nov 2002,
|
||||
* http://groups.google.com/groups?
|
||||
@@ -135,7 +125,7 @@ struct const_mem_fun_explicit
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr,const Class>,Type>::type
|
||||
is_convertible<const ChainedPtr&,const Class&>,Type>::type
|
||||
#else
|
||||
Type
|
||||
#endif
|
||||
@@ -155,7 +145,7 @@ struct const_mem_fun_explicit
|
||||
return operator()(x.get());
|
||||
}
|
||||
|
||||
Type operator()(const reference_wrapper<Class>& x,int=0)const
|
||||
Type operator()(const reference_wrapper<Class>& x)const
|
||||
{
|
||||
return operator()(x.get());
|
||||
}
|
||||
@@ -172,7 +162,7 @@ struct mem_fun_explicit
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<ChainedPtr,Class>,Type>::type
|
||||
is_convertible<ChainedPtr&,Class&>,Type>::type
|
||||
#else
|
||||
Type
|
||||
#endif
|
||||
@@ -194,7 +184,7 @@ struct mem_fun_explicit
|
||||
};
|
||||
|
||||
/* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN resolve to
|
||||
* mem_fun_explicit for MSVC++ 6.0 and to [const_]mem_fun otherwise.
|
||||
* [const_]mem_fun_explicit for MSVC++ 6.0 and to [const_]mem_fun otherwise.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MSVC)&&(BOOST_MSVC<1300)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -60,7 +60,7 @@ struct const_member_base
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr,const Class>,Type&>::type
|
||||
is_convertible<const ChainedPtr&,const Class&>,Type&>::type
|
||||
#else
|
||||
Type&
|
||||
#endif
|
||||
@@ -80,7 +80,7 @@ struct const_member_base
|
||||
return operator()(x.get());
|
||||
}
|
||||
|
||||
Type& operator()(const reference_wrapper<Class> x,int=0)const
|
||||
Type& operator()(const reference_wrapper<Class>& x,int=0)const
|
||||
{
|
||||
return operator()(x.get());
|
||||
}
|
||||
@@ -95,7 +95,7 @@ struct non_const_member_base
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr,const Class>,Type&>::type
|
||||
is_convertible<const ChainedPtr&,const Class&>,Type&>::type
|
||||
#else
|
||||
Type&
|
||||
#endif
|
||||
@@ -163,7 +163,7 @@ struct const_member_offset_base
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr,const Class>,Type&>::type
|
||||
is_convertible<const ChainedPtr&,const Class&>,Type&>::type
|
||||
#else
|
||||
Type&
|
||||
#endif
|
||||
@@ -201,7 +201,7 @@ struct non_const_member_offset_base
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
typename disable_if<
|
||||
is_convertible<const ChainedPtr,const Class>,Type&>::type
|
||||
is_convertible<const ChainedPtr&,const Class&>,Type&>::type
|
||||
#else
|
||||
Type&
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -45,10 +45,14 @@
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/foreach_fwd.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/bidir_node_iterator.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/modify_key_adaptor.hpp>
|
||||
#include <boost/multi_index/detail/ord_index_node.hpp>
|
||||
#include <boost/multi_index/detail/ord_index_ops.hpp>
|
||||
@@ -60,6 +64,7 @@
|
||||
#include <boost/multi_index/ordered_index_fwd.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <utility>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
@@ -130,6 +135,10 @@ protected:
|
||||
typedef ordered_index_node<
|
||||
typename super::node_type> node_type;
|
||||
|
||||
private:
|
||||
typedef typename node_type::impl_type node_impl_type;
|
||||
typedef typename node_impl_type::pointer node_impl_pointer;
|
||||
|
||||
public:
|
||||
/* types */
|
||||
|
||||
@@ -237,7 +246,21 @@ public:
|
||||
const_reverse_iterator rbegin()const{return make_reverse_iterator(end());}
|
||||
reverse_iterator rend(){return make_reverse_iterator(begin());}
|
||||
const_reverse_iterator rend()const{return make_reverse_iterator(begin());}
|
||||
const_iterator cbegin()const{return begin();}
|
||||
const_iterator cend()const{return end();}
|
||||
const_reverse_iterator crbegin()const{return rbegin();}
|
||||
const_reverse_iterator crend()const{return rend();}
|
||||
|
||||
iterator iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
/* capacity */
|
||||
|
||||
bool empty()const{return this->final_empty_();}
|
||||
@@ -338,6 +361,27 @@ public:
|
||||
mod,static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool modify(iterator position,Modifier mod,Rollback back)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
/* MSVC++ 6.0 optimizer on safe mode code chokes if this
|
||||
* this is not added. Left it for all compilers as it does no
|
||||
* harm.
|
||||
*/
|
||||
|
||||
position.detach();
|
||||
#endif
|
||||
|
||||
return this->final_modify_(
|
||||
mod,back,static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
template<typename Modifier>
|
||||
bool modify_key(iterator position,Modifier mod)
|
||||
{
|
||||
@@ -349,6 +393,19 @@ public:
|
||||
position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
|
||||
}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool modify_key(iterator position,Modifier mod,Rollback back)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
return modify(
|
||||
position,
|
||||
modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
|
||||
modify_key_adaptor<Rollback,value_type,KeyFromValue>(back,key));
|
||||
}
|
||||
|
||||
void swap(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
|
||||
{
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
@@ -376,14 +433,14 @@ public:
|
||||
template<typename CompatibleKey>
|
||||
iterator find(const CompatibleKey& x)const
|
||||
{
|
||||
return make_iterator(ordered_index_find(header(),key,x,comp));
|
||||
return make_iterator(ordered_index_find(root(),header(),key,x,comp));
|
||||
}
|
||||
|
||||
template<typename CompatibleKey,typename CompatibleCompare>
|
||||
iterator find(
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
{
|
||||
return make_iterator(ordered_index_find(header(),key,x,comp));
|
||||
return make_iterator(ordered_index_find(root(),header(),key,x,comp));
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
@@ -403,42 +460,51 @@ public:
|
||||
template<typename CompatibleKey>
|
||||
iterator lower_bound(const CompatibleKey& x)const
|
||||
{
|
||||
return make_iterator(ordered_index_lower_bound(header(),key,x,comp));
|
||||
return make_iterator(
|
||||
ordered_index_lower_bound(root(),header(),key,x,comp));
|
||||
}
|
||||
|
||||
template<typename CompatibleKey,typename CompatibleCompare>
|
||||
iterator lower_bound(
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
{
|
||||
return make_iterator(ordered_index_lower_bound(header(),key,x,comp));
|
||||
return make_iterator(
|
||||
ordered_index_lower_bound(root(),header(),key,x,comp));
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
iterator upper_bound(const CompatibleKey& x)const
|
||||
{
|
||||
return make_iterator(ordered_index_upper_bound(header(),key,x,comp));
|
||||
return make_iterator(
|
||||
ordered_index_upper_bound(root(),header(),key,x,comp));
|
||||
}
|
||||
|
||||
template<typename CompatibleKey,typename CompatibleCompare>
|
||||
iterator upper_bound(
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
{
|
||||
return make_iterator(ordered_index_upper_bound(header(),key,x,comp));
|
||||
return make_iterator(
|
||||
ordered_index_upper_bound(root(),header(),key,x,comp));
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
std::pair<iterator,iterator> equal_range(
|
||||
const CompatibleKey& x)const
|
||||
{
|
||||
return equal_range(x,comp);
|
||||
std::pair<node_type*,node_type*> p=
|
||||
ordered_index_equal_range(root(),header(),key,x,comp);
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(p.first),make_iterator(p.second));
|
||||
}
|
||||
|
||||
template<typename CompatibleKey,typename CompatibleCompare>
|
||||
std::pair<iterator,iterator> equal_range(
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
{
|
||||
std::pair<node_type*,node_type*> p=
|
||||
ordered_index_equal_range(root(),header(),key,x,comp);
|
||||
return std::pair<iterator,iterator>(
|
||||
lower_bound(x,comp),upper_bound(x,comp));
|
||||
make_iterator(p.first),make_iterator(p.second));
|
||||
}
|
||||
|
||||
/* range */
|
||||
@@ -447,12 +513,21 @@ public:
|
||||
std::pair<iterator,iterator>
|
||||
range(LowerBounder lower,UpperBounder upper)const
|
||||
{
|
||||
std::pair<iterator,iterator> p(
|
||||
lower_range(lower),upper_range(upper));
|
||||
if(p.second!=end()&&(p.first==end()||comp(key(*p.second),key(*p.first)))){
|
||||
p.second=p.first;
|
||||
}
|
||||
return p;
|
||||
typedef typename mpl::if_<
|
||||
is_same<LowerBounder,unbounded_type>,
|
||||
BOOST_DEDUCED_TYPENAME mpl::if_<
|
||||
is_same<UpperBounder,unbounded_type>,
|
||||
both_unbounded_tag,
|
||||
lower_unbounded_tag
|
||||
>::type,
|
||||
BOOST_DEDUCED_TYPENAME mpl::if_<
|
||||
is_same<UpperBounder,unbounded_type>,
|
||||
upper_unbounded_tag,
|
||||
none_unbounded_tag
|
||||
>::type
|
||||
>::type dispatch;
|
||||
|
||||
return range(lower,upper,dispatch());
|
||||
}
|
||||
|
||||
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
@@ -467,6 +542,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
ordered_index(
|
||||
const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x):
|
||||
super(x),
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
#endif
|
||||
|
||||
key(x.key),
|
||||
comp(x.comp)
|
||||
{
|
||||
@@ -518,8 +598,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
cpy->color()=org->color();
|
||||
|
||||
ordered_index_node_impl* parent_org=org->parent();
|
||||
if(!parent_org)cpy->parent()=0;
|
||||
node_impl_pointer parent_org=org->parent();
|
||||
if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
|
||||
else{
|
||||
node_type* parent_cpy=map.find(
|
||||
static_cast<final_node_type*>(node_type::from_impl(parent_org)));
|
||||
@@ -533,8 +613,10 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
}
|
||||
}
|
||||
|
||||
if(!org->left())cpy->left()=0;
|
||||
if(!org->right())cpy->right()=0;
|
||||
if(org->left()==node_impl_pointer(0))
|
||||
cpy->left()=node_impl_pointer(0);
|
||||
if(org->right()==node_impl_pointer(0))
|
||||
cpy->right()=node_impl_pointer(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,8 +632,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
node_type* res=static_cast<node_type*>(super::insert_(v,x));
|
||||
if(res==x){
|
||||
ordered_index_node_impl::link(
|
||||
x->impl(),inf.side,inf.pos,header()->impl());
|
||||
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -565,15 +646,14 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
|
||||
if(res==x){
|
||||
ordered_index_node_impl::link(
|
||||
x->impl(),inf.side,inf.pos,header()->impl());
|
||||
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void erase_(node_type* x)
|
||||
{
|
||||
ordered_index_node_impl::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_erase(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
super::erase_(x);
|
||||
|
||||
@@ -593,7 +673,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
empty_initialize();
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::detach_all_iterators();
|
||||
safe_super::detach_dereferenceable_iterators();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -618,23 +698,20 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
node_type* next=x;
|
||||
node_type::increment(next);
|
||||
|
||||
ordered_index_node_impl::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_erase(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
|
||||
BOOST_TRY{
|
||||
link_info inf;
|
||||
if(link_point(key(v),inf,Category())&&super::replace_(v,x)){
|
||||
ordered_index_node_impl::link(
|
||||
x->impl(),inf.side,inf.pos,header()->impl());
|
||||
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
||||
return true;
|
||||
}
|
||||
ordered_index_node_impl::restore(
|
||||
x->impl(),next->impl(),header()->impl());
|
||||
node_impl_type::restore(x->impl(),next->impl(),header()->impl());
|
||||
return false;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
ordered_index_node_impl::restore(
|
||||
x->impl(),next->impl(),header()->impl());
|
||||
node_impl_type::restore(x->impl(),next->impl(),header()->impl());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
@@ -652,7 +729,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
if(!b){
|
||||
ordered_index_node_impl::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_erase(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
BOOST_TRY{
|
||||
link_info inf;
|
||||
@@ -664,8 +741,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
ordered_index_node_impl::link(
|
||||
x->impl(),inf.side,inf.pos,header()->impl());
|
||||
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
super::erase_(x);
|
||||
@@ -681,7 +757,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
BOOST_TRY{
|
||||
if(!super::modify_(x)){
|
||||
ordered_index_node_impl::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_erase(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
@@ -693,7 +769,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
else return true;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
ordered_index_node_impl::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_erase(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
@@ -705,6 +781,35 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_rollback_(node_type* x)
|
||||
{
|
||||
if(in_place(x->value(),x,Category())){
|
||||
return super::modify_rollback_(x);
|
||||
}
|
||||
|
||||
node_type* next=x;
|
||||
node_type::increment(next);
|
||||
|
||||
node_impl_type::rebalance_for_erase(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
|
||||
BOOST_TRY{
|
||||
link_info inf;
|
||||
if(link_point(key(x->value()),inf,Category())&&
|
||||
super::modify_rollback_(x)){
|
||||
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
||||
return true;
|
||||
}
|
||||
node_impl_type::restore(x->impl(),next->impl(),header()->impl());
|
||||
return false;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
node_impl_type::restore(x->impl(),next->impl(),header()->impl());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
|
||||
@@ -735,7 +840,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
else{
|
||||
if((size_type)std::distance(begin(),end())!=size())return false;
|
||||
|
||||
std::size_t len=ordered_index_node_impl::black_count(
|
||||
std::size_t len=node_impl_type::black_count(
|
||||
leftmost()->impl(),root()->impl());
|
||||
for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
|
||||
node_type* x=it.get_node();
|
||||
@@ -749,16 +854,13 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
if(left_x&&comp(key(x->value()),key(left_x->value())))return false;
|
||||
if(right_x&&comp(key(right_x->value()),key(x->value())))return false;
|
||||
if(!left_x&&!right_x&&
|
||||
ordered_index_node_impl::black_count(
|
||||
x->impl(),root()->impl())!=len)
|
||||
node_impl_type::black_count(x->impl(),root()->impl())!=len)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(leftmost()->impl()!=
|
||||
ordered_index_node_impl::minimum(root()->impl()))
|
||||
if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
|
||||
return false;
|
||||
if(rightmost()->impl()!=
|
||||
ordered_index_node_impl::maximum(root()->impl()))
|
||||
if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -785,15 +887,17 @@ private:
|
||||
header()->color()=red;
|
||||
/* used to distinguish header() from root, in iterator.operator++ */
|
||||
|
||||
header()->parent()=0;
|
||||
header()->parent()=node_impl_pointer(0);
|
||||
header()->left()=header()->impl();
|
||||
header()->right()=header()->impl();
|
||||
}
|
||||
|
||||
struct link_info
|
||||
{
|
||||
ordered_index_side side;
|
||||
ordered_index_node_impl* pos;
|
||||
link_info():side(to_left){}
|
||||
|
||||
ordered_index_side side;
|
||||
node_impl_pointer pos;
|
||||
};
|
||||
|
||||
bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
|
||||
@@ -842,6 +946,21 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
|
||||
{
|
||||
node_type* y=header();
|
||||
node_type* x=root();
|
||||
bool c=false;
|
||||
while (x){
|
||||
y=x;
|
||||
c=comp(key(x->value()),k);
|
||||
x=node_type::from_impl(c?x->right():x->left());
|
||||
}
|
||||
inf.side=c?to_right:to_left;
|
||||
inf.pos=y->impl();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hinted_link_point(
|
||||
key_param_type k,node_type* position,link_info& inf,ordered_unique_tag)
|
||||
{
|
||||
@@ -865,7 +984,7 @@ private:
|
||||
node_type* before=position;
|
||||
node_type::decrement(before);
|
||||
if(comp(key(before->value()),k)&&comp(k,key(position->value()))){
|
||||
if(before->right()==0){
|
||||
if(before->right()==node_impl_pointer(0)){
|
||||
inf.side=to_right;
|
||||
inf.pos=before->impl();
|
||||
return true;
|
||||
@@ -889,7 +1008,7 @@ private:
|
||||
inf.pos=position->impl();
|
||||
return true;
|
||||
}
|
||||
else return link_point(k,inf,ordered_non_unique_tag());
|
||||
else return lower_link_point(k,inf,ordered_non_unique_tag());
|
||||
}
|
||||
else if(position==header()){
|
||||
if(!comp(k,key(rightmost()->value()))){
|
||||
@@ -902,17 +1021,20 @@ private:
|
||||
else{
|
||||
node_type* before=position;
|
||||
node_type::decrement(before);
|
||||
if (!comp(k,key(before->value()))&&!comp(key(position->value()),k)){
|
||||
if(before->right()==0){
|
||||
inf.side=to_right;
|
||||
inf.pos=before->impl();
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
inf.side=to_left;
|
||||
inf.pos=position->impl();
|
||||
return true;
|
||||
if(!comp(k,key(before->value()))){
|
||||
if(!comp(key(position->value()),k)){
|
||||
if(before->right()==node_impl_pointer(0)){
|
||||
inf.side=to_right;
|
||||
inf.pos=before->impl();
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
inf.side=to_left;
|
||||
inf.pos=position->impl();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else return lower_link_point(k,inf,ordered_non_unique_tag());
|
||||
}
|
||||
else return link_point(k,inf,ordered_non_unique_tag());
|
||||
}
|
||||
@@ -963,48 +1085,84 @@ private:
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename LowerBounder>
|
||||
iterator lower_range(LowerBounder lower)const
|
||||
template<typename LowerBounder,typename UpperBounder>
|
||||
std::pair<iterator,iterator>
|
||||
range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
|
||||
{
|
||||
node_type* y=header();
|
||||
node_type* z=root();
|
||||
|
||||
while(z){
|
||||
if(lower(key(z->value()))){
|
||||
if(!lower(key(z->value()))){
|
||||
z=node_type::from_impl(z->right());
|
||||
}
|
||||
else if(!upper(key(z->value()))){
|
||||
y=z;
|
||||
z=node_type::from_impl(z->left());
|
||||
}
|
||||
else z=node_type::from_impl(z->right());
|
||||
else{
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(
|
||||
lower_range(node_type::from_impl(z->left()),z,lower)),
|
||||
make_iterator(
|
||||
upper_range(node_type::from_impl(z->right()),y,upper)));
|
||||
}
|
||||
}
|
||||
|
||||
return make_iterator(y);
|
||||
return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
|
||||
}
|
||||
|
||||
iterator lower_range(unbounded_type)const
|
||||
template<typename LowerBounder,typename UpperBounder>
|
||||
std::pair<iterator,iterator>
|
||||
range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
|
||||
{
|
||||
return begin();
|
||||
return std::pair<iterator,iterator>(
|
||||
begin(),
|
||||
make_iterator(upper_range(root(),header(),upper)));
|
||||
}
|
||||
|
||||
template<typename LowerBounder,typename UpperBounder>
|
||||
std::pair<iterator,iterator>
|
||||
range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
|
||||
{
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(lower_range(root(),header(),lower)),
|
||||
end());
|
||||
}
|
||||
|
||||
template<typename LowerBounder,typename UpperBounder>
|
||||
std::pair<iterator,iterator>
|
||||
range(LowerBounder,UpperBounder,both_unbounded_tag)const
|
||||
{
|
||||
return std::pair<iterator,iterator>(begin(),end());
|
||||
}
|
||||
|
||||
template<typename LowerBounder>
|
||||
node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const
|
||||
{
|
||||
while(top){
|
||||
if(lower(key(top->value()))){
|
||||
y=top;
|
||||
top=node_type::from_impl(top->left());
|
||||
}
|
||||
else top=node_type::from_impl(top->right());
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
template<typename UpperBounder>
|
||||
iterator upper_range(UpperBounder upper)const
|
||||
node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const
|
||||
{
|
||||
node_type* y=header();
|
||||
node_type* z=root();
|
||||
|
||||
while(z){
|
||||
if(!upper(key(z->value()))){
|
||||
y=z;
|
||||
z=node_type::from_impl(z->left());
|
||||
while(top){
|
||||
if(!upper(key(top->value()))){
|
||||
y=top;
|
||||
top=node_type::from_impl(top->left());
|
||||
}
|
||||
else z=node_type::from_impl(z->right());
|
||||
else top=node_type::from_impl(top->right());
|
||||
}
|
||||
|
||||
return make_iterator(y);
|
||||
}
|
||||
|
||||
iterator upper_range(unbounded_type)const
|
||||
{
|
||||
return end();
|
||||
return y;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
@@ -1051,20 +1209,21 @@ private:
|
||||
|
||||
void rearranger(node_type* position,node_type *x)
|
||||
{
|
||||
if(!position)position=lower_bound(key(x->value())).get_node();
|
||||
if(!position||comp(key(position->value()),key(x->value()))){
|
||||
position=lower_bound(key(x->value())).get_node();
|
||||
}
|
||||
else if(comp(key(x->value()),key(position->value()))){
|
||||
/* inconsistent rearrangement */
|
||||
throw_exception(
|
||||
archive::archive_exception(
|
||||
archive::archive_exception::other_exception));
|
||||
}
|
||||
else node_type::increment(position);
|
||||
|
||||
if(position!=x){
|
||||
/* check the rearrangement is consistent */
|
||||
if(!in_place(x->value(),position,Category())){
|
||||
throw_exception(
|
||||
archive::archive_exception(
|
||||
archive::archive_exception::other_exception));
|
||||
}
|
||||
|
||||
ordered_index_node_impl::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_erase(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
ordered_index_node_impl::restore(
|
||||
node_impl_type::restore(
|
||||
x->impl(),position->impl(),header()->impl());
|
||||
}
|
||||
}
|
||||
@@ -1228,6 +1387,20 @@ struct ordered_non_unique
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
/* Boost.Foreach compatibility */
|
||||
|
||||
template<
|
||||
typename KeyFromValue,typename Compare,
|
||||
typename SuperMeta,typename TagList,typename Category
|
||||
>
|
||||
inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
||||
boost::multi_index::detail::ordered_index<
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category>*&,
|
||||
boost::foreach::tag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -18,9 +18,13 @@
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/foreach_fwd.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/rnd_node_iterator.hpp>
|
||||
#include <boost/multi_index/detail/rnd_index_node.hpp>
|
||||
#include <boost/multi_index/detail/rnd_index_ops.hpp>
|
||||
@@ -31,6 +35,7 @@
|
||||
#include <boost/multi_index/random_access_index_fwd.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
@@ -93,6 +98,12 @@ protected:
|
||||
typedef random_access_index_node<
|
||||
typename super::node_type> node_type;
|
||||
|
||||
private:
|
||||
typedef typename node_type::impl_type node_impl_type;
|
||||
typedef random_access_index_ptr_array<
|
||||
typename super::final_allocator_type> ptr_array;
|
||||
typedef typename ptr_array::pointer node_impl_ptr_pointer;
|
||||
|
||||
public:
|
||||
/* types */
|
||||
|
||||
@@ -182,9 +193,7 @@ public:
|
||||
template <class InputIterator>
|
||||
void assign(InputIterator first,InputIterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
clear();
|
||||
for(;first!=last;++first)push_back(*first);
|
||||
assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
|
||||
}
|
||||
|
||||
void assign(size_type n,value_param_type value)
|
||||
@@ -211,6 +220,20 @@ public:
|
||||
const_reverse_iterator rbegin()const{return make_reverse_iterator(end());}
|
||||
reverse_iterator rend(){return make_reverse_iterator(begin());}
|
||||
const_reverse_iterator rend()const{return make_reverse_iterator(begin());}
|
||||
const_iterator cbegin()const{return begin();}
|
||||
const_iterator cend()const{return end();}
|
||||
const_reverse_iterator crbegin()const{return rbegin();}
|
||||
const_reverse_iterator crend()const{return rend();}
|
||||
|
||||
iterator iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
/* capacity */
|
||||
|
||||
@@ -289,19 +312,7 @@ public:
|
||||
template<typename InputIterator>
|
||||
void insert(iterator position,InputIterator first,InputIterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
size_type s=0;
|
||||
BOOST_TRY{
|
||||
for(;first!=last;++first){
|
||||
if(push_back(*first).second)++s;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
relocate(position,end()-s,end());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
relocate(position,end()-s,end());
|
||||
insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
|
||||
}
|
||||
|
||||
iterator erase(iterator position)
|
||||
@@ -359,6 +370,27 @@ public:
|
||||
mod,static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool modify(iterator position,Modifier mod,Rollback back)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
/* MSVC++ 6.0 optimizer on safe mode code chokes if this
|
||||
* this is not added. Left it for all compilers as it does no
|
||||
* harm.
|
||||
*/
|
||||
|
||||
position.detach();
|
||||
#endif
|
||||
|
||||
return this->final_modify_(
|
||||
mod,back,static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
void swap(random_access_index<SuperMeta,TagList>& x)
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
@@ -407,7 +439,7 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
if(x==*this)relocate(position,i);
|
||||
if(&x==this)relocate(position,i);
|
||||
else{
|
||||
if(insert(position,*i).second){
|
||||
|
||||
@@ -438,7 +470,7 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
if(x==*this)relocate(position,first,last);
|
||||
if(&x==this)relocate(position,first,last);
|
||||
else{
|
||||
size_type n=0;
|
||||
BOOST_TRY{
|
||||
@@ -500,7 +532,7 @@ public:
|
||||
|
||||
void merge(random_access_index<SuperMeta,TagList>& x)
|
||||
{
|
||||
if(*this!=x){
|
||||
if(this!=&x){
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
size_type s=size();
|
||||
splice(end(),x);
|
||||
@@ -512,7 +544,7 @@ public:
|
||||
template <typename Compare>
|
||||
void merge(random_access_index<SuperMeta,TagList>& x,Compare comp)
|
||||
{
|
||||
if(*this!=x){
|
||||
if(this!=&x){
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
size_type s=size();
|
||||
splice(end(),x);
|
||||
@@ -539,7 +571,7 @@ public:
|
||||
void reverse()
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
random_access_index_node_impl::reverse(ptrs.begin(),ptrs.end());
|
||||
node_impl_type::reverse(ptrs.begin(),ptrs.end());
|
||||
}
|
||||
|
||||
/* rearrange operations */
|
||||
@@ -574,10 +606,10 @@ public:
|
||||
void rearrange(InputIterator first)
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
for(random_access_index_node_impl** p0=ptrs.begin(),** p0_end=ptrs.end();
|
||||
for(node_impl_ptr_pointer p0=ptrs.begin(),p0_end=ptrs.end();
|
||||
p0!=p0_end;++first,++p0){
|
||||
const value_type& v1=*first;
|
||||
random_access_index_node_impl** p1=node_from_value<node_type>(&v1)->up();
|
||||
const value_type& v1=*first;
|
||||
node_impl_ptr_pointer p1=node_from_value<node_type>(&v1)->up();
|
||||
|
||||
std::swap(*p0,*p1);
|
||||
(*p0)->up()=p0;
|
||||
@@ -595,6 +627,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
random_access_index(const random_access_index<SuperMeta,TagList>& x):
|
||||
super(x),
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
#endif
|
||||
|
||||
ptrs(x.get_allocator(),header()->impl(),x.size())
|
||||
{
|
||||
/* The actual copying takes place in subsequent call to copy_().
|
||||
@@ -619,9 +656,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
void copy_(
|
||||
const random_access_index<SuperMeta,TagList>& x,const copy_map_type& map)
|
||||
{
|
||||
for(random_access_index_node_impl** begin_org=x.ptrs.begin(),
|
||||
** begin_cpy=ptrs.begin(),
|
||||
** end_org=x.ptrs.end();
|
||||
for(node_impl_ptr_pointer begin_org=x.ptrs.begin(),
|
||||
begin_cpy=ptrs.begin(),
|
||||
end_org=x.ptrs.end();
|
||||
begin_org!=end_org;++begin_org,++begin_cpy){
|
||||
*begin_cpy=
|
||||
static_cast<node_type*>(
|
||||
@@ -662,8 +699,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
void delete_all_nodes_()
|
||||
{
|
||||
for(random_access_index_node_impl** x=ptrs.begin(),**x_end=ptrs.end();
|
||||
x!=x_end;++x){
|
||||
for(node_impl_ptr_pointer x=ptrs.begin(),x_end=ptrs.end();x!=x_end;++x){
|
||||
this->final_delete_node_(
|
||||
static_cast<final_node_type*>(node_type::from_impl(*x)));
|
||||
}
|
||||
@@ -675,7 +711,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
ptrs.clear();
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::detach_all_iterators();
|
||||
safe_super::detach_dereferenceable_iterators();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -721,6 +757,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_rollback_(node_type* x)
|
||||
{
|
||||
return super::modify_rollback_(x);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
|
||||
@@ -779,12 +820,12 @@ private:
|
||||
|
||||
static void relocate(node_type* position,node_type* x)
|
||||
{
|
||||
random_access_index_node_impl::relocate(position->up(),x->up());
|
||||
node_impl_type::relocate(position->up(),x->up());
|
||||
}
|
||||
|
||||
static void relocate(node_type* position,node_type* first,node_type* last)
|
||||
{
|
||||
random_access_index_node_impl::relocate(
|
||||
node_impl_type::relocate(
|
||||
position->up(),first->up(),last->up());
|
||||
}
|
||||
|
||||
@@ -796,7 +837,61 @@ private:
|
||||
}
|
||||
#endif
|
||||
|
||||
random_access_index_ptr_array<typename super::final_allocator_type> ptrs;
|
||||
template <class InputIterator>
|
||||
void assign_iter(InputIterator first,InputIterator last,mpl::true_)
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
clear();
|
||||
for(;first!=last;++first)push_back(*first);
|
||||
}
|
||||
|
||||
void assign_iter(size_type n,value_param_type value,mpl::false_)
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
clear();
|
||||
for(size_type i=0;i<n;++i)push_back(value);
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
void insert_iter(
|
||||
iterator position,InputIterator first,InputIterator last,mpl::true_)
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
size_type s=0;
|
||||
BOOST_TRY{
|
||||
for(;first!=last;++first){
|
||||
if(push_back(*first).second)++s;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
relocate(position,end()-s,end());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
relocate(position,end()-s,end());
|
||||
}
|
||||
|
||||
void insert_iter(
|
||||
iterator position,size_type n,value_param_type x,mpl::false_)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
size_type s=0;
|
||||
BOOST_TRY{
|
||||
while(n--){
|
||||
if(push_back(x).second)++s;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
relocate(position,end()-s,end());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
relocate(position,end()-s,end());
|
||||
}
|
||||
|
||||
ptr_array ptrs;
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
@@ -909,6 +1004,16 @@ struct random_access
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
/* Boost.Foreach compatibility */
|
||||
|
||||
template<typename SuperMeta,typename TagList>
|
||||
inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
||||
boost::multi_index::detail::random_access_index<SuperMeta,TagList>*&,
|
||||
boost::foreach::tag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2006 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,12 +15,17 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/foreach_fwd.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/bidir_node_iterator.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/safe_ctr_proxy.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
#include <boost/multi_index/detail/scope_guard.hpp>
|
||||
@@ -28,6 +33,7 @@
|
||||
#include <boost/multi_index/detail/seq_index_ops.hpp>
|
||||
#include <boost/multi_index/sequenced_index_fwd.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
@@ -80,47 +86,50 @@ class sequenced_index:
|
||||
#pragma parse_mfunc_templ off
|
||||
#endif
|
||||
|
||||
typedef typename SuperMeta::type super;
|
||||
typedef typename SuperMeta::type super;
|
||||
|
||||
protected:
|
||||
typedef sequenced_index_node<
|
||||
typename super::node_type> node_type;
|
||||
typename super::node_type> node_type;
|
||||
|
||||
private:
|
||||
typedef typename node_type::impl_type node_impl_type;
|
||||
|
||||
public:
|
||||
/* types */
|
||||
|
||||
typedef typename node_type::value_type value_type;
|
||||
typedef tuples::null_type ctor_args;
|
||||
typedef typename super::final_allocator_type allocator_type;
|
||||
typedef typename allocator_type::reference reference;
|
||||
typedef typename allocator_type::const_reference const_reference;
|
||||
typedef typename node_type::value_type value_type;
|
||||
typedef tuples::null_type ctor_args;
|
||||
typedef typename super::final_allocator_type allocator_type;
|
||||
typedef typename allocator_type::reference reference;
|
||||
typedef typename allocator_type::const_reference const_reference;
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
typedef safe_mode::safe_iterator<
|
||||
bidir_node_iterator<node_type>,
|
||||
safe_ctr_proxy<
|
||||
bidir_node_iterator<node_type> > > iterator;
|
||||
bidir_node_iterator<node_type> > > iterator;
|
||||
#else
|
||||
typedef safe_mode::safe_iterator<
|
||||
bidir_node_iterator<node_type>,
|
||||
sequenced_index> iterator;
|
||||
sequenced_index> iterator;
|
||||
#endif
|
||||
#else
|
||||
typedef bidir_node_iterator<node_type> iterator;
|
||||
typedef bidir_node_iterator<node_type> iterator;
|
||||
#endif
|
||||
|
||||
typedef iterator const_iterator;
|
||||
typedef iterator const_iterator;
|
||||
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
typedef typename
|
||||
boost::reverse_iterator<iterator> reverse_iterator;
|
||||
boost::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef typename
|
||||
boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef TagList tag_list;
|
||||
boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef TagList tag_list;
|
||||
|
||||
protected:
|
||||
typedef typename super::final_node_type final_node_type;
|
||||
@@ -174,9 +183,7 @@ public:
|
||||
template <class InputIterator>
|
||||
void assign(InputIterator first,InputIterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
clear();
|
||||
for(;first!=last;++first)push_back(*first);
|
||||
assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
|
||||
}
|
||||
|
||||
void assign(size_type n,value_param_type value)
|
||||
@@ -203,6 +210,20 @@ public:
|
||||
const_reverse_iterator rbegin()const{return make_reverse_iterator(end());}
|
||||
reverse_iterator rend(){return make_reverse_iterator(begin());}
|
||||
const_reverse_iterator rend()const{return make_reverse_iterator(begin());}
|
||||
const_iterator cbegin()const{return begin();}
|
||||
const_iterator cend()const{return end();}
|
||||
const_reverse_iterator crbegin()const{return rbegin();}
|
||||
const_reverse_iterator crend()const{return rend();}
|
||||
|
||||
iterator iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(&x));
|
||||
}
|
||||
|
||||
/* capacity */
|
||||
|
||||
@@ -215,8 +236,15 @@ public:
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
if(n>size())insert(end(),n-size(),x);
|
||||
else if(n<size()){
|
||||
iterator it=begin();
|
||||
std::advance(it,n);
|
||||
iterator it;
|
||||
if(n<=size()/2){
|
||||
it=begin();
|
||||
std::advance(it,n);
|
||||
}
|
||||
else{
|
||||
it=end();
|
||||
for(size_type m=size()-n;m--;--it){}
|
||||
}
|
||||
erase(it,end());
|
||||
}
|
||||
}
|
||||
@@ -260,8 +288,7 @@ public:
|
||||
template<typename InputIterator>
|
||||
void insert(iterator position,InputIterator first,InputIterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
for(;first!=last;++first)insert(position,*first);
|
||||
insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
|
||||
}
|
||||
|
||||
iterator erase(iterator position)
|
||||
@@ -319,6 +346,27 @@ public:
|
||||
mod,static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool modify(iterator position,Modifier mod,Rollback back)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
/* MSVC++ 6.0 optimizer on safe mode code chokes if this
|
||||
* this is not added. Left it for all compilers as it does no
|
||||
* harm.
|
||||
*/
|
||||
|
||||
position.detach();
|
||||
#endif
|
||||
|
||||
return this->final_modify_(
|
||||
mod,back,static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
void swap(sequenced_index<SuperMeta,TagList>& x)
|
||||
{
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
@@ -354,7 +402,7 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
if(x==*this){
|
||||
if(&x==this){
|
||||
if(position!=i)relink(position.get_node(),i.get_node());
|
||||
}
|
||||
else{
|
||||
@@ -387,7 +435,7 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
if(x==*this){
|
||||
if(&x==this){
|
||||
BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
|
||||
if(position!=last)relink(
|
||||
position.get_node(),first.get_node(),last.get_node());
|
||||
@@ -450,7 +498,7 @@ public:
|
||||
void reverse()
|
||||
{
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
sequenced_index_node_impl::reverse(header()->impl());
|
||||
node_impl_type::reverse(header()->impl());
|
||||
}
|
||||
|
||||
/* rearrange operations */
|
||||
@@ -501,6 +549,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
sequenced_index(const sequenced_index<SuperMeta,TagList>& x):
|
||||
super(x)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe_super()
|
||||
#endif
|
||||
|
||||
{
|
||||
/* The actual copying takes place in subsequent call to copy_().
|
||||
*/
|
||||
@@ -577,7 +630,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
empty_initialize();
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::detach_all_iterators();
|
||||
safe_super::detach_dereferenceable_iterators();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -621,6 +674,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_rollback_(node_type* x)
|
||||
{
|
||||
return super::modify_rollback_(x);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
|
||||
@@ -682,22 +740,22 @@ private:
|
||||
|
||||
void link(node_type* x)
|
||||
{
|
||||
sequenced_index_node_impl::link(x->impl(),header()->impl());
|
||||
node_impl_type::link(x->impl(),header()->impl());
|
||||
};
|
||||
|
||||
static void unlink(node_type* x)
|
||||
{
|
||||
sequenced_index_node_impl::unlink(x->impl());
|
||||
node_impl_type::unlink(x->impl());
|
||||
}
|
||||
|
||||
static void relink(node_type* position,node_type* x)
|
||||
{
|
||||
sequenced_index_node_impl::relink(position->impl(),x->impl());
|
||||
node_impl_type::relink(position->impl(),x->impl());
|
||||
}
|
||||
|
||||
static void relink(node_type* position,node_type* first,node_type* last)
|
||||
{
|
||||
sequenced_index_node_impl::relink(
|
||||
node_impl_type::relink(
|
||||
position->impl(),first->impl(),last->impl());
|
||||
}
|
||||
|
||||
@@ -718,6 +776,38 @@ private:
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class InputIterator>
|
||||
void assign_iter(InputIterator first,InputIterator last,mpl::true_)
|
||||
{
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
clear();
|
||||
for(;first!=last;++first)push_back(*first);
|
||||
}
|
||||
|
||||
void assign_iter(size_type n,value_param_type value,mpl::false_)
|
||||
{
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
clear();
|
||||
for(size_type i=0;i<n;++i)push_back(value);
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
void insert_iter(
|
||||
iterator position,InputIterator first,InputIterator last,mpl::true_)
|
||||
{
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
for(;first!=last;++first)insert(position,*first);
|
||||
}
|
||||
|
||||
void insert_iter(
|
||||
iterator position,size_type n,value_param_type x,mpl::false_)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
for(size_type i=0;i<n;++i)insert(position,x);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
#pragma parse_mfunc_templ reset
|
||||
@@ -828,6 +918,16 @@ struct sequenced
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
/* Boost.Foreach compatibility */
|
||||
|
||||
template<typename SuperMeta,typename TagList>
|
||||
inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
||||
boost::multi_index::detail::sequenced_index<SuperMeta,TagList>*&,
|
||||
boost::foreach::tag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Multiply indexed container.
|
||||
*
|
||||
* Copyright 2003-2006 Joaquín M López Muñoz.
|
||||
* Copyright 2003-2011 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -29,9 +29,9 @@
|
||||
#include <boost/mpl/deref.hpp>
|
||||
#include <boost/multi_index_container_fwd.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/adl_swap.hpp>
|
||||
#include <boost/multi_index/detail/base_type.hpp>
|
||||
#include <boost/multi_index/detail/converter.hpp>
|
||||
#include <boost/multi_index/detail/def_ctor_tuple_cons.hpp>
|
||||
#include <boost/multi_index/detail/header_holder.hpp>
|
||||
#include <boost/multi_index/detail/has_tag.hpp>
|
||||
#include <boost/multi_index/detail/no_duplicate_tags.hpp>
|
||||
@@ -44,8 +44,11 @@
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/multi_index/detail/archive_constructed.hpp>
|
||||
#include <boost/multi_index/detail/serialization_version.hpp>
|
||||
#include <boost/serialization/collection_size_type.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#endif
|
||||
|
||||
@@ -72,8 +75,14 @@ class multi_index_container:
|
||||
Value,IndexSpecifierList,Allocator>::type
|
||||
>::type>,
|
||||
BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder<
|
||||
typename detail::multi_index_node_type<
|
||||
Value,IndexSpecifierList,Allocator>::type,
|
||||
typename detail::prevent_eti<
|
||||
Allocator,
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
typename detail::multi_index_node_type<
|
||||
Value,IndexSpecifierList,Allocator>::type
|
||||
>::type
|
||||
>::type::pointer,
|
||||
multi_index_container<Value,IndexSpecifierList,Allocator> >,
|
||||
public detail::multi_index_base_type<
|
||||
Value,IndexSpecifierList,Allocator>::type
|
||||
@@ -91,19 +100,24 @@ class multi_index_container:
|
||||
private:
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template <typename,typename,typename> friend class detail::index_base;
|
||||
template <typename,typename> friend class detail::header_holder;
|
||||
template <typename,typename> friend class detail::converter;
|
||||
template <typename,typename> friend struct detail::header_holder;
|
||||
template <typename,typename> friend struct detail::converter;
|
||||
#endif
|
||||
|
||||
typedef typename detail::multi_index_base_type<
|
||||
Value,IndexSpecifierList,Allocator>::type super;
|
||||
typedef ::boost::base_from_member<
|
||||
typename boost::detail::allocator::rebind_to<
|
||||
typedef typename
|
||||
boost::detail::allocator::rebind_to<
|
||||
Allocator,
|
||||
typename super::node_type
|
||||
>::type> bfm_allocator;
|
||||
>::type node_allocator;
|
||||
typedef ::boost::base_from_member<
|
||||
node_allocator> bfm_allocator;
|
||||
typedef detail::header_holder<
|
||||
typename super::node_type,
|
||||
typename detail::prevent_eti<
|
||||
Allocator,
|
||||
node_allocator
|
||||
>::type::pointer,
|
||||
multi_index_container> bfm_header;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
@@ -116,15 +130,8 @@ public:
|
||||
* brought forward here to save us some typename's.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
typedef
|
||||
detail::default_constructible_tuple_cons<
|
||||
typename super::ctor_args_list> ctor_args_list;
|
||||
#else
|
||||
typedef typename super::ctor_args_list ctor_args_list;
|
||||
#endif
|
||||
|
||||
typedef IndexSpecifierList index_specifier_type_list;
|
||||
typedef typename super::ctor_args_list ctor_args_list;
|
||||
typedef IndexSpecifierList index_specifier_type_list;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
/* MSVC++ 6.0 chokes on moderately long index lists (around 6 indices
|
||||
@@ -189,6 +196,14 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
explicit multi_index_container(const allocator_type& al):
|
||||
bfm_allocator(al),
|
||||
super(ctor_args_list(),bfm_allocator::member),
|
||||
node_count(0)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
multi_index_container(
|
||||
InputIterator first,InputIterator last,
|
||||
@@ -230,6 +245,7 @@ public:
|
||||
multi_index_container(
|
||||
const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
|
||||
bfm_allocator(x.bfm_allocator::member),
|
||||
bfm_header(),
|
||||
super(x),
|
||||
node_count(0)
|
||||
{
|
||||
@@ -254,11 +270,10 @@ public:
|
||||
}
|
||||
|
||||
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
|
||||
const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
|
||||
multi_index_container<Value,IndexSpecifierList,Allocator> x)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_INVARIANT;
|
||||
multi_index_container<Value,IndexSpecifierList,Allocator> tmp(x);
|
||||
this->swap(tmp);
|
||||
this->swap(x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -347,8 +362,10 @@ public:
|
||||
{
|
||||
typedef typename nth_index<N>::type index;
|
||||
|
||||
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
|
||||
BOOST_STATIC_ASSERT(
|
||||
(mpl::contains<iterator_type_list,IteratorType>::value));
|
||||
#endif
|
||||
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(
|
||||
@@ -364,9 +381,11 @@ public:
|
||||
{
|
||||
typedef typename nth_index<N>::type index;
|
||||
|
||||
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
|
||||
BOOST_STATIC_ASSERT((
|
||||
mpl::contains<iterator_type_list,IteratorType>::value||
|
||||
mpl::contains<const_iterator_type_list,IteratorType>::value));
|
||||
#endif
|
||||
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(
|
||||
@@ -397,8 +416,10 @@ public:
|
||||
{
|
||||
typedef typename index<Tag>::type index;
|
||||
|
||||
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
|
||||
BOOST_STATIC_ASSERT(
|
||||
(mpl::contains<iterator_type_list,IteratorType>::value));
|
||||
#endif
|
||||
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(
|
||||
@@ -413,9 +434,11 @@ public:
|
||||
{
|
||||
typedef typename index<Tag>::type index;
|
||||
|
||||
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
|
||||
BOOST_STATIC_ASSERT((
|
||||
mpl::contains<iterator_type_list,IteratorType>::value||
|
||||
mpl::contains<const_iterator_type_list,IteratorType>::value));
|
||||
#endif
|
||||
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(
|
||||
@@ -429,17 +452,18 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
node_type* header()const
|
||||
{
|
||||
return bfm_header::member;
|
||||
return &*bfm_header::member;
|
||||
}
|
||||
|
||||
node_type* allocate_node()
|
||||
{
|
||||
return bfm_allocator::member.allocate(1);
|
||||
return &*bfm_allocator::member.allocate(1);
|
||||
}
|
||||
|
||||
void deallocate_node(node_type* x)
|
||||
{
|
||||
bfm_allocator::member.deallocate(x,1);
|
||||
typedef typename node_allocator::pointer node_pointer;
|
||||
bfm_allocator::member.deallocate(static_cast<node_pointer>(x),1);
|
||||
}
|
||||
|
||||
bool empty_()const
|
||||
@@ -501,9 +525,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
void erase_(node_type* x)
|
||||
{
|
||||
--node_count;
|
||||
super::erase_(x);
|
||||
deallocate_node(x);
|
||||
--node_count;
|
||||
}
|
||||
|
||||
void delete_node_(node_type* x)
|
||||
@@ -526,6 +550,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
|
||||
{
|
||||
if(bfm_allocator::member!=x.bfm_allocator::member){
|
||||
detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member);
|
||||
}
|
||||
std::swap(bfm_header::member,x.bfm_header::member);
|
||||
super::swap_(x);
|
||||
std::swap(node_count,x.node_count);
|
||||
@@ -537,7 +564,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
}
|
||||
|
||||
template<typename Modifier>
|
||||
bool modify_(Modifier mod,node_type* x)
|
||||
bool modify_(Modifier& mod,node_type* x)
|
||||
{
|
||||
mod(const_cast<value_type&>(x->value()));
|
||||
|
||||
@@ -557,6 +584,42 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template<typename Modifier,typename Rollback>
|
||||
bool modify_(Modifier& mod,Rollback& back,node_type* x)
|
||||
{
|
||||
mod(const_cast<value_type&>(x->value()));
|
||||
|
||||
bool b;
|
||||
BOOST_TRY{
|
||||
b=super::modify_rollback_(x);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
BOOST_TRY{
|
||||
back(const_cast<value_type&>(x->value()));
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->erase_(x);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
|
||||
BOOST_TRY{
|
||||
if(!b){
|
||||
back(const_cast<value_type&>(x->value()));
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->erase_(x);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
|
||||
@@ -570,11 +633,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
template<class Archive>
|
||||
void save(Archive& ar,const unsigned int version)const
|
||||
{
|
||||
const std::size_t s=size_();
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
const serialization::collection_size_type s(size_());
|
||||
const detail::serialization_version<value_type> value_version;
|
||||
ar<<serialization::make_nvp("count",s);
|
||||
ar<<serialization::make_nvp("value_version",value_version);
|
||||
#else
|
||||
const std::size_t s=size_();
|
||||
const unsigned int value_version=0;
|
||||
ar<<serialization::make_nvp("count",s);
|
||||
#endif
|
||||
|
||||
index_saver_type sm(bfm_allocator::member,s);
|
||||
|
||||
for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){
|
||||
serialization::save_construct_data_adl(ar,&*it,value_version);
|
||||
ar<<serialization::make_nvp("item",*it);
|
||||
sm.add(it.get_node(),ar,version);
|
||||
}
|
||||
@@ -590,12 +664,33 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
clear_();
|
||||
|
||||
std::size_t s;
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
serialization::collection_size_type s;
|
||||
detail::serialization_version<value_type> value_version;
|
||||
if(version<1){
|
||||
std::size_t sz;
|
||||
ar>>serialization::make_nvp("count",sz);
|
||||
s=static_cast<serialization::collection_size_type>(sz);
|
||||
}
|
||||
else{
|
||||
ar>>serialization::make_nvp("count",s);
|
||||
}
|
||||
if(version<2){
|
||||
value_version=0;
|
||||
}
|
||||
else{
|
||||
ar>>serialization::make_nvp("value_version",value_version);
|
||||
}
|
||||
#else
|
||||
std::size_t s;
|
||||
unsigned int value_version=0;
|
||||
ar>>serialization::make_nvp("count",s);
|
||||
#endif
|
||||
|
||||
index_loader_type lm(bfm_allocator::member,s);
|
||||
|
||||
for(std::size_t n=0;n<s;++n){
|
||||
detail::archive_constructed<Value> value("item",ar,version);
|
||||
detail::archive_constructed<Value> value("item",ar,value_version);
|
||||
std::pair<node_type*,bool> p=insert_(
|
||||
value.get(),super::end().get_node());
|
||||
if(!p.second)throw_exception(
|
||||
@@ -786,7 +881,8 @@ project(
|
||||
Value,IndexSpecifierList,Allocator> multi_index_type;
|
||||
typedef typename nth_index<multi_index_type,N>::type index;
|
||||
|
||||
#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
|
||||
#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
|
||||
(!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
|
||||
BOOST_STATIC_ASSERT((
|
||||
mpl::contains<
|
||||
BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
|
||||
@@ -820,7 +916,8 @@ project(
|
||||
Value,IndexSpecifierList,Allocator> multi_index_type;
|
||||
typedef typename nth_index<multi_index_type,N>::type index;
|
||||
|
||||
#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
|
||||
#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
|
||||
(!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
|
||||
BOOST_STATIC_ASSERT((
|
||||
mpl::contains<
|
||||
BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
|
||||
@@ -874,7 +971,8 @@ project(
|
||||
typedef typename ::boost::multi_index::index<
|
||||
multi_index_type,Tag>::type index;
|
||||
|
||||
#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
|
||||
#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
|
||||
(!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
|
||||
BOOST_STATIC_ASSERT((
|
||||
mpl::contains<
|
||||
BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
|
||||
@@ -909,7 +1007,8 @@ project(
|
||||
typedef typename ::boost::multi_index::index<
|
||||
multi_index_type,Tag>::type index;
|
||||
|
||||
#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
|
||||
#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
|
||||
(!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
|
||||
BOOST_STATIC_ASSERT((
|
||||
mpl::contains<
|
||||
BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
|
||||
@@ -1012,6 +1111,24 @@ void swap(
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)&&\
|
||||
!defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
/* class version = 1 : we now serialize the size through
|
||||
* boost::serialization::collection_size_type.
|
||||
* class version = 2 : proper use of {save|load}_construct_data.
|
||||
*/
|
||||
|
||||
namespace serialization {
|
||||
template<typename Value,typename IndexSpecifierList,typename Allocator>
|
||||
struct version<
|
||||
boost::multi_index_container<Value,IndexSpecifierList,Allocator>
|
||||
>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int,value=2);
|
||||
};
|
||||
} /* namespace serialization */
|
||||
#endif
|
||||
|
||||
/* Associated global functions are promoted to namespace boost, except
|
||||
* comparison operators and swap, which are meant to be Koenig looked-up.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2005 Joaqu匤 M L�ez Mu�z.
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user