Compare commits

...

58 Commits

Author SHA1 Message Date
Beman Dawes 2a29d4ac2f Release 1.50.0
[SVN r79156]
2012-06-28 12:37:29 +00:00
Joaquín M López Muñoz b35a722129 merged [75643] from trunk
[SVN r75691]
2011-11-27 13:52:14 +00:00
Joaquín M López Muñoz 67f9c5b3ab merged [73498] from trunk
[SVN r73518]
2011-08-03 21:03:48 +00:00
Joaquín M López Muñoz 026fab85aa merged [71770] from trunk
[SVN r71810]
2011-05-08 11:38:13 +00:00
Joaquín M López Muñoz 71fbbf1754 merged [71671] from trunk
[SVN r71768]
2011-05-06 19:47:26 +00:00
Joaquín M López Muñoz 84e34e45c3 merged [69540], [69632] and [69720] from trunk
[SVN r71767]
2011-05-06 19:38:25 +00:00
Joaquín M López Muñoz 768432afcb merged [61482] from trunk
[SVN r64324]
2010-07-25 10:44:55 +00:00
Joaquín M López Muñoz 48eab15fc0 merged [64322] from trunk
[SVN r64323]
2010-07-25 10:19:38 +00:00
Joaquín M López Muñoz 13842a23dc merged [64317] from trunk
[SVN r64318]
2010-07-24 19:36:50 +00:00
Joaquín M López Muñoz e4771a0fae merged [64312] from trunk
[SVN r64313]
2010-07-24 09:20:29 +00:00
Joaquín M López Muñoz eb1f2a98b7 merged [59582] from trunk
[SVN r59638]
2010-02-11 19:28:27 +00:00
Joaquín M López Muñoz 215d795984 merged [58485] and [59443] from trunk
[SVN r59525]
2010-02-06 14:38:28 +00:00
Joaquín M López Muñoz efce67f27b reverted [58517]
[SVN r58847]
2010-01-09 18:17:59 +00:00
Joaquín M López Muñoz 5fd288b095 merged [58485] from trunk
[SVN r58517]
2009-12-23 18:01:35 +00:00
Joaquín M López Muñoz 588e7657f3 merged [57541] and [58472] from trunk
[SVN r58473]
2009-12-21 10:23:36 +00:00
Troy D. Straszheim d2efd9d5ed rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Joaquín M López Muñoz b185884ffe merged [56829] from trunk
[SVN r56831]
2009-10-14 16:13:13 +00:00
Joaquín M López Muñoz f88fb07ae8 merged [56354] from trunk
[SVN r56385]
2009-09-26 12:54:43 +00:00
Joaquín M López Muñoz 718559b87f merged [55994] and [55995] from trunk
[SVN r56111]
2009-09-08 20:20:35 +00:00
Troy D. Straszheim 180f64dc11 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Joaquín M López Muñoz ff51956131 merged [55055] and [55058] from trunk
[SVN r55081]
2009-07-22 15:16:28 +00:00
Joaquín M López Muñoz 3199ff1b44 merged up to [53676] from trunk
[SVN r53730]
2009-06-07 18:44:00 +00:00
Joaquín M López Muñoz 6d2c3985f0 merged rev [52078] from trunk
[SVN r52101]
2009-04-01 08:45:12 +00:00
Troy D. Straszheim d3e74bc941 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Joaquín M López Muñoz f5976c1695 merged rev. 50321 from trunk
[SVN r50328]
2008-12-19 19:11:40 +00:00
Joaquín M López Muñoz b61b58abfa merged up to rev. 49674 from trunk
[SVN r50300]
2008-12-16 21:00:30 +00:00
Joaquín M López Muñoz d026f22be0 merged rev. 49142 from trunk
[SVN r49148]
2008-10-06 17:54:07 +00:00
Joaquín M López Muñoz 8c5ac57c6a merged rev. 48728 from trunk
[SVN r48774]
2008-09-14 16:36:06 +00:00
Joaquín M López Muñoz df5eb5b646 merged rev. 48444 from trunk
[SVN r48513]
2008-09-01 15:27:55 +00:00
Joaquín M López Muñoz c2d5785ae8 merged rev. 47225 from trunk
[SVN r47234]
2008-07-08 16:38:25 +00:00
Joaquín M López Muñoz ebf92487ae merged rev. 47071 from trunk
[SVN r47076]
2008-07-04 15:08:59 +00:00
Joaquín M López Muñoz bd8ea1bc86 merged up to rev. 47041 from trunk
[SVN r47045]
2008-07-03 16:51:53 +00:00
Joaquín M López Muñoz 93da3b3f29 merged rev. 43157 from trunk
[SVN r43158]
2008-02-07 16:50:11 +00:00
Joaquín M López Muñoz faf18a55f0 merged rev. 41397 from trunk
[SVN r41513]
2007-11-30 21:09:14 +00:00
Beman Dawes 0468378c0d Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes 9b4c07478c Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes 1434c7d727 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody 33e19c4ce1 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Joaquín M. López Muñoz 47079d4620 merged from trunk to branch
[SVN r37105]
2007-02-27 07:49:12 +00:00
Joaquín M. López Muñoz 543fbad471 merged from trunk to branch
[SVN r37079]
2007-02-26 09:16:36 +00:00
Joaquín M. López Muñoz 5d2015ed2e merged from trunk to branch
[SVN r37050]
2007-02-23 16:16:28 +00:00
Joaquín M. López Muñoz add267a90a merged from trunk to branch
[SVN r36776]
2007-01-24 18:21:23 +00:00
Joaquín M. López Muñoz de9febb387 merged from trunk to branch
[SVN r36480]
2006-12-21 12:01:02 +00:00
nobody 93d21ea64c This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r35900]
2006-11-07 14:41:23 +00:00
Rene Rivera 28930f64c0 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Joaquín M. López Muñoz 6418bd5e83 merged from trunk to branch
[SVN r35634]
2006-10-16 17:40:23 +00:00
Joaquín M. López Muñoz e46279d9ec merged from trunk to branch
[SVN r35444]
2006-10-02 15:20:03 +00:00
Joaquín M. López Muñoz 99284aa1c5 merged from trunk to branch
[SVN r34743]
2006-07-26 15:12:41 +00:00
Joaquín M. López Muñoz c41ded0890 merged from trunk to branch
[SVN r34604]
2006-07-20 06:19:59 +00:00
Joaquín M. López Muñoz 0c0acfaa3f merged from trunk to branch
[SVN r34527]
2006-07-13 07:57:18 +00:00
Joaquín M. López Muñoz 5c5ca84a23 merged from trunk to branch
[SVN r34022]
2006-05-19 06:57:13 +00:00
Joaquín M. López Muñoz 48764f7801 merged from trunk to branch
[SVN r33915]
2006-05-03 09:30:45 +00:00
Joaquín M. López Muñoz f91af5453c merged from trunk to branch
[SVN r33760]
2006-04-21 13:09:37 +00:00
Joaquín M. López Muñoz 87383bcc10 merged from trunk to branch
[SVN r33742]
2006-04-19 07:23:16 +00:00
Joaquín M. López Muñoz d7f2c3606b merged from trunk to branch
[SVN r33734]
2006-04-18 17:01:51 +00:00
Joaquín M. López Muñoz 3a663bd7c4 merged from trunk to branch
[SVN r33545]
2006-04-05 07:28:50 +00:00
Joaquín M. López Muñoz 37ac7c0377 merged from trunk to branch
[SVN r33430]
2006-03-22 07:25:04 +00:00
nobody 75de04b6f8 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
179 changed files with 5514 additions and 1777 deletions
-16
View File
@@ -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 ;
+30 -3
View File
@@ -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&iacute;nez Aguerre
suggested the inclusion of
<a href="tutorial/indices.html#iterator_to"><code>iterator_to</code></a>. The
rollback versions of <code>modify</code> and <code>modify_key</code> arose
from discussions with Mat&iacute;as Capeletto. Steven Watanabe spotted an
include guard bug present from the first release of the library.
</p>
<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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+177 -95
View File
@@ -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>&lt;xlocnum></code>
Replace line 84 of <code>&lt;xlocnum&gt;</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&lt;0&gt;::type</code>
Then, for instance, the type <code>employee_set::nth_index&lt;0&gt;::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&lt;0&gt;::type</code>
Applying this technique, <code>employee_set::nth_index&lt;0&gt;::type</code>
now becomes:
</p>
@@ -1030,9 +1112,9 @@ Performance
<br>
<p>Revised February 6th 2006</p>
<p>Revised October 14th 2009</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+36 -12
View File
@@ -31,7 +31,7 @@ Tests
<ul>
<li><a href="#example1">Example 1: basic usage</a></li>
<li><a href="#example2">Example 2: using member functions as keys</a></li>
<li><a href="#example2">Example 2: using functions as keys</a></li>
<li><a href="#example3">Example 3: constructing <code>multi_index_container</code>s
with <code>ctor_args_list</code></a></li>
<li><a href="#example4">Example 4: bidirectional map</a></li>
@@ -42,6 +42,7 @@ Tests
<li><a href="#example9">Example 9: serialization and MRU lists</a></li>
<li><a href="#example10">Example 10: random access indices</a></li>
<li><a href="#example11">Example 11: index rearrangement</a></li>
<li><a href="#example12">Example 12: using Boost.Interprocess allocators</a></li>
</ul>
<h2><a name="example1">Example 1: basic usage</a></h2>
@@ -55,23 +56,23 @@ Basic program showing the multi-indexing capabilities of Boost.MultiIndex
with an admittedly boring set of <code>employee</code> records.
</p>
<h2><a name="example2">Example 2: using member functions as keys</a></h2>
<h2><a name="example2">Example 2: using functions as keys</a></h2>
<p>
See <a href="../example/memfun_key.cpp">source code</a>.
See <a href="../example/fun_key.cpp">source code</a>.
</p>
<p>
Usually keys assigned to an index are based on a member variable of the
element, but key extractors can be defined which take their value from
a member function. This has some similarity with the concept of
a member function or a global function. This has some similarity with the concept of
<i>calculated keys</i> supported by some relational database engines.
The example shows how to use the predefined <code>const_mem_fun</code>
key extractor to deal with this situation.
and <code>global_fun</code> key extractors to deal with this situation.
</p>
<p>
Keys based on member functions usually will not be actual references,
Keys based on functions usually will not be actual references,
but rather the temporary values resulting from the invocation of the
member function used. This implies that <code>modify_key</code> cannot be
applied to this type of extractors, which is a perfectly logical
@@ -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&lt;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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+2 -16
View File
@@ -41,7 +41,6 @@ principle driving the current internal design of <code>multi_index_container</co
<li><a href="#notifying">Notifying indices</a></li>
<li><a href="#constraints">Constraints</a></li>
<li><a href="#user_defined_indices">User-defined indices</a></li>
<li><a href="#bimap">Bidirectional map</a></li>
<li><a href="#indexed_maps">Indexed maps</a></li>
<li><a href="#move_semantics">Move semantics</a></li>
</ul>
@@ -150,19 +149,6 @@ simple enough to make them worth documenting so that the (bold)
user can write implementations for her own indices.
</p>
<h2><a name="bimap">Bidirectional map</a></h2>
<p>
<a href="examples.html#example4">Example 4</a> in the examples section
features a <i>bidirectional map</i>, implemented as a
<code>multi_index_container</code> with two unique ordered indices. This particular
structure is deemed important enough as to provide it as a separate
class template, relying internally in <code>multi_index_container</code>. As
feedback is collected from the users of Boost.MultiIndex, other singular
instantiations of <code>multi_index_container</code> might be encapsulated
to form a component library of ready to use containers.
</p>
<h2><a name="indexed_maps">Indexed maps</a></h2>
<p>
@@ -240,9 +226,9 @@ Release notes
<br>
<p>Revised February 6th 2006</p>
<p>Revised July 5th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+13 -13
View File
@@ -397,9 +397,9 @@ which is functionally equivalent to <code>std::set&lt;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&lt;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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
+128 -42
View File
@@ -44,9 +44,11 @@ Sequenced indices
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#types">Nested types</a></li>
<li><a href="#constructors">Constructors, copy and assignment</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#observers">Observers</a></li>
<li><a href="#lookup">Lookup</a></li>
<li><a href="#bucket_interface">Bucket interface</a></li>
<li><a href="#hash_policy">Hash policy</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
@@ -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>&lt;</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>&gt;</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// modifiers:</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
@@ -262,7 +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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
@@ -313,6 +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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_local_iterator</span> <span class=identifier>local_iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// hash policy:</span>
@@ -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&lt;&gt;</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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code>
@@ -459,7 +488,7 @@ one element can be causing insertion not to be allowed.<br>
<code>iterator insert(iterator position,const value_type&amp; 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&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
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&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, restores all keys of the element
to their original state.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below. 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&lt;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&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
<b>Effects:</b> Calls <code>mod(k)</code> where <code>k</code> is the key
obtained by the internal <code>KeyFromValue</code> object of the index from
the element pointed to by <code>position</code>, and rearranges
<code>*position</code> into all the indices of the <code>multi_index_container</code>.
Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, the element is erased.<br>
<b>Postconditions:</b>Validity of <code>position</code> is preserved if
the operation succeeds.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Basic. If an exception is thrown by some
user-provided operation (except possibly <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
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&lt;typename Modifier,typename Rollback><br>
bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> and <code>Rollback</code>
are models of <a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The sequence of operations <code>mod(k)</code>,
<code>back(k)</code>, where <code>k</code> is the key of the element
pointed to by <code>position</code>, restores k to its original state.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>,
with <code>mod'</code> and <code>back</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
<code>back'(x)</code> is the same as <code>back(key(x))</code>, where
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<h4><a name="observers">Observers</a></h4>
@@ -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&amp; 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&lt;iterator,iterator> equal_range(const CompatibleKey&amp; 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&lt;<br>
&nbsp;&nbsp;typename CompatibleKey,typename CompatibleHash, typename CompatiblePred<br>
&gt;<br>
std::pair&lt;iterator,iterator> equal_range(</br>
std::pair&lt;iterator,iterator> equal_range(<br>
&nbsp;&nbsp;const CompatibleKey&amp; x,<br>
&nbsp;&nbsp;const CompatibleHash&amp; hash,const CompatiblePred&amp; eq)const;
</code>
@@ -784,13 +857,26 @@ std::pair&lt;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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_iterator_to(const value_type&amp; x);<br>
const_local_iterator local_iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="hash_policy">Hash policy</a></h4>
@@ -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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+5 -3
View File
@@ -88,7 +88,9 @@ The following dependencies among headers of Boost.MultiIndex hold:
<li><a href="key_extraction.html#member_synopsis">
<code>"boost/multi_index/member.hpp"</code></a>,</li>
<li><a href="key_extraction.html#mem_fun_synopsis">
<code>"boost/multi_index/mem_fun.hpp"</code></a> and</li>
<code>"boost/multi_index/mem_fun.hpp"</code></a>,</li>
<li><a href="key_extraction.html#global_fun_synopsis">
<code>"boost/multi_index/global_fun.hpp"</code></a> and</li>
<li><a href="key_extraction.html#composite_key_synopsis">
<code>"boost/multi_index/composite_key.hpp"</code></a>.</li>
</ul>
@@ -125,9 +127,9 @@ Index
<br>
<p>Revised February 6th 2005</p>
<p>Revised June 19th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+13 -3
View File
@@ -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>&lt;</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>&gt;</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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+184 -22
View File
@@ -63,6 +63,12 @@ Compiler specifics
<li><a href="#boost_multi_index_mem_fun">Macro <code>BOOST_MULTI_INDEX_MEM_FUN</code></a></li>
</ul>
</li>
<li><a href="#global_fun_synopsis">Header
<code>"boost/multi_index/global_fun.hpp"</code> synopsis</a>
<ul>
<li><a href="#global_fun">Class template <code>global_fun</code></a></li>
</ul>
</li>
<li><a href="#composite_key_synopsis">Header
<code>"boost/multi_index/composite_key.hpp"</code> synopsis</a>
<ul>
@@ -131,12 +137,13 @@ for every <code>k1</code> of type <code>const KeyFromValue</code> and
</p>
<p>
Boost.MultiIndex provides five general-purpose key extractors:
Boost.MultiIndex provides six general-purpose key extractors:
<ul>
<li><a href="#identity"><code>identity</code></a>,</li>
<li><a href="#member"><code>member</code></a>,</li>
<li><a href="#const_mem_fun"><code>const_mem_fun</code></a>,</li>
<li><a href="#mem_fun"><code>mem_fun</code></a> and</li>
<li><a href="#mem_fun"><code>mem_fun</code></a>,</li>
<li><a href="#global_fun"><code>global_fun</code></a> and</li>
<li><a href="#composite_key"><code>composite_key</code></a>,</li>
</ul>
plus replacements for some of them:
@@ -178,6 +185,7 @@ ultimately dereferencing to values of <code>Type&amp;</code> or
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>identity</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>member</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>mem_fun</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>global_fun</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>composite_key</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
</pre></blockquote>
@@ -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&amp; is not convertible to const Type&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
@@ -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&amp; is not convertible to const Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
@@ -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&amp; is not convertible to const Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
@@ -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>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if const ChainedPtr is not convertible to const Class</span>
<span class=comment>// only provided if const ChainedPtr&amp; is not convertible to const Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
@@ -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>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if ChainedPtr is not convertible to Class</span>
<span class=comment>// only provided if ChainedPtr&amp; is not convertible to Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
@@ -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>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if const ChainedPtr is not convertible to const Class</span>
<span class=comment>// only provided if const ChainedPtr&amp; is not convertible to const Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
@@ -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>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if ChainedPtr is not convertible to Class</span>
<span class=comment>// only provided if ChainedPtr&amp; is not convertible to Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
@@ -769,6 +777,147 @@ but it resolves to
for MSVC++ 6.0 or lower.
</p>
<h2>
<a name="global_fun_synopsis">Header
<a href="../../../../boost/multi_index/global_fun.hpp">
<code>"boost/multi_index/global_fun.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>Type</span> <span class=special>(*</span><span class=identifier>PtrToFunction</span><span class=special>)(</span><span class=identifier>Value</span><span class=special>)&gt;</span>
<span class=keyword>struct</span> <span class=identifier>global_fun</span><span class=special>;</span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
<span class=special>}</span> <span class=comment>// namespace boost</span>
</pre></blockquote>
<h3><a name="global_fun">Class template <code>global_fun</code></a></h3>
<p>
<code>global_fun</code> is a <a href="#key_extractors"><code>Key Extractor</code></a>
based on a given global or static member function accepting the base type as argument
and returning the associated key.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>Type</span> <span class=special>(*</span><span class=identifier>PtrToFunction</span><span class=special>)(</span><span class=identifier>Value</span><span class=special>)&gt;</span>
<span class=keyword>struct</span> <span class=identifier>global_fun</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// Only provided under the following circumstances:
// - If Value is a reference to a constant type, only provided
// when const ChainedPtr&amp; is not convertible to Value;
// - if Value is a reference to a non-const type, only provided
// when ChainedPtr&amp; is not convertible to Value;
// - else, only provided when const ChainedPtr&amp; is not
// convertible to const Value&amp;.</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// only provided if Value is a reference type</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Value</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// only provided if Value is not a reference type</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// only provided if Value is not a reference type</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// only provided if Value is a reference type</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span>
<span class=identifier>remove_reference</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// only provided if Value is not a reference type or is
// a reference to a constant type</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>remove_const</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>PtrToFunction</code> specifies the particular function used to extract
the key of type <code>Type</code> from some <code>BaseType</code>.
<code>global_fun</code> supports the following function signatures:
<ul>
<li><code>Type f(BaseType)</code> (<code>Value</code> is <code>BaseType</code>),</li>
<li><code>Type f(const BaseType&amp;)</code> (<code>Value</code> is <code>const BaseType&amp;</code>),</li>
<li><code>Type f(BaseType&amp;)</code> (<code>Value</code> is <code>BaseType&amp;</code>).</li>
</ul>
<code>global_fun&lt;Type,Value,PtrToFunction&gt;</code> is a model of:
<ul>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from <code>reference_wrapper&lt;BaseType></code>,</li>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from any <a href="#chained_pointers">chained pointer</a>
to <code>BaseType</code>.</li>
</ul>
When <code>Value</code> is <code>BaseType</code> or
<code>const BaseType&amp;</code>,
<code>global_fun&lt;Type,Value,PtrToFunction&gt;</code> is also a model of:
<ul>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from <code>BaseType</code>,</li>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from <code>reference_wrapper&lt;const BaseType></code>,</li>
<li><a href="#key_extractors"><code>Key Extractor</code></a>
from any <a href="#chained_pointers">chained pointer</a>
to <code>const BaseType</code>.</li>
</ul>
</p>
<h4><code>global_fun</code> members</h4>
<code>template&lt;typename ChainedPtr> Type operator()(const ChainedPtr&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>ChainedPtr</code> is a <a href="#chained_pointers">chained pointer</a>
type to <code>Value</code>.<br>
<b>Returns:</b> <code>PtrToFunction)(y)</code>, where <code>y</code> is the
object chained-pointed to by <code>x</code>.
</blockquote>
<code>Type operator()(Value x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x)</code>.
</blockquote>
<code>Type operator()(const Value&amp; x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x)</code>.
</blockquote>
<code>Type operator()(const reference_wrapper&lt;const Value&gt;&amp; x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x.get())</code>.
</blockquote>
<code>
Type operator()(<br>
&nbsp;&nbsp;const reference_wrapper&lt;remove_reference&lt;Value&gt;::type&gt;&amp; x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x.get())</code>.
</blockquote>
<code>Type operator()(<br>
&nbsp;&nbsp;const reference_wrapper&lt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;typename remove_const&lt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename remove_reference&lt;Value&gt;::type&gt;::type&gt;&amp; x)const;</code>
<blockquote>
<b>Returns:</b> <code>PtrToFunction(x.get())</code>.
</blockquote>
<h2>
<a name="composite_key_synopsis">Header
<a href="../../../../boost/multi_index/composite_key.hpp">
@@ -787,7 +936,7 @@ for MSVC++ 6.0 or lower.
<span class=comment>// comparison operators for composite_key_result:</span>
<span class=comment>// <b>OP</b> is any of =,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=comment>// <b>OP</b> is any of ==,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
@@ -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>&amp;</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>&amp;</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&amp; is not convertible to const value_type&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span>
<span class=identifier>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>&amp;</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 =,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=comment>// <b>OP</b> is any of ==,&lt;,!=,&gt;,&gt;=,&lt;=</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
@@ -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>&lt;y<sub>i</sub></code> and
<code>y<sub>i</sub>&lt;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&lt;i>()(x<sub>i</sub>,y<sub>i</sub>)</code> and
<code>key_eqs().get&lt;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&lt;i>()(x<sub>i</sub>,y<sub>i</sub>)</code>
@@ -1534,7 +1683,7 @@ bool operator()(<br>
<code>key_comps().get&lt;i>()(x<sub>i</sub>,y<sub>i</sub>)</code> and
<code>key_comps().get&lt;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&lt;composite_key&lt;K0,...,Kk> ></code>, with
<code>Ki::result_type = Qi</code> for all <code>i = 0,...,k</code>.
</blockquote>
provided that each <code>Qi</code> is either <code>Ti</code> or a
<a href="ord_indices.html#set_operations"><code>Compatible Key</code></a>
of <code>Comparei</code>. In this case, the comparison is done
provided that
<ul>
<li>for <code>i = 0,...,min(j,k)-1</code>, <code>Qi</code> is either <code>Ti</code>
or <i>not coarser</i> than <code>Ti</code> (<code>Qi</code> is a
<a href="ord_indices.html#set_operations"><code>Compatible Key</code></a>
of <code>Comparei</code> and there are no two distinct elements of
<code>Ti</code> equivalent to one single element of <code>Qi</code>);
</li>
<li>
<code>Qm</code> (with <code>m = min(j,k)</code>) is either <code>Tm</code> or a
<a href="ord_indices.html#set_operations"><code>Compatible Key</code></a>
of <code>Comparem</code>.
</li>
</ul>
In this case, the comparison is done
lexicographically only on the first <code>1+min(j,k)</code> elements.
</p>
@@ -2101,9 +2263,9 @@ Compiler specifics
<br>
<p>Revised February 6th 2006</p>
<p>Revised June 25th 2008</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+117 -69
View File
@@ -99,10 +99,15 @@ synopsis</a>
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</span> <span class=keyword>struct</span> <span class=identifier>nth_index</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</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>&lt;</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>&gt;</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>&lt;</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>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</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>&lt;</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>&gt;</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>&lt;</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>&gt;</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>&lt;</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>&gt;</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>&lt;</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>&gt;</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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>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>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>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>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_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>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_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>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
<span class=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>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_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>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_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>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index_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>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
<span class=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>&amp;</span> <span class=identifier>al</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=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>&lt;</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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</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>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</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>&lt;</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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</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>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</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>&lt;</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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</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>&lt;</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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</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>&lt;</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>&gt;</span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span>
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</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>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</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>&lt;</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>&gt;</span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span>
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</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>&lt;</span><span class=identifier>N</span><span class=special>&gt;::</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>&lt;</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>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span>
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</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>&lt;</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>&gt;</span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span>
<span class=keyword>template</span><span class=special>&lt;</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>&gt;</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;::</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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>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>&lt;</span><span class=identifier>N</span><span class=special>&gt;(</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>&lt;</span><span class=identifier>N</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>N</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>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>&lt;</span><span class=identifier>N</span><span class=special>&gt;(</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>&lt;</span><span class=identifier>N</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;(</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>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>&gt;</span>
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special>&lt;</span>
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special>&lt;</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;,</span><span class=identifier>Tag</span>
<span class=special>&gt;::</span><span class=identifier>type</span>
<span class=special>&gt;::</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>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;(</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>&lt;</span><span class=identifier>Tag</span><span class=special>&gt;(</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&lt;T&gt;::other::pointer</code> can be any
kind of
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html"><code>Random
Access Iterator</code></a>, provided that it is explicitly constructible from
the literal <code>0</code> (standing here as the null pointer) or from any
<code>p</code> of type <code>T*</code> pointing into an area allocated by
some instance of <code>Allocator</code> or some other allocator type rebound
from <code>Allocator</code>. A <code>pointer</code> constructed from
<code>p</code> shall dereference to <code>*p</code>.
</li>
</ul>
</li>
</ol>
Indices of a given <code>multi_index_container</code> instantiation cannot have
duplicate <a href="indices.html#tags">tags</a>, either within a single
@@ -589,7 +625,7 @@ the same order as they were specified.<br>
<blockquote>
<code>index&lt;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&lt;N>::type</code> is equivalent to
<code>nth_index&lt;N>::type::iterator</code>.<br>
<b>Note:</b> The use of <code>nth_index_iterator</code> is deprecated.
</blockquote>
<code>template&lt;int N> struct nth_index_const_iterator</code>
@@ -606,6 +643,7 @@ as an associated tag type.
<blockquote>
<code>nth_index_const_iterator&lt;N>::type</code> is equivalent to
<code>nth_index&lt;N>::type::const_iterator</code>.<br>
<b>Note:</b> The use of <code>nth_index_const_iterator</code> is deprecated.
</blockquote>
<code>template&lt;typename Tag> struct index_iterator</code>
@@ -613,6 +651,7 @@ as an associated tag type.
<blockquote>
<code>index_iterator&lt;Tag>::type</code> is equivalent to
<code>index&lt;Tag>::type::iterator</code>.<br>
<b>Note:</b> The use of <code>index_iterator</code> is deprecated.
</blockquote>
<code>template&lt;typename Tag> struct index_const_iterator</code>
@@ -620,12 +659,13 @@ as an associated tag type.
<blockquote>
<code>index_const_iterator&lt;Tag>::type</code> is equivalent to
<code>index&lt;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>
&nbsp;&nbsp;const ctor_args_list&amp; comp=ctor_args_list(),<br>
&nbsp;&nbsp;const ctor_args_list&amp; args_list=ctor_args_list(),<br>
&nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code>
<blockquote>
@@ -634,6 +674,14 @@ specified argument list and allocator.<br>
<b>Complexity:</b> Constant.
</blockquote>
<code>explicit multi_index_container(const allocator_type&amp; 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&lt;typename InputIterator><br>
multi_index_container(<br>
&nbsp;&nbsp;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&lt;int N,typename IteratorType><br>
typename nth_index_iterator&lt;N>::type project(IteratorType it);</code>
typename nth_index&lt;N>::type::iterator project(IteratorType it);</code>
<blockquote>
<b>Requires:</b> <code>0 &lt;= N &lt; 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&lt;N>::type</code> iterator
<b>Effects:</b> Returns an <code>nth_index&lt;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&lt;int N,typename IteratorType><br>
typename nth_index_const_iterator&lt;N>::type project(IteratorType it)const;</code>
typename nth_index&lt;N>::type::const_iterator project(IteratorType it)const;</code>
<blockquote>
<b>Requires:</b> <code>0 &lt;= N &lt; 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&lt;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&lt;typename Tag,typename IteratorType><br>
typename index_iterator&lt;Tag>::type project(IteratorType it);</code>
<blockquote>
<b>Requires:</b> <code>Tag</code> is such that
<code>index_iterator&lt;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&lt;Tag>::type</code> iterator
<b>Effects:</b> Returns an <code>nth_index&lt;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&lt;typename Tag,typename IteratorType><br>
typename index_const_iterator&lt;Tag>::type project(IteratorType it)const;</code>
typename index&lt;Tag>::type::iterator project(IteratorType it);</code>
<blockquote>
<b>Requires:</b> <code>Tag</code> is such that
<code>index_const_iterator&lt;Tag>::type</code> is valid. <code>IteratorType</code>
<code>index&lt;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&lt;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&lt;typename Tag,typename IteratorType><br>
typename index&lt;Tag>::type::const_iterator project(IteratorType it)const;</code>
<blockquote>
<b>Requires:</b> <code>Tag</code> is such that
<code>index&lt;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&lt;Tag>::type</code>
<b>Effects:</b> Returns an <code>index&lt;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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+117 -47
View File
@@ -43,6 +43,7 @@ Hashed indices
<li><a href="#complexity_signature">Complexity signature</a></li>
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#constructors">Constructors, copy and assignment</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#observers">Observers</a></li>
<li><a href="#set_operations">Set operations</a></li>
@@ -205,7 +206,7 @@ requirements for these types of containers.
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
<span class=keyword>namespace</span><span class=special>{</span> <b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=special>}</span> <span class=comment>// see range()</span>
<b>implementation defined </b><span class=identifier>unbounded</span><span class=special>;</span> <span class=comment>// see range()</span>
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
@@ -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>&lt;</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>&gt;</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
@@ -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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
<span class=keyword>bool</span> <span class=identifier>empty</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
@@ -272,7 +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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify_key</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
@@ -395,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&lt;&gt;</code> is assumed),</li>
<li><code>KeyFromValue</code> from the index specifier,</li>
<li><code>Compare</code> from the index specifier.</li>
</ul>
@@ -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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code>
@@ -473,7 +498,7 @@ one element can be causing insertion not to be allowed.<br>
<code>iterator insert(iterator position,const value_type&amp; 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&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
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&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, restores all keys of the element
to their original state.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.
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&lt;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&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
<b>Effects:</b> Calls <code>mod(k)</code> where <code>k</code> is the key
obtained by the internal <code>KeyFromValue</code> object of the index from
the element pointed to by <code>position</code>, and rearranges
<code>*position</code> into all the indices of the <code>multi_index_container</code>.
Rearrangement is successful if
<ul>
<li>the index is non-unique OR no other element exists
with equivalent key,</li>
<li>AND rearrangement is allowed by all other indices of the
<code>multi_index_container</code>.</li>
</ul>
If the rearrangement fails, the element is erased.<br>
<b>Postconditions:</b>Validity of <code>position</code> is preserved if
the operation succeeds.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Basic. If an exception is thrown by some
user-provided operation (except possibly <code>mod</code>), then
the element pointed to by <code>position</code> is erased.
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&lt;typename Modifier,typename Rollback><br>
bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> and <code>Rollback</code>
are models of <a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The sequence of operations <code>mod(k)</code>,
<code>back(k)</code>, where <code>k</code> is the key of the element
pointed to by <code>position</code>, restores k to its original state.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>,
with <code>mod'</code> and <code>back</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
<code>back'(x)</code> is the same as <code>back(key(x))</code>, where
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
</blockquote>
<h4><a name="observers">Observers</a></h4>
@@ -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&amp; x,const CompatibleCompare&amp; 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&amp; 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&amp; x,const CompatibleCompare&amp; 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&amp; 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&amp; x,const CompatibleCompare&amp; 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&amp; 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&amp; x,const CompatibleCompare&amp; 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&lt;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&lt;typename CompatibleKey,typename CompatibleCompare><br>
std::pair&lt;iterator,iterator> equal_range(</br>
std::pair&lt;iterator,iterator> equal_range(<br>
&nbsp;&nbsp;const CompatibleKey&amp; x,const CompatibleCompare&amp; comp)const;
</code>
<blockquote>
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
is a compatible extension of <code>key_compare</code>.</br>
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&lt;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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+69 -15
View File
@@ -41,6 +41,7 @@ Key extraction
<li><a href="#complexity_signature">Complexity signature</a></li>
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#constructors">Constructors, copy and assignment</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#capacity">Capacity operations</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#list_operations">List operations</a></li>
@@ -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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
@@ -273,6 +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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
@@ -396,7 +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&lt;&gt;</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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="capacity">Capacity operations</a></h4>
<a name="capacity_memfun"><code>size_type capacity()const;</code></a>
@@ -533,7 +556,7 @@ Note that more than one element can be causing insertion not to be allowed.<br>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; 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&amp; 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>&lt;</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&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
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&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, restores all keys of the element
to their original state.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on
random access indices does not change the position of the element with respect
to the index; rearrangement on other indices may or might not succeed. If the
rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
throws inside the handling code executing after some other user-provided
operation has thrown, it is the exception generated by <code>back</code> that
is rethrown.
</blockquote>
<h4><a name="list_operations">List operations</a></h4>
<p>
@@ -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>&amp;x!=this</code>.</br>
<code>&amp;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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+67 -13
View File
@@ -41,6 +41,7 @@ Random access indices
<li><a href="#complexity_signature">Complexity signature</a></li>
<li><a href="#instantiation_types">Instantiation types</a></li>
<li><a href="#constructors">Constructors, copy and assignment</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#capacity">Capacity operations</a></li>
<li><a href="#modifiers">Modifiers</a></li>
<li><a href="#list_operations">List operations</a></li>
@@ -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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>const_iterator</span> <span class=identifier>iterator_to</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// capacity:</span>
@@ -260,6 +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>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
@@ -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&lt;&gt;</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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
const_iterator iterator_to(const value_type&amp; x)const;</code>
<blockquote>
<b>Requires:</b> <code>x</code> is a reference to an element of the container.<br>
<b>Returns:</b> An iterator to <code>x</code>.<br>
<b>Complexity:</b> Constant.<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<h4><a name="capacity">Capacity operations</a></h4>
<code>void resize(size_type n,const value_type&amp; x=value_type());</code>
@@ -487,7 +510,7 @@ Note that more than one element can be causing insertion not to be allowed.<br>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; 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&amp; 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>&lt;</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span>
@@ -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&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.</br>
iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
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&lt;typename Modifier,typename Rollback><br>
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
pointed to by <code>position</code>, restores all keys of the element
to their original state.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
indices does not change the position of the element with respect to the index;
rearrangement on other indices may or might not succeed. If the rearrangement
fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
<b>Exception safety:</b> Strong, except if <code>back</code> throws an
exception, in which case the modified element is erased. If <code>back</code>
throws inside the handling code executing after some other user-provided
operation has thrown, it is the exception generated by <code>back</code> that
is rethrown.
</blockquote>
<h4><a name="list_operations">List operations</a></h4>
<p>
@@ -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>&amp;x!=this</code>.</br>
<code>&amp;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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+221 -2
View File
@@ -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&lt;MultiIndexContainer,N&gt;::type</code>,</li>
<li><code>multi_index_container&lt;...&gt;::nth_index_iterator&lt;N&gt;::type</code>,</li>
<li><code>nth_index_const_iterator&lt;MultiIndexContainer,N&gt;::type</code>,</li>
<li><code>multi_index_container&lt;...&gt;::nth_index_const_iterator&lt;N&gt;::type</code>,</li>
<li><code>index_iterator&lt;MultiIndexContainer,Tag&gt;::type</code>,</li>
<li><code>multi_index_container&lt;...&gt;::index_iterator&lt;Tag&gt;::type</code>,</li>
<li><code>index_const_iterator&lt;MultiIndexContainer,Tag&gt;::type</code>,</li>
<li><code>multi_index_container&lt;...&gt;::index_const_iterator&lt;Tag&gt;::type</code>.</li>
</ul>
Use the following instead:
<ul>
<li><code>nth_index&lt;MultiIndexContainer,N&gt;::type::iterator</code>,</li>
<li><code>multi_index_container&lt;...&gt;::nth_index&lt;N&gt;::type::iterator</code>,</li>
<li><code>nth_index&lt;MultiIndexContainer,N&gt;::type::const_iterator</code>,</li>
<li><code>multi_index_container&lt;...&gt;::nth_index&lt;N&gt;::type::const_iterator</code>,</li>
<li><code>index&lt;MultiIndexContainer,Tag&gt;::type::iterator</code>,</li>
<li><code>multi_index_container&lt;...&gt;::index&lt;Tag&gt;::type::iterator</code>,</li>
<li><code>index&lt;MultiIndexContainer,Tag&gt;::type::const_iterator</code>,</li>
<li><code>multi_index_container&lt;...&gt;::index&lt;Tag&gt;::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&amp;)</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>&lt;</span>
<span class=keyword>int</span><span class=special>,</span><span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>sequenced_container</span><span class=special>;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=identifier>l</span><span class=special>(...);</span>
<span class=identifier>sequenced_container</span> <span class=identifier>c</span><span class=special>;</span>
<span class=comment>// iterator-based overload of assign</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=identifier>l</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>l</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
<span class=comment>// The following is equivalent to
// c.assign(
// static_cast&lt;sequenced_container::size_type&gt;(10),100);
// that is, &quot;10&quot; and &quot;100&quot; are not taken to be iterators as
// in the previous expression.</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=number>10</span><span class=special>,</span><span class=number>100</span><span class=special>);</span>
</pre></blockquote>
</li>
<li>The performance of ordered indices <code>range</code> and
<code>equal_range</code> has been improved.
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_34">Boost 1.34 release</a></h2>
<p>
@@ -140,9 +359,9 @@ Acknowledgements
<br>
<p>Revised February 6th 2006</p>
<p>Revised November 24th 2011</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2011 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+4 -3
View File
@@ -116,7 +116,8 @@ with some of the least common features offered by Boost.MultiIndex.
</tr>
<tr class="odd_tr">
<td><a href="../test/test_serialization1.cpp"><code>test_serialization1.cpp</code></a><br>
<a href="../test/test_serialization2.cpp"><code>test_serialization2.cpp</code></a></td>
<a href="../test/test_serialization2.cpp"><code>test_serialization2.cpp</code></a><br>
<a href="../test/test_serialization3.cpp"><code>test_serialization3.cpp</code></a></td>
<td>Serialization support.</td>
</tr>
<tr>
@@ -149,9 +150,9 @@ Future work
<br>
<p>Revised March 2nd 2006</p>
<p>Revised July 11th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+69 -34
View File
@@ -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>&lt;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>&lt;</span><span class=number>1</span><span class=special>&gt;().</span><span class=identifier>find</span><span class=special>(</span><span class=string>&quot;Judy Smith&quot;</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>&lt;</span><span class=number>1</span><span class=special>&gt;::</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>&lt;</span><span class=number>1</span><span class=special>&gt;().</span><span class=identifier>find</span><span class=special>(</span><span class=string>&quot;Judy Smith&quot;</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>&lt;</span><span class=identifier>name</span><span class=special>&gt;::</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>&lt;</span><span class=identifier>name</span><span class=special>&gt;().</span><span class=identifier>find</span><span class=special>(</span><span class=string>&quot;Judy Smith&quot;</span><span class=special>);</span> <span class=comment>// get&lt;1&gt; 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>&amp;</span> <span class=identifier>e</span><span class=special>)</span>
<span class=special>{</span>
<span class=identifier>e</span><span class=special>.</span><span class=identifier>id</span><span class=special>=</span><span class=identifier>new_id</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>private</span><span class=special>:</span>
<span class=keyword>int</span> <span class=identifier>new_id</span><span class=special>;</span>
<span class=special>};</span>
<span class=special>...</span>
<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=...</span>
<span class=keyword>int</span> <span class=identifier>old_id</span><span class=special>=</span><span class=identifier>it</span><span class=special>-&gt;</span><span class=identifier>id</span><span class=special>;</span> <span class=comment>// keep the original id
// try to modify the id, restore it in case of collisions</span>
<span class=identifier>es</span><span class=special>.</span><span class=identifier>modify</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>change_id</span><span class=special>(</span><span class=number>321</span><span class=special>),</span><span class=identifier>change_id</span><span class=special>(</span><span class=identifier>old_id</span><span class=special>));</span>
</pre></blockquote>
<p>In the example, <code>change_id(old_id)</code> is invoked to restore the original
conditions when the modification results in collisions with some other element.
The differences in behavior between <code>replace</code>, <code>modify</code> and
<code>modify</code> with rollback have to be considered by the programmer on a
case-by-case basis to determine the best updating mechanism.
</p>
<p align="center">
<table cellspacing="0">
<caption><b>Behavior of the different updating mechanisms.</b></caption>
<tr>
<th align="center">updating function</th>
<th>If there is a collision...</th>
</tr>
<tr>
<td align="center"><code>replace(it,x)</code></td>
<td>replacement does not take place.</td>
</tr>
<tr class="odd_tr">
<td align="center"><code>modify(it,mod)</code></td>
<td>the element is erased.</td>
</tr>
<tr>
<td align="center"><code>modify(it,mod,back)</code></td>
<td><code>back</code> is used to restore the original conditions.
(If <code>back</code> throws, the element is erased.)
</td>
</tr>
</table>
</p>
<p>
A key-based version of <code>modify</code>, named
<a href="../reference/ord_indices.html#modify_key"><code>modify_key</code></a>, is
provided as well. In this case, the modifying functor is passed a reference to
the <code>key_value</code> part of the element instead of the whole object.
Key-based versions of <code>modify</code>, named
<a href="../reference/ord_indices.html#modify_key"><code>modify_key</code></a>, are
provided as well. In this case, the modifying functors are passed a reference to
the <code>key_type</code> part of the element instead of the whole object.
</p>
<blockquote><pre>
@@ -990,8 +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>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>s</span><span class=special>;</span> <span class=comment>// list-like container</span>
<span class=special>&gt;</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 &quot;older&quot; to all occurrences of &quot;sister&quot;</span>
<span class=identifier>text_container</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;::</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>&lt;</span><span class=number>1</span><span class=special>&gt;::</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>&quot;sister&quot;</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>()&amp;&amp;*</span><span class=identifier>it1</span><span class=special>==</span><span class=string>&quot;sister&quot;</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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+58 -3
View File
@@ -32,6 +32,7 @@ Debugging support
<ul>
<li><a href="#value_semantics">Value semantics</a></li>
<li><a href="#ctor_args_list">Use of <code>ctor_args_list</code></a></li>
<li><a href="#special_allocator">Special allocator support</a></li>
<li><a href="#serialization">Serialization</a></li>
</ul>
@@ -191,6 +192,60 @@ A program is provided in the <a href="../examples.html#example3">examples sectio
puts in practise these concepts.
</p>
<h2><a name="special_allocator">Special allocator support</a></h2>
<p>
Boost.MultiIndex allows for a slightly more general class of allocators
than strictly required by the C++ standard, as explained in detail in the
<a href="../reference/multi_index_container.html#instantiation_types">reference</a>.
An important type of non-standard allocators supported are those provided by the
<a href="../../../interprocess/index.html">Boost Interprocess Library</a>;
this opens up the possibility of placing <code>multi_index_container</code>s
in shared memory.
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>allocators</span><span class=special>/</span><span class=identifier>allocator</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>managed_shared_memory</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>bip</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>interprocess</span><span class=special>;</span>
<span class=comment>// a shared memory compatible allocator of ints</span>
<span class=keyword>typedef</span> <span class=identifier>bip</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span><span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span><span class=special>::</span><span class=identifier>segment_manager</span>
<span class=special>&gt;</span> <span class=identifier>shared_int_allocator</span><span class=special>;</span>
<span class=comment>// define a shared memory compatible multi_index_container
// using shared_int_allocator</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;,</span>
<span class=identifier>shared_int_allocator</span>
<span class=special>&gt;</span> <span class=identifier>unique_int_list</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// create a managed memory segment</span>
<span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span> <span class=identifier>seg</span><span class=special>(</span>
<span class=identifier>bip</span><span class=special>::</span><span class=identifier>create_only</span><span class=special>,</span><span class=string>&quot;SharedMemoryID&quot;</span><span class=special>,</span><span class=number>65536</span><span class=special>);</span>
<span class=comment>// construct a unique_int_list into the segment</span>
<span class=identifier>unique_int_list</span><span class=special>*</span> <span class=identifier>puil</span><span class=special>=</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>construct</span><span class=special>&lt;</span><span class=identifier>unique_int_list</span><span class=special>&gt;</span>
<span class=special>(</span><span class=string>&quot;UniqueIntListID&quot;</span><span class=special>)</span> <span class=comment>// object identifier within the segment
// Construction args: first a ctor arg list, then a
// shared memory allocator obtained from the segment object.</span>
<span class=special>(</span><span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
<span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>allocator_type</span><span class=special>(</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>get_segment_manager</span><span class=special>()));</span>
</pre></blockquote>
<p>
The examples section includes a <a href="../examples.html#example12">program</a>
that further explores this capability.
</p>
<h2><a name="serialization">Serialization</a></h2>
<p>
@@ -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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+57 -3
View File
@@ -48,6 +48,7 @@ Key extraction
</ul>
</li>
<li><a href="#rearrange">Index rearranging</a></li>
<li><a href="#iterator_to"><code>iterator_to</code></a></li>
<li><a href="#ordered_node_compression">Ordered indices node compression</a></li>
</ul>
@@ -90,6 +91,7 @@ some added benefits, functionally or in the area of performance.
</tr>
<tr class="odd_tr">
<td align="center"><code>&nbsp;&nbsp;random_access&nbsp;&nbsp;</code></td>
</tr>
</table>
</p>
@@ -608,7 +610,8 @@ thus, <code>rearrange</code> does not accept the following:
<blockquote><pre>
<span class=comment>// undefined behavior: [rbegin(),rend()) is not free with respect
// to the base index</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>rbegin</span><span class=special>());</span></pre></blockquote>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>rearrange</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>rbegin</span><span class=special>());</span>
</pre></blockquote>
<p>
The view concept is defined in detail in the
@@ -617,6 +620,57 @@ See <a href="../examples.html#example11">example 11</a> in the examples section
for a demonstration of use of <code>rearrange</code>.
</p>
<h2><a name="iterator_to"><code>iterator_to</code></a></h2>
<p>
All indices of Boost.MultiIndex provide a member function called <code>iterator_to</code>
which returns an iterator to a given element of the container:
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=keyword>int</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span><span class=identifier>sequenced</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>c</span><span class=special>;</span>
<span class=special>...</span>
<span class=comment>// convoluted way to do c.pop_back()</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>iterator_to</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>back</span><span class=special>()));</span>
<span class=comment>// The following, though similar to the previous code,
// does not work: iterator_to accepts a reference to
// the element in the container, not a copy.</span>
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>back</span><span class=special>();</span>
<span class=identifier>c</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>iterator_to</span><span class=special>(</span><span class=identifier>x</span><span class=special>));</span> <span class=comment>// run-time failure ensues</span>
</pre></blockquote>
<p>
<code>iterator_to</code> provides a way to retrieve an iterator to an element
from a pointer to the element, thus making iterators and pointers interchangeable
for the purposes of element pointing (not so for traversal) in many situations.
This notwithstanding, it is not the aim of <code>iterator_to</code> to
promote the usage of pointers as substitutes for real iterators: the latter are
specifically designed for handling the elements of a container,
and not only benefit from the iterator orientation of container interfaces,
but are also capable of exposing many more programming bugs than raw pointers, both
at compile and run time. <code>iterator_to</code> is thus meant to be used
in scenarios where access via iterators is not suitable or desireable:
<ul>
<li>Interoperability with preexisting APIs based on pointers or references.</li>
<li>Publication of pointer-based interfaces (for instance, when
designing a C-compatible library).
</li>
<li>The exposure of pointers in place of iterators can act as a <i>type
erasure</i> barrier effectively decoupling the user of the code
from the implementation detail of which particular container is being
used. Similar techniques, like the famous Pimpl idiom, are used
in large projects to reduce dependencies and build times.
</li>
<li>Self-referencing contexts where an element acts upon its owner
container and no iterator to itself is available.
</li>
</ul>
</p>
<h2><a name="ordered_node_compression">Ordered indices node compression</a></h2>
<p>
@@ -664,9 +718,9 @@ Key extraction
<br>
<p>Revised February 6th 2006</p>
<p>Revised October 15th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+139 -16
View File
@@ -41,6 +41,7 @@ Container creation
<li><a href="#member"><code>member</code></a></li>
<li><a href="#const_mem_fun"><code>const_mem_fun</code>
and <code>mem_fun</code></a></li>
<li><a href="#global_fun"><code>global_fun</code></a></li>
</ul>
</li>
<li><a href="#user_defined_key_extractors">User-defined key extractors</a></li>
@@ -244,6 +245,68 @@ of Boost.MultiIndex key extractors</a>.
provides a complete program showing how to use <code>const_mem_fun</code>.
<p>
<h3><a name="global_fun"><code>global_fun</code></a></h3>
<p>
Whereas <code>const_mem_fun</code> and <code>mem_fun</code> are based on a
given member function of the base type from where the key is extracted,
<a href="../reference/key_extraction.html#global_fun"><code>global_fun</code></a>
takes a global function (or static member function) accepting the base
type as its parameter and returning the key:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>ordered_index</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index</span><span class=special>/</span><span class=identifier>global_fun</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>rectangle</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>x0</span><span class=special>,</span><span class=identifier>y0</span><span class=special>;</span>
<span class=keyword>int</span> <span class=identifier>x1</span><span class=special>,</span><span class=identifier>y1</span><span class=special>;</span>
<span class=special>};</span>
<span class=keyword>unsigned</span> <span class=keyword>long</span> <span class=identifier>area</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>rectangle</span><span class=special>&amp;</span> <span class=identifier>r</span><span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=special>(</span><span class=keyword>unsigned</span> <span class=keyword>long</span><span class=special>)(</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>x1</span><span class=special>-</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>x0</span><span class=special>)*(</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>x1</span><span class=special>-</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>x0</span><span class=special>)+</span>
<span class=special>(</span><span class=keyword>unsigned</span> <span class=keyword>long</span><span class=special>)(</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>y1</span><span class=special>-</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>y0</span><span class=special>)*(</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>y1</span><span class=special>-</span><span class=identifier>r</span><span class=special>.</span><span class=identifier>y0</span><span class=special>);</span>
<span class=special>}</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>rectangle</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=comment>// sort by increasing area</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>global_fun</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=identifier>rectangle</span><span class=special>&amp;,</span><span class=keyword>unsigned</span> <span class=keyword>long</span><span class=special>,&amp;</span><span class=identifier>area</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>rectangle_container</span><span class=special>;</span>
</pre></blockquote>
<p>
The specification of <code>global_fun</code> obeys the following syntax:
</p>
<blockquote><pre>
<span class=identifier>global_fun</span><span class=special>&lt;</span><span class=identifier><i>(argument type)</i></span><span class=special>,</span><span class=identifier><i>(key type)</i></span><span class=special>,</span><span class=identifier><i>(pointer to function)</i></span><span class=special>&gt;</span>
</pre></blockquote>
<p>
where the argument type and key type must match <i>exactly</i> those in the
signature of the function used; for instance, in the example above the argument
type is <code>const rectangle&amp;</code>, without omitting the "<code>const</code>"
and "<code>&amp;</code>" parts. So, although most of the time the base type will be
accepted by constant reference, <code>global_fun</code> is also prepared to take
functions accepting their argument by value or by non-constant reference: this
latter case cannot generally be used directly in the specification of
<code>multi_index_container</code>s as their elements are treated as constant,
but the section on <a href="#advanced_key_extractors">advanced features
of Boost.MultiIndex key extractors</a> describes valid use cases of
key extraction based on such functions with a non-constant reference argument.
</p>
<p><a href="../examples.html#example2">Example 2</a> in the examples section
uses <code>gobal_fun</code>.
<p>
<h2><a name="user_defined_key_extractors">User-defined key extractors</a></h2>
<p>
@@ -632,10 +695,12 @@ following final type:
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>T</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>i</span><span class=special>;</span>
<span class=keyword>const</span> <span class=keyword>int</span> <span class=identifier>j</span><span class=special>;</span>
<span class=keyword>int</span> <span class=identifier>f</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>int</span> <span class=identifier>g</span><span class=special>();</span>
<span class=keyword>int</span> <span class=identifier>i</span><span class=special>;</span>
<span class=keyword>const</span> <span class=keyword>int</span> <span class=identifier>j</span><span class=special>;</span>
<span class=keyword>int</span> <span class=identifier>f</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>int</span> <span class=identifier>g</span><span class=special>();</span>
<span class=keyword>static</span> <span class=keyword>int</span> <span class=identifier>gf</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>T</span><span class=special>&amp;);</span>
<span class=keyword>static</span> <span class=keyword>int</span> <span class=identifier>gg</span><span class=special>(</span><span class=identifier>T</span><span class=special>&amp;);</span>
<span class=special>};</span>
</pre></blockquote>
@@ -656,7 +721,7 @@ each of its members.
<th>read/write?</th>
</tr>
<tr>
<td align="center" rowspan="4"><code>T</code></td>
<td align="center" rowspan="6"><code>T</code></td>
<td><code>i</code></td>
<td><code>member&lt;T,int,&amp;T::i></code></td>
<td align="center">yes</td>
@@ -680,9 +745,21 @@ each of its members.
<td align="center">no</td>
<td align="center">no</td>
</tr>
<tr>
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td><code>gg()</code></td>
<td><code>global_fun&lt;T&amp;,int,&amp;T::gg></code></td>
<td align="center">no</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td align="center" rowspan="4"><code>reference_wrapper&lt;T></code></td>
<td align="center" rowspan="6"><code>reference_wrapper&lt;T></code></td>
<td><code>i</code></td>
<td><code>member&lt;T,int,&amp;T::i></code></td>
<td align="center">yes</td>
@@ -706,9 +783,21 @@ each of its members.
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td><code>gg()</code></td>
<td><code>global_fun&lt;T&amp;,int,&amp;T::gg></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td align="center" rowspan="4"><code>reference_wrapper&lt;const T></code></td>
<td align="center" rowspan="6"><code>reference_wrapper&lt;const T></code></td>
<td><code>i</code></td>
<td><code>member&lt;T,const int,&amp;T::i></code></td>
<td align="center">yes</td>
@@ -730,9 +819,19 @@ each of its members.
<td><code>g()</code></td>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td><code>gg()</code></td>
<td colspan="3">&nbsp;</td>
</tr>
<tr class="odd_tr">
<td align="center" rowspan="4">chained pointer to <code>T</code><br>
<td align="center" rowspan="6">chained pointer to <code>T</code><br>
or to <code>reference_wrapper&lt;T></code></td>
<td><code>i</code></td>
<td><code>member&lt;T,int,&amp;T::i></code></td>
@@ -757,9 +856,21 @@ each of its members.
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr class="odd_tr">
<td><code>gg()</code></td>
<td><code>global_fun&lt;T&amp;,int,&amp;T::gg></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td align="center" rowspan="4">chained pointer to <code>const T</code><br>
<td align="center" rowspan="6">chained pointer to <code>const T</code><br>
or to <code>reference_wrapper&lt;const T></code></td>
<td><code>i</code></td>
<td><code>member&lt;T,const int,&amp;T::i></code></td>
@@ -782,6 +893,16 @@ each of its members.
<td><code>g()</code></td>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td><code>gf()</code></td>
<td><code>global_fun&lt;const T&amp;,int,&amp;T::gf></code></td>
<td align="center">yes</td>
<td align="center">no</td>
</tr>
<tr>
<td><code>gg()</code></td>
<td colspan="3">&nbsp;</td>
</tr>
</table>
</p>
@@ -790,10 +911,12 @@ each of its members.
The column "applicable to <code>const</code> elements?" states whether the
corresponding key extractor can be used when passed constant elements (this
relates to the elements specified in the first column, not the referenced
<code>T</code> objects). The only negative case is for <code>T::g</code> when
the elements are raw <code>T</code> objects, which make sense as we are dealing
with a non-constant member function: this also implies that <code>multi_index_container</code>s
of elements of <code>T</code> cannot be sorted by <code>T::g</code>, because
<code>T</code> objects). The only negative cases are for <code>T::g</code> and
<code>T:gg</code> when the elements are raw <code>T</code> objects, which make sense
as we are dealing with a non-constant member function (<code>T::g</code>)
and a function taking <code>T</code> by
non-constant reference: this also implies that <code>multi_index_container</code>s
of elements of <code>T</code> cannot be sorted by <code>T::g</code> or <code>T::gg</code>, because
elements contained within a <code>multi_index_container</code> are treated as constant.
</p>
@@ -804,7 +927,7 @@ The column "read/write?" shows which combinations yield
<p>
Some care has to be taken to preserve <code>const</code>-correctness in the
specification of the key extractors: in some sense, the <code>const</code>
specification of <code>member</code> key extractors: in some sense, the <code>const</code>
qualifier is carried along to the member part, even if that particular
member is not defined as <code>const</code>. For instance, if the elements
are of type <code>const T *</code>, sorting by <code>T::i</code> is <i>not</i>
@@ -832,9 +955,9 @@ Container creation
<br>
<p>Revised February 6th 2006</p>
<p>Revised June 11th 2007</p>
<p>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+3 -3
View File
@@ -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&lt;n>::type</code>.
<code>nth_index&lt;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>&copy; Copyright 2003-2006 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+10 -8
View File
@@ -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
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex basic example.
*
* Copyright 2003-2005 Joaqu匤 M Lez Muz.
* 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
View File
@@ -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;
}
+3 -3
View File
@@ -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);
+3 -2
View File
@@ -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;
+26 -5
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of member functions used as key extractors.
/* Boost.MultiIndex example of functions used as key extractors.
*
* Copyright 2003-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
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of hashed indices.
*
* Copyright 2003-2005 Joaqu匤 M Lez Muz.
* 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 "
+293
View File
@@ -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 -1
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of multi_index_container::ctor_args_list.
*
* Copyright 2003-2004 Joaqu匤 M Lez Muz.
* 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 -1
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of random access indices.
*
* Copyright 2003-2006 Joaqu匤 M Lez Muz.
* 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 -1
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of rearrange facilities.
*
* Copyright 2003-2006 Joaqu匤 M Lez Muz.
* 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 -1
View File
@@ -1,6 +1,6 @@
/* Boost.MultiIndex example of use of sequenced indices.
*
* Copyright 2003-2005 Joaqu匤 M Lez Muz.
* 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)
+2 -2
View File
@@ -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)
{
+14 -5
View File
@@ -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 Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 -19
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaqu M Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 Lez Muz.
/* 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 -21
View File
@@ -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));
+46 -15
View File
@@ -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_)
{
}
+188
View File
@@ -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
+296 -93
View File
@@ -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 Lez Muz.
/* 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)
+4 -3
View File
@@ -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
+3 -3
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaqu M Lez Muz.
/* 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)
+2 -1
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaqu M Lez Muz.
/* 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>
+11 -21
View File
@@ -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)
+6 -6
View File
@@ -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
+264 -91
View File
@@ -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 Lez Muz.
/* 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)
+139 -34
View File
@@ -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 Lez Muz.
/* 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 Lez Muz.
/* 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)
+134 -34
View File
@@ -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 Lez Muz.
/* 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 -1
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaqu M Lez Muz.
/* 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)
+151 -34
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/* Copyright 2003-2005 Joaqu M Lez Muz.
/* 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