This commit was manufactured by cvs2svn to create branch
'thread_rewrite'. [SVN r30953]
16
Jamfile
@@ -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 ;
|
||||
@@ -1,144 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Acknowledgements</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Acknowledgements</h1>
|
||||
|
||||
<div class="prev_link"><a href="release_notes.html"><img src="prev.gif" alt="release notes" border="0"><br>
|
||||
Release notes
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link">
|
||||
</div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
Fernando Cacciola, Darren Cook, Beman Dawes, Jeremy Maitin-Shepard and Daryle
|
||||
Walker from the Boost mailing list provided useful suggestions for improvement
|
||||
on the first alpha releases of the library. Gang Wang discovered several
|
||||
bugs in the code. Thomas Wenisch brought out the idea of "sequence sets"
|
||||
from which sequenced indices were designed. Giovanni Bajo, Chris Little and
|
||||
Maxim Yegorushkin tested the library on several platforms. Daniel Wallin
|
||||
contributed fixes for MSVC++ 7.0. Ron Liechty and the support staff at
|
||||
Metrowerks provided assistance during the porting of the library to CW 8.3.
|
||||
Porting to VisualAge 6.0 counted on Toon Knapen's help. Markus Schöpflin
|
||||
aided with Compaq C++ 6.5 and GCC for Tru64 UNIX. Rosa Bernárdez proofread the
|
||||
last versions of the tutorial.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Pavel Voženílek has been immensely helpful in thoroughly reviewing
|
||||
every single bit of the library, and he also suggested several extra
|
||||
functionalities, most notably range querying, safe mode, polymorphic key
|
||||
extractors and MPL support. Thank you!
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The Boost acceptance review took place between March 20th and 30th 2004.
|
||||
Pavel Voženílek was the review manager. Thanks to all the people
|
||||
who participated and specially to those who submitted reviews:
|
||||
Fredrik Blomqvist, Tom Brinkman, Paul A Bristow, Darren Cook, Jeff Garland,
|
||||
David B. Held, Brian McNamara, Gary Powell, Rob Stewart, Arkadiy Vertleyb,
|
||||
Jörg Walter. Other Boost members also contributed ideas, particularly
|
||||
in connection with the library's naming scheme: Pavol Droba,
|
||||
Dave Gomboc, Jeremy Maitin-Shepard, Thorsten Ottosen, Matthew Vogt,
|
||||
Daryle Walker. My apologies if I inadvertently left somebody out of this
|
||||
list.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex could not have been written without Aleksey Gurtovoy
|
||||
et al. superb <a href="../../../libs/mpl/doc/index.html">Boost MPL
|
||||
Library</a>. Also, Aleksey's techniques for dealing with ETI-related
|
||||
problems in MSVC++ 6.0 helped solve some internal issues of the library.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The internal implementation of red-black trees is based on that of SGI STL
|
||||
<a href="http://www.sgi.com/tech/stl/stl_tree.h">stl_tree.h</a> file:
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
Copyright (c) 1996,1997
|
||||
Silicon Graphics Computer Systems, Inc.
|
||||
<br>
|
||||
Permission to use, copy, modify, distribute and sell this software
|
||||
and its documentation for any purpose is hereby granted without fee,
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both that copyright notice and this permission notice appear
|
||||
in supporting documentation. Silicon Graphics makes no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied warranty.
|
||||
<br>
|
||||
<br>
|
||||
Copyright (c) 1994
|
||||
Hewlett-Packard Company
|
||||
<br>
|
||||
Permission to use, copy, modify, distribute and sell this software
|
||||
and its documentation for any purpose is hereby granted without fee,
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both that copyright notice and this permission notice appear
|
||||
in supporting documentation. Hewlett-Packard Company makes no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied warranty.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<span style="float:right;"><img src="lopez.jpg" width="160" height="120"></span>
|
||||
I would like to dedicate this piece of work to Rosa Bernárdez, my very first
|
||||
C++ teacher, for her unconditional support in many endeavors of which programming is
|
||||
by no means the most important. In memory of my cat López (2001-2003): he
|
||||
lived too fast, died too young.
|
||||
<br style="clear:all;">
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_33">Boost 1.33 release</a></h2>
|
||||
|
||||
<p>
|
||||
Many thanks again to Pavel Voženílek, who has carefully reviewed
|
||||
the new material and suggested many improvements. The design of hashed indices
|
||||
has benefited from discussions with several Boost members, most notably
|
||||
Howard Hinnant and Daniel James. Daniel has also contributed
|
||||
<a href="../../functional/hash/index.html">Boost.Hash</a>
|
||||
to the community: hashed indices depend on this library as
|
||||
their default hash function provider. Robert Ramey's
|
||||
<a href="../../serialization/index.html">Boost Serialization Library</a>
|
||||
provides the very solid framework upon which Boost.MultiIndex serialization
|
||||
capabilities are built. Toon Knapen helped adjust the library for VisualAge 6.0.
|
||||
Markus Schöpflin provided a Jamfile tweak for GCC under Tru64 UNIX.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="release_notes.html"><img src="prev.gif" alt="release notes" border="0"><br>
|
||||
Release notes
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link">
|
||||
</div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 11th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,941 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Compiler specifics</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Compiler specifics</h1>
|
||||
|
||||
<div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="performance.html"><img src="next.gif" alt="performance" border="0"><br>
|
||||
Performance
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex has been tried in different compilers, with
|
||||
various degrees of success. We list the limitations encountered,
|
||||
along with suitable workarounds when available.
|
||||
</p>
|
||||
|
||||
<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</a></li>
|
||||
<li>
|
||||
<a href="#gcc_32">GNU GCC 3.2 and later</a>
|
||||
<ul>
|
||||
<li><a href="#gcc_tru64">GNU GCC for Tru64 UNIX</a></li>
|
||||
<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="#va_60">IBM VisualAge C++ V6.0 for AIX</a></li>
|
||||
<li><a href="#intel_71_8x_lin">Intel C++ Compiler for Linux 7.1/8.0/8.1</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="#intel_8x_9x_win">Intel C++ Compiler for Windows 32-bit 8.0/8.1/9.0</a></li>
|
||||
<li><a href="#cw_83_9x">Metrowerks CodeWarrior 8.3 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_71">Microsoft Visual C++ 7.1</a></li>
|
||||
<li><a href="#msvc_80">Microsoft Visual C++ 8.0</a></li>
|
||||
<li><a href="#portability">Portability techniques</a>
|
||||
<ul>
|
||||
<li><a href="#member_offset">Use of <code>member_offset</code></a></li>
|
||||
<li><a href="#mem_fun_explicit">Use of <code>const_mem_fun_explicit</code> and
|
||||
<code>mem_fun_explicit</code></a></li>
|
||||
<li><a href="#composite_key_no_pts"><code>composite_key</code> in compilers
|
||||
without partial template specialization</a></li>
|
||||
<li><a href="#symbol_reduction">Reduction of symbol name lengths</a>
|
||||
<ul>
|
||||
<li><a href="#argument_limitation">Limitation of maximum number of arguments</a></li>
|
||||
<li><a href="#type_hiding">Type hiding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="bcb_64">Borland C++ Builder 6.4</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.
|
||||
</p>
|
||||
|
||||
<h2><a name="comeau_433_win_vc7_71">Comeau C/C++ 4.3.3 for Windows (VC++ 7.0/7.1 backend)</a></h2>
|
||||
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h2><a name="compaq_65">Compaq C++ 6.5-042 for Tru64 UNIX</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
</p>
|
||||
|
||||
<h2><a name="gcc_32">GNU GCC 3.2 and later</a></h2>
|
||||
|
||||
<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 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.</li>
|
||||
</ul>
|
||||
Boost.MultiIndex does not work with versions 3.1 and prior of GCC.
|
||||
</p>
|
||||
|
||||
<h3><a name="gcc_tru64">GNU GCC for Tru64 UNIX</a></h3>
|
||||
|
||||
<p>
|
||||
On this platform, GCC is not able to handle debug symbol names whose length
|
||||
exceeds 32,768 bytes, resulting in the error <code>mips-tfile, ... string
|
||||
too big</code>. You may encounter this issue with heavily templatized
|
||||
code like Boost.MultiIndex, which typically produces long symbol names. The problem
|
||||
can be overcome by omitting the compiler option <code>-g</code> (generate debugging
|
||||
information.) Alternatively, consult the section on
|
||||
<a href="#symbol_reduction">reduction of symbol name lengths</a> for various
|
||||
applicable workarounds.
|
||||
</p>
|
||||
|
||||
<h3><a name="gcc_4_darwin">Darwin GCC 4.0</a></h3>
|
||||
|
||||
<p>
|
||||
Build 4061 of GCC 4.0, shipped with Darwin 8.2 and prior (Mac OS X 10.4.2 and
|
||||
prior), corresponds to a prerelease version of GNU GCC 4.0.0 which introduces
|
||||
a <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17435">regression bug</a>
|
||||
related to binding of references to temporary objects. This bug precludes the
|
||||
usage of Boost.MultiIndex
|
||||
<a href="advanced_topics.html#invariant_check">invariant-checking mode</a>; other
|
||||
than this, Boost.MultiIndex works correctly.
|
||||
The bug is corrected in GCC 4.0 Apple build 5026, which is in sync with the official
|
||||
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>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler.
|
||||
</p>
|
||||
|
||||
<h2><a name="va_60">IBM VisualAge C++ V6.0 for AIX</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><pre>
|
||||
<span class=preprocessor>#pragma</span> <span class=identifier>info</span><span class=special>(</span><span class=identifier>nolan</span><span class=special>)</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
This latter pragma, however, may also eliminate other warnings not related
|
||||
to the use of <code>offsetof</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
Serialization capabilities are not available as Boost.Serialization is not
|
||||
supported on this platform.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_71_8x_lin">Intel C++ Compiler for Linux 7.1/8.0/8.1</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with these compilers.
|
||||
</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>
|
||||
|
||||
<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.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></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.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_71_win_stlport_453">
|
||||
Intel C++ Compiler for Windows 32-bit 7.1 + STLport 4.5.3</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.
|
||||
</p>
|
||||
|
||||
<h2><a name="intel_8x_9x_win">Intel C++ Compiler for Windows 32-bit 8.0/8.1/9.0</a></h2>
|
||||
|
||||
<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.
|
||||
Other than this, Boost.MultiIndex works without problems.
|
||||
</p>
|
||||
|
||||
<h2><a name="cw_83_9x">Metrowerks CodeWarrior 8.3 and later</a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex works correctly with versions of this compiler from 8.3 to
|
||||
9.5, under the two operating systems tested: Mac OS and Windows.
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="reference/key_extraction.html#const_mem_fun"><code>const_mem_fun</code></a> and
|
||||
<a href="reference/key_extraction.html#mem_fun"><code>mem_fun</code></a>
|
||||
not supported, refer to the section on
|
||||
<a href="#mem_fun_explicit">use of <code>const_mem_fun_explicit</code> and
|
||||
<code>mem_fun_explicit</code></a> for workarounds.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
No support for <a href="reference/multi_index_container.html#index_retrieval">index retrieval</a>
|
||||
and <a href="reference/multi_index_container.html#projection">projection</a>
|
||||
nested types and member functions:
|
||||
<ul>
|
||||
<li><code>nth_index</code>,</li>
|
||||
<li><code>index</code>,</li>
|
||||
<li><code>nth_index_iterator</code>,</li>
|
||||
<li><code>nth_index_const_iterator</code>,</li>
|
||||
<li><code>index_iterator</code>,</li>
|
||||
<li><code>index_const_iterator</code>,</li>
|
||||
<li><code>get</code>,</li>
|
||||
<li><code>project</code>.</li>
|
||||
</ul>
|
||||
You can use instead their global equivalents. Also, this compiler does not
|
||||
implement argument dependent lookup, so you might need to explicitly qualify
|
||||
these global names with <code>::boost::multi_index</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
<code>boost::multi_index::multi_index_container</code> is imported to
|
||||
<code>namespace boost</code> by means of a <code>using</code> declaration.
|
||||
MSVC++ 6.0, however, does not properly handle this import. So, instead of
|
||||
writing:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
use the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
or else resort to a directive <code>using namespace boost::multi_index</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
The lack of partial template specialization support in MSVC++ 6.0
|
||||
results in some inconveniences when using <code>composite_key</code> that
|
||||
can be remedied as explained in
|
||||
<a href="#composite_key_no_pts">"<code>composite_key</code>
|
||||
in compilers without partial template specialization"</a>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
MSVC++ 6.0 presents serious limitations for the maximum length of
|
||||
symbol names generated by the compiler, which might result in the
|
||||
linker error
|
||||
<code><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/lnk1179.asp">LNK1179</a>:
|
||||
invalid or corrupt file: duplicate comdat
|
||||
comdat</code>. To overcome this problem, consult the section on
|
||||
<a href="#symbol_reduction">reduction of symbol name lengths</a> for various
|
||||
applicable workarounds.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
Under some circumstances, the compiler emits the error
|
||||
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/C2587.asp">
|
||||
<code>C2587</code></a><code>: '_U' : illegal use of local variable as
|
||||
default parameter</code>, inside the MSVC internal header
|
||||
<code><xlocnum></code>.
|
||||
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="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
|
||||
of <code>multi_index_container</code> iterator constructor. Two workarounds exist:
|
||||
the first consists of avoiding this constructor and replacing
|
||||
code like:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><...></span> <span class=identifier>s</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
with equivalent operations:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><...></span> <span class=identifier>s</span><span class=special>;</span>
|
||||
<span class=identifier>s</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The second workaround has not been confirmed by the author, but it is given
|
||||
on the Internet in connection with this error appearing in other libraries.
|
||||
Replace line 84 of <code><xlocnum></code>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span> <span class=keyword>virtual</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
with the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<b>Warning</b>: it is not known whether this
|
||||
replacement can result in unexpected side effects in code implicitly
|
||||
using <code><xlocnum></code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
In general, the extensive use of templates by Boost.MultiIndex puts this compiler
|
||||
under severe stress, so that several internal limitations may be reached.
|
||||
The following measures can help alleviate these problems:
|
||||
<ul>
|
||||
<li>Set the compiler option <code>/Zm</code> (Specify Memory Allocation Limit)
|
||||
to increase the amount of memory available for compilation. Usual values for
|
||||
this option range from 300 to 800.</li>
|
||||
<li>If in debug mode, try switching from <code>/ZI</code> (Program Database for
|
||||
Edit and Continue) to a less demanding type of debugging information
|
||||
(<code>/Zi</code>, <code>/Z7</code> or <code>/Zd</code>.)</li>
|
||||
<li>Play with the precompiled headers options. Usually, turning this feature
|
||||
off yields the best results.</li>
|
||||
<li>If the compiler emits the error
|
||||
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/c1055.asp">
|
||||
<code>C1055</code></a><code>: compiler limit : out of keys</code>, try
|
||||
disabling the option <code>/Gm</code> (Enable Minimal Rebuild.) In these
|
||||
cases, it is also beneficial to split the project into smaller
|
||||
subprojects.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5
|
||||
+ STLport 4.5.3</a>
|
||||
</h2>
|
||||
|
||||
<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.
|
||||
</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.)
|
||||
</p>
|
||||
|
||||
<h2><a name="msvc_70">Microsoft Visual C++ 7.0</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.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
No support for <a href="reference/multi_index_container.html#index_retrieval">index retrieval</a>
|
||||
and <a href="reference/multi_index_container.html#projection">projection</a>
|
||||
nested types and member functions:
|
||||
<ul>
|
||||
<li><code>nth_index</code>,</li>
|
||||
<li><code>index</code>,</li>
|
||||
<li><code>nth_index_iterator</code>,</li>
|
||||
<li><code>nth_index_const_iterator</code>,</li>
|
||||
<li><code>index_iterator</code>,</li>
|
||||
<li><code>index_const_iterator</code>,</li>
|
||||
<li><code>get</code>,</li>
|
||||
<li><code>project</code>.</li>
|
||||
</ul>
|
||||
You can use instead their global equivalents. Also, this compiler does not
|
||||
implement argument dependent lookup, so you might need to explicitly qualify
|
||||
these global names with <code>::boost::multi_index</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
<code>boost::multi_index::multi_index_container</code> is imported to
|
||||
<code>namespace boost</code> by means of a <code>using</code> declaration.
|
||||
MSVC++ 7.0, however, does not properly handle this import. So, instead of
|
||||
writing:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
use the following:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
or else resort to a directive <code>using namespace boost::multi_index</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><hr></blockquote>
|
||||
|
||||
<p>
|
||||
The lack of partial template specialization support in MSVC++ 7.0
|
||||
results in some inconveniences when using <code>composite_key</code> that
|
||||
can be remedied as explained in
|
||||
<a href="#composite_key_no_pts">"<code>composite_key</code>
|
||||
in compilers without partial template specialization"</a>.
|
||||
</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">
|
||||
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_80">Microsoft Visual C++ 8.0</a></h2>
|
||||
|
||||
<p>
|
||||
No problems have been detected with this compiler. The Beta 2 version of
|
||||
this product was used for the testing.
|
||||
</p>
|
||||
|
||||
<h2><a name="portability">Portability techniques</a></h2>
|
||||
|
||||
<h3><a name="member_offset">Use of <code>member_offset</code></a></h3>
|
||||
|
||||
<p>
|
||||
The <code>member</code> key extractor poses some problems in compilers
|
||||
that do not properly support pointers to members as non-type
|
||||
template arguments, as indicated by the
|
||||
<a href="../../../libs/config/config.htm">Boost Configuration Library</a>
|
||||
defect macro <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code>.
|
||||
The following compilers have been confirmed not
|
||||
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>
|
||||
</ul>
|
||||
This program can help determine if your compiler
|
||||
properly supports pointers to members as non-type template parameters:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>iostream</span><span class=special>></span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>pair</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>y</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>pair</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>x_</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>y_</span><span class=special>):</span><span class=identifier>x</span><span class=special>(</span><span class=identifier>x_</span><span class=special>),</span><span class=identifier>y</span><span class=special>(</span><span class=identifier>y_</span><span class=special>){}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>pair</span><span class=special>::*</span> <span class=identifier>PtrToPairMember</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>foo</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>bar</span><span class=special>(</span><span class=identifier>pair</span><span class=special>&</span> <span class=identifier>p</span><span class=special>){</span><span class=keyword>return</span> <span class=identifier>p</span><span class=special>.*</span><span class=identifier>PtrToPairMember</span><span class=special>;}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>pair</span> <span class=identifier>p</span><span class=special>(</span><span class=number>0</span><span class=special>,</span><span class=number>1</span><span class=special>);</span>
|
||||
<span class=identifier>foo</span><span class=special><&</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>x</span><span class=special>></span> <span class=identifier>fx</span><span class=special>;</span>
|
||||
<span class=identifier>foo</span><span class=special><&</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>y</span><span class=special>></span> <span class=identifier>fy</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>if</span><span class=special>(</span><span class=identifier>fx</span><span class=special>.</span><span class=identifier>bar</span><span class=special>(</span><span class=identifier>p</span><span class=special>)!=</span><span class=number>0</span><span class=special>||</span><span class=identifier>fy</span><span class=special>.</span><span class=identifier>bar</span><span class=special>(</span><span class=identifier>p</span><span class=special>)!=</span><span class=number>1</span><span class=special>)</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special><<</span><span class=string>"KO"</span><span class=special><<</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span>
|
||||
<span class=keyword>else</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special><<</span><span class=string>"OK"</span><span class=special><<</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>return</span> <span class=number>0</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
If you find a compiler that does not pass the test, and for which
|
||||
<code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code> is <i>not</i> defined,
|
||||
please report to the Boost developers mailing list.
|
||||
</p>
|
||||
<p>To overcome this defect, a replacement utility
|
||||
<a href="reference/key_extraction.html#member_offset"><code>member_offset</code></a>
|
||||
has been provided that does the work of <code>member</code> at the
|
||||
expense of less convenient notation and the possibility of
|
||||
non-conformance with the standard. Please consult
|
||||
the reference for further information on <code>member_offset</code>.
|
||||
As an example of use, given the class
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>class</span> <span class=identifier>A</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
the instantiation <code>member<A,int,&A::x></code> can be simulated then
|
||||
as <code>member_offset<A,int,offsetof(A,x)></code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For those writing portable code, Boost.MultiIndex provides the ternary macro
|
||||
<a href="reference/key_extraction.html#boost_multi_index_member"><code>BOOST_MULTI_INDEX_MEMBER</code></a>.
|
||||
Continuing with the example above, the
|
||||
expression
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>BOOST_MULTI_INDEX_MEMBER</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>x</span><span class=special>)</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
expands by default to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>x</span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
or alternatively to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>member_offset</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>offsetof</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=identifier>x</span><span class=special>)></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
if <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code> is defined.
|
||||
</p>
|
||||
|
||||
<h3><a name="mem_fun_explicit">Use of <code>const_mem_fun_explicit</code> and
|
||||
<code>mem_fun_explicit</code></a></h3>
|
||||
|
||||
<p>
|
||||
MSVC++ 6.0 has problems with <code>const</code> member functions as non-type
|
||||
template parameters, and thus does not accept the <code>const_mem_fun</code>
|
||||
key extractor. A simple workaround, fortunately, has been found, consisting
|
||||
in specifying the <i>type</i> of these pointers as an additional template
|
||||
parameter. The alternative
|
||||
<a href="reference/key_extraction.html#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>
|
||||
extractor adopts this solution; for instance, given the type
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>A</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>int</span> <span class=identifier>f</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
the extractor <code>const_mem_fun<A,int,&A::f></code> can be replaced by
|
||||
<code>const_mem_fun_explicit<A,int,int (A::*)()const,&A::f></code>. A similar
|
||||
<code>mem_fun_explicit</code> class template is provided for non-constant
|
||||
member functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you are writing cross-platform code, the selection of either key extractor
|
||||
is transparently handled by the macro
|
||||
<a href="reference/key_extraction.html#boost_multi_index_const_mem_fun"><code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code></a>,
|
||||
so that
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>f</span><span class=special>)</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
expands by default to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>const_mem_fun</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
but resolves to
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>const_mem_fun_explicit</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=keyword>int</span> <span class=special>(</span><span class=identifier>A</span><span class=special>::*)()</span><span class=keyword>const</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
in MSVC++ 6.0. Non-<code>const</code> member functions are covered by
|
||||
<a href="reference/key_extraction.html#mem_fun_explicit"><code>mem_fun_explicit</code></a>
|
||||
and the macro
|
||||
<a href="reference/key_extraction.html#boost_multi_index_mem_fun"><code>BOOST_MULTI_INDEX_MEM_FUN</code></a>.
|
||||
</p>
|
||||
|
||||
<h3><a name="composite_key_no_pts"><code>composite_key</code> in compilers
|
||||
without partial template specialization</a></h3>
|
||||
|
||||
<p>
|
||||
When using <code>composite_key</code>s, lookup is performed by passing
|
||||
tuples of values: this ability is achieved by suitably specializing
|
||||
the class templates <code>std::equal_to</code>, <code>std::less</code>,
|
||||
<code>std::greater</code> and <code>boost::hash</code> for
|
||||
<a href="reference/key_extraction.html#composite_key_result">
|
||||
<code>composite_key_result</code></a> instantiations so that they
|
||||
provide the appropriate overloads accepting tuples --and in the case
|
||||
of <code>std::less</code> and <code>std::greater</code>, also partial
|
||||
tuples where only the first components are specified.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In those compilers that do not support partial template specialization,
|
||||
these specializations cannot be provided, and so
|
||||
tuple-based lookup is not available by default. In this case,
|
||||
<code>multi_index_container</code> instantiations using composite keys
|
||||
will work as expected, both for ordered and hashed indices,
|
||||
except that lookup operations will not accept tuples as an argument.
|
||||
For ordered indices, the most obvious workaround
|
||||
to this deficiency involves explicitly specifying the comparison
|
||||
predicate with
|
||||
<a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>;
|
||||
in the case of hashed indices we can use the analogous
|
||||
<a href="reference/key_extraction.html#composite_key_equal_to"><code>composite_key_equal_to</code></a>
|
||||
and
|
||||
<a href="reference/key_extraction.html#composite_key_hash"><code>composite_key_hash</code></a>.
|
||||
This substitution is tedious as the elementary components for all the constituent key extractors must
|
||||
be explicitly typed. For this reason, Boost.MultiIndex provides the following replacement
|
||||
class templates
|
||||
<ul>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_equal_to">
|
||||
<code>composite_key_result_equal_to</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_less">
|
||||
<code>composite_key_result_less</code></a>,</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_greater">
|
||||
<code>composite_key_result_greater</code></a> and</li>
|
||||
<li><a href="reference/key_extraction.html#composite_key_result_hash">
|
||||
<code>composite_key_result_hash</code></a>,</li>
|
||||
</ul>
|
||||
that act as the missing specializations of <code>std::equal_to</code>, <code>std::less</code>,
|
||||
<code>std::greater</code> and <code>boost::hash</code> for <code>composite_key_result</code>s.
|
||||
They can be used as follows:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>composite_key</span><span class=special><</span>
|
||||
<span class=identifier>phonebook_entry</span><span class=special>,</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>family_name</span><span class=special>>,</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>given_name</span><span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>ckey_t</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>phonebook_entry</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span>
|
||||
<span class=identifier>ckey_t</span><span class=special>,</span>
|
||||
<span class=comment>// composite_key_result_less plays the role of
|
||||
// std::less<ckey_t::result_type></span>
|
||||
<span class=identifier>composite_key_result_less</span><span class=special><</span><span class=identifier>ckey_t</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>phone_number</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>phonebook</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="symbol_reduction">Reduction of symbol name lengths</a></h3>
|
||||
|
||||
<p>
|
||||
The types generated on the instantiations of <code>multi_index_container</code>s
|
||||
typically produce very long symbol names, sometimes beyond the internal limits
|
||||
of some compilers. There are several techniques to shorten generated symbol
|
||||
names: these techniques have also the beneficial side effect that resulting error
|
||||
messages are more readable.
|
||||
</p>
|
||||
|
||||
<h4><a name="argument_limitation">Limitation of maximum number of arguments</a></h4>
|
||||
|
||||
<p>
|
||||
The class templates <a href="reference/indices.html#indexed_by"><code>indexed_by</code></a>,
|
||||
<a href="reference/indices.html#tag"><code>tag</code></a> and
|
||||
<a href="reference/key_extraction.html#composite_key"><code>composite_key</code></a>
|
||||
accept a variable number of arguments whose maximum number is limited by
|
||||
internal macros. Even non-used arguments contribute to the final types,
|
||||
so manually adjusting the corresponding macros can result in a modest reduction
|
||||
of symbol names.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<caption><b>Limiting maximum number of arguments of some class templates
|
||||
of Boost.MultiIndex.</b></caption>
|
||||
<tr>
|
||||
<th>class template</th>
|
||||
<th>limiting macro</th>
|
||||
<th>default value</th>
|
||||
<th>default value<br>(MSVC++ 6.0)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"> <code>indexed_by</code> </td>
|
||||
<td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE</code> </td>
|
||||
<td align="center">20</td>
|
||||
<td align="center">5</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td align="center"> <code>tag</code> </td>
|
||||
<td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_TAG_SIZE</code> </td>
|
||||
<td align="center">20</td>
|
||||
<td align="center">3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"> <code>composite_key</code> </td>
|
||||
<td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE</code> </td>
|
||||
<td align="center">10</td>
|
||||
<td align="center">5</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<h4><a name="type_hiding">Type hiding</a></h4>
|
||||
|
||||
<p>
|
||||
Consider a typical instantiation of <code>multi_index_container</code>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>employee_set</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Then, for instance, the type <code>employee_set::nth_type<0>::type</code>
|
||||
resolves to the following in GCC:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_index</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>nth_layer</span><span class=special><</span>
|
||||
<span class=number>1</span><span class=special>,</span> <span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_unique</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_non_unique</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span> <span class=special>&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_unique</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span> <span class=keyword>int</span><span class=special>,</span> <span class=special>&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span>
|
||||
<span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>vector0</span><span class=special><</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_unique_tag</span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
It can be seen that a significant portion of the type name is contributed by
|
||||
the <code>indexed_by<...></code> part, which is nothing but an expanded
|
||||
version of the index specifier list provided in the definition of
|
||||
<code>employee_set</code>. We can prevent this very long name from appearing
|
||||
in the final type by encapsulating it into another, shorter-named construct:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// reducing symbol names through type hiding
|
||||
// type hide the index spexifier list within employee_set_indices</span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>employee_set_indices</span><span class=special>:</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>{};</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>employee_set_indices</span>
|
||||
<span class=special>></span> <span class=identifier>employee_set</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>employee_set_indices</code> works as a conventional <code>typedef</code>
|
||||
in all respects, save for a detail: its name does not explicitly
|
||||
include the information contained in the <code>indexed_by</code> instantiation.
|
||||
Applying this technique, <code>employee_set::nth_type<0>::type</code>
|
||||
now becomes:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_index</span><span class=special><</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>nth_layer</span><span class=special><</span>
|
||||
<span class=number>1</span><span class=special>,</span> <span class=identifier>employee</span><span class=special>,</span>
|
||||
<span class=identifier>employee_set_indices</span><span class=special>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span>
|
||||
<span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>vector0</span><span class=special><</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>>,</span>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_unique_tag</span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
which is considerably shorter than the original, and also more
|
||||
easily parsed by a human reader. Type hiding would not work if, instead of
|
||||
making <code>employee_set_indices</code> a derived <code>struct</code> of
|
||||
<code>indexed_by<...></code>, we had defined it as a <code>typedef</code>:
|
||||
<code>typedef</code>s are syntactic aliases and usually get expanded
|
||||
by the compiler before doing any further type handling.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Type hiding techniques can also be applied to <code>composite_key</code> intantiations,
|
||||
which often contribute a great deal to symbol name lengths.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="performance.html"><img src="next.gif" alt="performance" border="0"><br>
|
||||
Performance
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 26th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,360 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Examples</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Examples</h1>
|
||||
|
||||
<div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br>
|
||||
Performance
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="tests.html"><img src="next.gif" alt="tests" border="0"><br>
|
||||
Tests
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<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="#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>
|
||||
<li><a href="#example5">Example 5: sequenced indices</a></li>
|
||||
<li><a href="#example6">Example 6: complex searches and foreign keys</a></li>
|
||||
<li><a href="#example7">Example 7: composite keys</a></li>
|
||||
<li><a href="#example8">Example 8: hashed indices</a></li>
|
||||
<li><a href="#example9">Example 9: serialization and MRU lists</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="example1">Example 1: basic usage</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/basic.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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>
|
||||
|
||||
<p>
|
||||
See <a href="../example/memfun_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
|
||||
<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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Keys based on member 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
|
||||
constraint anyway.
|
||||
</p>
|
||||
|
||||
<h2><a name="example3">Example 3: constructing <code>multi_index_container</code>s
|
||||
with <code>ctor_args_list</code></a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/non_default_ctor.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
We show a practical example of usage of <code>multi_index_container::ctor_arg_list</code>,
|
||||
whose definition and purpose are explained in the
|
||||
<a href="advanced_topics.html#ctor_args_list">Advanced topics section</a>. The
|
||||
program groups a sorted collection of numbers based on identification through
|
||||
modulo arithmetics, by which <code>x</code> and <code>y</code> are equivalent
|
||||
if <code>(x%n)==(y%n)</code>, for some fixed <code>n</code>.
|
||||
</p>
|
||||
|
||||
<h2><a name="example4">Example 4: bidirectional map</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/bimap.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This example shows how to construct a bidirectional map with
|
||||
<code>multi_index_container</code>. By a <i>bidirectional map</i> we mean
|
||||
a container of elements of <code>std::pair<const FromType,const ToType></code>
|
||||
such that no two elements exists with the same <code>first</code>
|
||||
<i>or</i> <code>second</code> value (<code>std::map</code> only
|
||||
guarantees uniqueness of the first member). Fast lookup is provided
|
||||
for both keys. The program features a tiny Spanish-English
|
||||
dictionary with online query of words in both languages.
|
||||
</p>
|
||||
|
||||
<h2><a name="example5">Example 5: sequenced indices</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/sequenced.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The combination of a sequenced index with an index of type <code>ordered_non_unique</code>
|
||||
yields a <code>list</code>-like structure with fast lookup capabilities. The
|
||||
example performs some operations on a given text, like word counting and
|
||||
selective deletion of some words.
|
||||
</p>
|
||||
|
||||
<h2><a name="example6">Example 6: complex searches and foreign keys</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/complex_structs.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This program illustrates some advanced techniques that can be applied
|
||||
for complex data structures using <code>multi_index_container</code>.
|
||||
Consider a <code>car_model</code> class for storing information
|
||||
about automobiles. On a first approach, <code>car_model</code> can
|
||||
be defined as:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>car_model</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>model</span><span class=special>;</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>manufacturer</span><span class=special>;</span>
|
||||
<span class=keyword>int</span> <span class=identifier>price</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
This definition has a design flaw that any reader acquainted with
|
||||
relational databases can easily spot: The <code>manufacturer</code>
|
||||
member is duplicated among all cars having the same manufacturer.
|
||||
This is a waste of space and poses difficulties when, for instance,
|
||||
the name of a manufacturer has to be changed. Following the usual
|
||||
principles in relational database design, the appropriate design
|
||||
involves having the manufactures stored in a separate
|
||||
<code>multi_index_container</code> and store pointers to these in
|
||||
<code>car_model</code>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>car_manufacturer</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>struct</span> <span class=identifier>car_model</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>model</span><span class=special>;</span>
|
||||
<span class=identifier>car_manufacturer</span><span class=special>*</span> <span class=identifier>manufacturer</span><span class=special>;</span>
|
||||
<span class=keyword>int</span> <span class=identifier>price</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Although predefined Boost.MultiIndex key extractors can handle many
|
||||
situations involving pointers (see
|
||||
<a href="advanced_topics.html#advanced_key_extractors">advanced features
|
||||
of Boost.MultiIndex key extractors</a> in the Advanced topics section), this case
|
||||
is complex enough that a suitable key extractor has to be defined. The following
|
||||
utility cascades two key extractors:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>class</span> <span class=identifier>KeyExtractor1</span><span class=special>,</span><span class=keyword>class</span> <span class=identifier>KeyExtractor2</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>key_from_key</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>public</span><span class=special>:</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>KeyExtractor1</span><span class=special>::</span><span class=identifier>result_type</span> <span class=identifier>result_type</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>key_from_key</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>KeyExtractor1</span><span class=special>&</span> <span class=identifier>key1_</span><span class=special>=</span><span class=identifier>KeyExtractor1</span><span class=special>(),</span>
|
||||
<span class=keyword>const</span> <span class=identifier>KeyExtractor2</span><span class=special>&</span> <span class=identifier>key2_</span><span class=special>=</span><span class=identifier>KeyExtractor2</span><span class=special>()):</span>
|
||||
<span class=identifier>key1</span><span class=special>(</span><span class=identifier>key1_</span><span class=special>),</span><span class=identifier>key2</span><span class=special>(</span><span class=identifier>key2_</span><span class=special>)</span>
|
||||
<span class=special>{}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Arg</span><span class=special>></span>
|
||||
<span class=identifier>result_type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Arg</span><span class=special>&</span> <span class=identifier>arg</span><span class=special>)</span><span class=keyword>const</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>key1</span><span class=special>(</span><span class=identifier>key2</span><span class=special>(</span><span class=identifier>arg</span><span class=special>));</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>private</span><span class=special>:</span>
|
||||
<span class=identifier>KeyExtractor1</span> <span class=identifier>key1</span><span class=special>;</span>
|
||||
<span class=identifier>KeyExtractor2</span> <span class=identifier>key2</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
so that access from a <code>car_model</code> to the <code>name</code> field
|
||||
of its associated <code>car_manufacturer</code> can be accomplished with
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>key_from_key</span><span class=special><</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>car_manufacturer</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&</span><span class=identifier>car_manufacturer</span><span class=special>::</span><span class=identifier>name</span><span class=special>>,</span>
|
||||
<span class=identifier>member</span><span class=special><</span><span class=identifier>car_model</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>car_manufacturer</span> <span class=special>*,</span><span class=identifier>car_model</span><span class=special>::</span><span class=identifier>manufacturer</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The program asks the user for a car manufacturer and a range of prices
|
||||
and returns the car models satisfying these requirements. This is a complex
|
||||
search that cannot be performed on a single operation. Broadly sketched,
|
||||
one procedure for executing the selection is:
|
||||
<ol>
|
||||
<li>Select the elements with the given manufacturer by means
|
||||
of <code>equal_range</code>,
|
||||
<li>feed these elements into a <code>multi_index_container</code> sorted
|
||||
by price,
|
||||
<li>select by price using <code>lower_bound</code> and
|
||||
<code>upper_bound</code>;
|
||||
</ol>
|
||||
or alternatively:
|
||||
<ol>
|
||||
<li>Select the elements within the price range with
|
||||
<code>lower_bound</code> and <code>upper_bound</code>,
|
||||
<li>feed these elements into a <code>multi_index_container</code> sorted
|
||||
by manufacturer,
|
||||
<li>locate the elements with given manufacturer using
|
||||
<code>equal_range</code>.
|
||||
</ol>
|
||||
An interesting technique developed in the example lies in
|
||||
the construction of the intermediate <code>multi_index_container</code>.
|
||||
In order to avoid object copying, appropriate <i>view</i> types
|
||||
are defined with <code>multi_index_container</code>s having as elements
|
||||
pointers to <code>car_model</code>s instead of actual objects.
|
||||
These views have to be supplemented with appropriate
|
||||
dereferencing key extractors.
|
||||
</p>
|
||||
|
||||
<h2><a name="example7">Example 7: composite keys</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/composite_keys.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex <a href="advanced_topics.html#composite_keys">
|
||||
<code>composite_key</code></a> construct provides a flexible tool for
|
||||
creating indices with non-trivial sorting criteria.
|
||||
The program features a rudimentary simulation of a file system
|
||||
along with an interactive Unix-like shell. A file entry is represented by
|
||||
the following structure:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>file_entry</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name</span><span class=special>;</span>
|
||||
<span class=keyword>unsigned</span> <span class=identifier>size</span><span class=special>;</span>
|
||||
<span class=keyword>bool</span> <span class=identifier>is_dir</span><span class=special>;</span> <span class=comment>// true if the entry is a directory</span>
|
||||
<span class=keyword>const</span> <span class=identifier>file_entry</span><span class=special>*</span> <span class=identifier>dir</span><span class=special>;</span> <span class=comment>// directory this entry belongs in</span>
|
||||
<span class=special>};</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Entries are kept in a <code>multi_index_container</code> maintaining two indices
|
||||
with composite keys:
|
||||
<ul>
|
||||
<li>A primary index ordered by directory and name,</li>
|
||||
<li>a secondary index ordered by directory and size.</li>
|
||||
</ul>
|
||||
The reason that the order is made firstly by the directory in which
|
||||
the files are located obeys to the local nature of the shell commands,
|
||||
like for instance <code>ls</code>. The shell simulation only has three
|
||||
commands:
|
||||
<ul>
|
||||
<li><code>cd [.|..|<i><directory></i>]</code></li>
|
||||
<li><code>ls [-s]</code> (<code>-s</code> orders the output by size)</li>
|
||||
<li><code>mkdir <i><directory></i></code></li>
|
||||
</ul>
|
||||
The program exits when the user presses the Enter key at the command prompt.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The reader is challenged to add more functionality to the program; for
|
||||
instance:
|
||||
<ul>
|
||||
<li>Implement additional commands, like <code>cp</code>.</li>
|
||||
<li>Add handling of absolute paths.</li>
|
||||
<li>Use <a href="advanced_topics.html#serialization">serialization</a>
|
||||
to store and retrieve the filesystem state between program runs.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="example8">Example 8: hashed indices</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/hashed.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Hashed indices can be used as an alternative to ordered indices when
|
||||
fast lookup is needed and sorting information is of no interest. The
|
||||
example features a word counter where duplicate entries are checked
|
||||
by means of a hashed index. Confront the word counting algorithm with
|
||||
that of <a href="#example5">example 5</a>.
|
||||
</p>
|
||||
|
||||
<h2><a name="example9">Example 9: serialization and MRU lists</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../example/serialization.cpp">source code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A typical application of serialization capabilities allows a program to
|
||||
restore the user context between executions. The example program asks
|
||||
the user for words and keeps a record of the ten most recently entered
|
||||
ones, in the current or in previous sessions. The serialized data structure,
|
||||
sometimes called an <i>MRU (most recently used) list</i>, has some interest
|
||||
on its own: an MRU list behaves as a regular FIFO queue, with the exception
|
||||
that, when inserting a preexistent entry, this does not appear twice, but
|
||||
instead the entry is moved to the front of the list. You can observe this
|
||||
behavior in many programs featuring a "Recent files" menu command. This
|
||||
data structure is implemented with <code>multi_index_container</code> by
|
||||
combining a sequenced index and an index of type <code>hashed_unique</code>.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br>
|
||||
Performance
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="tests.html"><img src="next.gif" alt="tests" border="0"><br>
|
||||
Tests
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised August 22nd 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,268 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Future work</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Future work</h1>
|
||||
|
||||
<div class="prev_link"><a href="tests.html"><img src="prev.gif" alt="tests" border="0"><br>
|
||||
Tests
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="release_notes.html"><img src="next.gif" alt="release notes" border="0"><br>
|
||||
Release notes
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
A number of new functionalities are considered for inclusion into
|
||||
future releases of Boost.MultiIndex. Some of them depend on the
|
||||
potential for extensibility of the library, which has been a guiding
|
||||
principle driving the current internal design of <code>multi_index_container</code>.
|
||||
</p>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#ranked_indices">Ranked indices</a></li>
|
||||
<li><a href="#random_access_indices">Random access indices</a></li>
|
||||
<li><a href="#notifying">Notifying indices</a></li>
|
||||
<li><a href="#constraints">Constraints</a></li>
|
||||
<li><a href="#user_defined_indices">User-defined indices</a></li>
|
||||
<li><a href="#bimap">Bidirectional map</a></li>
|
||||
<li><a href="#indexed_maps">Indexed maps</a></li>
|
||||
<li><a href="#move_semantics">Move semantics</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="ranked_indices">Ranked indices</a></h2>
|
||||
|
||||
<p>
|
||||
Ordered indices are implemented using red-black trees; these trees
|
||||
can be augmented with additional information to obtain a type
|
||||
of data structure called
|
||||
<a href="http://pine.cs.yale.edu/pinewiki/OrderStatisticsTree"><i>order-statistics
|
||||
trees</i></a>, allowing for logarithmic search of the <i>n</i>-th element. It
|
||||
has been proposed that order-statistics trees be used to devise a new type of
|
||||
<i>ranked indices</i> that support <code>operator[]</code> while retaining
|
||||
the functionality of ordered indices.
|
||||
</p>
|
||||
|
||||
<h2><a name="random_access_indices">Random access indices</a></h2>
|
||||
|
||||
<p>
|
||||
These indices provide random access iterators and location of elements
|
||||
by their position ordinal. Although they seem at first glance to model
|
||||
the semantics of <code>std::vector</code>, random access indices present
|
||||
important differences:
|
||||
<ul>
|
||||
<li>Iterator and reference validity is preserved on insertion and deletion,</li>
|
||||
<li>memory contiguity is not provided,</li>
|
||||
<li>standard mutating algorithms (vg. <code>std::sort</code>) will in general
|
||||
not work with random access indices, as elements of a
|
||||
<code>multi_index_container</code> cannot be directly moved or swapped;</li>
|
||||
</ul>
|
||||
so it might be more accurate to regard this type of indices as a variation of
|
||||
sequenced indices with random access semantics.
|
||||
</p>
|
||||
|
||||
<h2><a name="notifying">Notifying indices</a></h2>
|
||||
|
||||
<p>
|
||||
<i>Notifying indices</i> can be implemented as decorators over
|
||||
preexistent index types, with the added functionality that internal
|
||||
events of the index (insertion, erasing, modifying of elements) are
|
||||
signalled to an external entity --for instance, by means of the
|
||||
<a href="../../../doc/html/signals.html">Boost.Signals</a>
|
||||
library. This functionality can have applications for:
|
||||
<ol>
|
||||
<li>Logging,</li>
|
||||
<li>interfacing to GUI-based applications,</li>
|
||||
<li>synchronization between separate data structures.</li>
|
||||
</ol>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following is a sketch of a possible realization of notifying
|
||||
indices:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>insert_log</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>void</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>int</span> <span class=identifier>x</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>clog</span><span class=special><<</span><span class=string>"insert: "</span><span class=special><<</span><span class=identifier>x</span><span class=special><<</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>notifying</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span> <span class=special>>,</span> <span class=comment>// notifying index</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>indexed_t</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>indexed_t</span> <span class=identifier>t</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// on_insert is the signal associated to insertions</span>
|
||||
<span class=identifier>t</span><span class=special>.</span><span class=identifier>on_insert</span><span class=special>.</span><span class=identifier>connect</span><span class=special>(</span><span class=identifier>insert_log</span><span class=special>());</span>
|
||||
|
||||
<span class=identifier>t</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>0</span><span class=special>);</span>
|
||||
<span class=identifier>t</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>1</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>return</span> <span class=number>0</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// output:
|
||||
// insert: 0
|
||||
// insert: 1</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h2><a name="constraints">Constraints</a></h2>
|
||||
|
||||
<p>
|
||||
The notifying indices functionality described above exploits a powerful
|
||||
design pattern based on <i>index adaptors</i>, decorators over preexistent
|
||||
indices which add some functionality or somehow change the semantics of
|
||||
the underlying index. This pattern can be used for the implementation
|
||||
of <i>constraints</i>, adaptors that restrict the elements accepted by an
|
||||
index according to some validation predicate. The following is a possible
|
||||
realization of how constraints syntax may look like:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>struct</span> <span class=identifier>is_even</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>int</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>x</span><span class=special>%</span><span class=number>2</span><span class=special>==</span><span class=number>0</span><span class=special>;}</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>constrained</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span><span class=identifier>is_even</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>indexed_t</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h2><a name="user_defined_indices">User-defined indices</a></h2>
|
||||
|
||||
<p>
|
||||
The mechanisms by which Boost.MultiIndex orchestrates the
|
||||
operations of the indices held by a <code>multi_index_container</code> are
|
||||
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>
|
||||
<code>multi_index_container</code> is rich enough to provide the basis
|
||||
for implementation of <i>indexed maps</i>, i.e. maps which
|
||||
can be looked upon several different keys. The motivation for having
|
||||
such a container is mainly aesthetic convenience, since it
|
||||
would not provide any additional feature to similar constructs
|
||||
based directly on <code>multi_index_container</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The main challenge in writing an indexed map lies in the design of a
|
||||
reasonable interface that resembles that of <code>std::map</code> as
|
||||
much as possible. There seem to be fundamental difficulties in extending
|
||||
the syntax of a <code>std::map</code> to multiple keys. For one example,
|
||||
consider the situation:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>indexed_map</span><span class=special><</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>string</span><span class=special>,</span><span class=keyword>double</span><span class=special>></span> <span class=identifier>m</span><span class=special>;</span>
|
||||
<span class=comment>// keys are int and string, double is the mapped to value</span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=identifier>cout</span><span class=special><<</span><span class=identifier>m</span><span class=special>[</span><span class=number>0</span><span class=special>]<<</span><span class=identifier>endl</span><span class=special>;</span> <span class=comment>// OK</span>
|
||||
<span class=identifier>cout</span><span class=special><<</span><span class=identifier>m</span><span class=special>[</span><span class=string>"zero"</span><span class=special>]<<</span><span class=identifier>endl</span><span class=special>;</span> <span class=comment>// OK</span>
|
||||
<span class=identifier>m</span><span class=special>[</span><span class=number>1</span><span class=special>]=</span><span class=number>1.0</span><span class=special>;</span> <span class=comment>// !!</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
In the last sentence of the example, the user has no way of
|
||||
providing the <code>string</code> key mapping to the same value
|
||||
as <code>m[1]</code>. This and similar problems have to be devoted
|
||||
a careful study when designing the interface of a potential
|
||||
indexed map.
|
||||
</p>
|
||||
|
||||
<h2><a name="move_semantics">Move semantics</a></h2>
|
||||
|
||||
<p>
|
||||
Andrei Alexandrescu introduced a technique for simulating move
|
||||
constructors called Mojo (see his article in C/C++ User Journal
|
||||
<a href="http://www.cuj.com/documents/s=8246/cujcexp2102alexandr/">
|
||||
"Generic<Programming>: Move Constructors"</a>.) Move semantics
|
||||
alleviates the computational load involved in the creation and copying
|
||||
of temporary objects, specially for heavy classes as
|
||||
<code>multi_index_container</code>s are. David Abrahams and Gary Powell provide
|
||||
an alternative implementation of move semantics in their paper
|
||||
<a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html">
|
||||
"Clarification of Initialization of Class Objects by rvalues"</a> for
|
||||
the C++ Evolution Working Group.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Adding move semantics to <code>multi_index_container</code> is particularly
|
||||
beneficial when the container is used as an internal building block in other
|
||||
libraries (vg. relational database frameworks), enabling the efficient
|
||||
development of functions returning <code>multi_index_container</code>s. Without support
|
||||
for move semantics, this scheme is impractical and less elegant syntaxes
|
||||
should be resorted to.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="tests.html"><img src="prev.gif" alt="tests" border="0"><br>
|
||||
Tests
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="release_notes.html"><img src="next.gif" alt="release notes" border="0"><br>
|
||||
Release notes
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 5th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,97 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Index</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost Multi-index Containers Library</h1>
|
||||
|
||||
<div class="prev_link"></div>
|
||||
<div class="up_link"></div>
|
||||
<div class="next_link"><a href="tutorial.html"><img src="next.gif" alt="tutorial" border="0"><br>
|
||||
Tutorial
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
The Boost Multi-index Containers Library provides a class template named
|
||||
<code>multi_index_container</code> which enables the construction of containers
|
||||
maintaining one or more <i>indices</i> with different sorting and access semantics.
|
||||
Indices provide interfaces similar to those of STL containers, making using them
|
||||
familiar. The concept of multi-indexing over the same collection of elements is
|
||||
borrowed from relational database terminology and allows for the specification of
|
||||
complex data structures in the spirit of multiply indexed relational tables where
|
||||
simple sets and maps are not enough. A wide selection of indices is provided,
|
||||
modeled after analogous STL containers like <code>std::set</code>,
|
||||
<code>std::list</code> and hashed sets.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex features additional functionalities, like subobject searching,
|
||||
range querying and in-place updating of elements, which make it a convenient replacement
|
||||
for <code>std::set</code> and <code>set::multiset</code> even when no multi-indexing
|
||||
capabilities are needed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The versatile nature of Boost.MultiIndex allows for the specification of
|
||||
a wide spectrum of different data structures. The following are possible
|
||||
examples of use developed in the documentation:
|
||||
<ul>
|
||||
<li><a href="tutorial.html#multipe_sort">Sets with several iteration orders
|
||||
and search criteria</a>.</li>
|
||||
<li><a href="tutorial.html#list_fast_lookup">Lists with fast lookup</a>
|
||||
and/or without duplicates.</li>
|
||||
<li><a href="examples.html#example4">Bidirectional maps</a>, i.e. maps
|
||||
searchable either for key or value.</li>
|
||||
<li><a href="examples.html#example9">MRU (most recently used) lists</a>,
|
||||
structures keeping the <i>n</i> last referenced items, beginning with
|
||||
the newest ones.</li>
|
||||
<li><a href="advanced_topics.html#emulate_std_containers">Emulations of
|
||||
standard containers</a> taking advantage of the extra functionalities
|
||||
provided by Boost.MultiIndex.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="tutorial.html">Tutorial</a></li>
|
||||
<li><a href="advanced_topics.html">Advanced topics</a></li>
|
||||
<li><a href="reference/index.html">Reference</a></li>
|
||||
<li><a href="compiler_specifics.html">Compiler specifics</a></li>
|
||||
<li><a href="performance.html">Performance</a></li>
|
||||
<li><a href="examples.html">Examples</a></li>
|
||||
<li><a href="tests.html">Tests</a></li>
|
||||
<li><a href="future_work.html">Future work</a></li>
|
||||
<li><a href="release_notes.html">Release notes</a></li>
|
||||
<li><a href="acknowledgements.html">Acknowledgements</a></li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"></div>
|
||||
<div class="up_link"></div>
|
||||
<div class="next_link"><a href="tutorial.html"><img src="next.gif" alt="tutorial" border="0"><br>
|
||||
Tutorial
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised March 15th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
BIN
doc/lopez.jpg
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 85 KiB |
BIN
doc/next.gif
|
Before Width: | Height: | Size: 852 B |
BIN
doc/perf_1o.png
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB |
BIN
doc/perf_1s.png
|
Before Width: | Height: | Size: 13 KiB |
BIN
doc/perf_2o.png
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 13 KiB |
BIN
doc/perf_3o.png
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,724 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Performance</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Performance</h1>
|
||||
|
||||
<div class="prev_link"><a href="compiler_specifics.html"><img src="prev.gif" alt="compiler specifics" border="0"><br>
|
||||
Compiler specifics
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="examples.html"><img src="next.gif" alt="examples" border="0"><br>
|
||||
Examples
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#intro">Introduction</a></li>
|
||||
<li><a href="#simulation">Manual simulation of a <code>multi_index_container</code></a></li>
|
||||
<li><a href="#spatial_efficiency">Spatial efficiency</a></li>
|
||||
<li><a href="#time_efficiency">Time efficiency</a></li>
|
||||
<li><a href="#tests">Performance tests</a>
|
||||
<ul>
|
||||
<li><a href="#test_1r">Results for 1 ordered index</a>
|
||||
<ul>
|
||||
<li><a href="#memory_1r">Memory consumption</a></li>
|
||||
<li><a href="#time_1r">Execution time</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#test_1s">Results for 1 sequenced index</a>
|
||||
<ul>
|
||||
<li><a href="#memory_1s">Memory consumption</a></li>
|
||||
<li><a href="#time_1s">Execution time</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#test_2r">Results for 2 ordered indices</a>
|
||||
<ul>
|
||||
<li><a href="#memory_2r">Memory consumption</a></li>
|
||||
<li><a href="#time_2r">Execution time</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#test_1r1s">Results for 1 ordered index + 1 sequenced index</a>
|
||||
<ul>
|
||||
<li><a href="#memory_1r1s">Memory consumption</a></li>
|
||||
<li><a href="#time_1r1s">Execution time</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#test_3r">Results for 3 ordered indices</a>
|
||||
<ul>
|
||||
<li><a href="#memory_3r">Memory consumption</a></li>
|
||||
<li><a href="#time_3r">Execution time</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#test_2r1s">Results for 2 ordered indices + 1 sequenced index</a>
|
||||
<ul>
|
||||
<li><a href="#memory_2r1s">Memory consumption</a></li>
|
||||
<li><a href="#time_2r1s">Execution time</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#conclusions">Conclusions</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="intro">Introduction</a></h2>
|
||||
|
||||
<p>
|
||||
Boost.MultiIndex helps the programmer to avoid the manual construction of cumbersome
|
||||
compositions of containers when multi-indexing capabilities are needed. Furthermore,
|
||||
it does so in an efficient manner, both in terms of space and time consumption. The
|
||||
space savings stem from the compact representation of the underlying data structures,
|
||||
requiring a single node per element. As for time efficiency, Boost.MultiIndex
|
||||
intensively uses metaprogramming techniques producing very tight implementations
|
||||
of member functions which take care of the elementary operations for each index:
|
||||
for <code>multi_index_container</code>s with two or more indices, the running time
|
||||
can be reduced to half as long as with manual simulations involving several
|
||||
STL containers.
|
||||
</p>
|
||||
|
||||
<h2><a name="simulation">Manual simulation of a <code>multi_index_container</code></a></h2>
|
||||
|
||||
<p>
|
||||
The section on <a href="advanced_topics.html#emulate_std_containers">emulation
|
||||
of standard containers with <code>multi_index_container</code></a> shows the equivalence
|
||||
between single-index <code>multi_index_container</code>s and some STL containers. Let us now
|
||||
concentrate on the problem of simulating a <code>multi_index_container</code> with two
|
||||
or more indices with a suitable combination of standard containers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider the following instantiation of <code>multi_index_container</code>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>>,</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span> <span class=special>>,</span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>indexed_t</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>indexed_t</code> maintains two internal indices on elements of type
|
||||
<code>int</code>. In order to simulate this data structure resorting only to
|
||||
standard STL containers, one can use on a first approach the following types:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// dereferencing compare predicate</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Iterator</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>it_compare</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Iterator</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>Iterator</span><span class=special>&</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>comp</span><span class=special>(*</span><span class=identifier>x</span><span class=special>,*</span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>private</span><span class=special>:</span>
|
||||
<span class=identifier>Compare</span> <span class=identifier>comp</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=identifier>manual_t1</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #0</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special><</span>
|
||||
<span class=keyword>const</span> <span class=keyword>int</span><span class=special>*,</span>
|
||||
<span class=identifier>it_compare</span><span class=special><</span>
|
||||
<span class=keyword>const</span> <span class=keyword>int</span><span class=special>*,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special><</span><span class=keyword>int</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>manual_t2</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #1</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
where <code>manual_t1</code> is the "base" container that holds
|
||||
the actual elements, and <code>manual_t2</code> stores pointers to
|
||||
elements of <code>manual_t1</code>. This scheme turns out to be quite
|
||||
inefficient, though: while insertion into the data structure is simple enough:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>manual_t1</span> <span class=identifier>c1</span><span class=special>;</span>
|
||||
<span class=identifier>manual_t2</span> <span class=identifier>c2</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// insert the element 5</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>=</span><span class=identifier>c1</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>5</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(&*</span><span class=identifier>t1</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
deletion, on the other hand, necessitates a logarithmic search, whereas
|
||||
<code>indexed_t</code> deletes in constant time:
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// remove the element pointed to by it2</span>
|
||||
<span class=identifier>manual_t2</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it2</span><span class=special>=...;</span>
|
||||
<span class=identifier>c1</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(*</span><span class=identifier>it2</span><span class=special>);</span> <span class=comment>// watch out! performs in logarithmic time</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>it1</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The right approach consists of feeding the second container not with
|
||||
raw pointers, but with elements of type <code>manual_t1::iterator</code>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=identifier>manual_t1</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #0</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special><</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>,</span>
|
||||
<span class=identifier>it_compare</span><span class=special><</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>,</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special><</span><span class=keyword>int</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>manual_t2</span><span class=special>;</span> <span class=comment>// equivalent to indexed_t's index #1</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Now, insertion and deletion can be performed with complexity bounds
|
||||
equivalent to those of <code>indexed_t</code>:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>manual_t1</span> <span class=identifier>c1</span><span class=special>;</span>
|
||||
<span class=identifier>manual_t2</span> <span class=identifier>c2</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// insert the element 5</span>
|
||||
<span class=identifier>manual_t1</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>=</span><span class=identifier>c1</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=number>5</span><span class=special>).</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>t1</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// remove the element pointed to by it2</span>
|
||||
<span class=identifier>manual_t2</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>it2</span><span class=special>=...;</span>
|
||||
<span class=identifier>c1</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(*</span><span class=identifier>it2</span><span class=special>);</span> <span class=comment>// OK: constant time</span>
|
||||
<span class=identifier>c2</span><span class=special>.</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>it1</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The construction can be extended in a straightworward manner to
|
||||
handle more than two indices. In what follows, we will compare
|
||||
instantiations of <code>multi_index_container</code> against this sort of
|
||||
manual simulations.
|
||||
</p>
|
||||
|
||||
<h2><a name="spatial_efficiency">Spatial efficiency</a></h2>
|
||||
|
||||
<p>
|
||||
The gain in space consumption of <code>multi_index_container</code> with
|
||||
respect to its manual simulations is amenable to a very simple
|
||||
theoretical analysis. For simplicity, we will ignore alignment
|
||||
issues (which in general play in favor of <code>multi_index_container</code>.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Nodes of a <code>multi_index_container</code> with <i>N</i> indices hold the value
|
||||
of the element plus <i>N</i> headers containing linking information for
|
||||
each index. Thus the node size is
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<i>S<sub>I</sub></i> = <i>e</i> + <i>h</i><sub>0</sub> + ··· +
|
||||
<i>h</i><sub><i>N</i>-1</sub>, where<br>
|
||||
<i>e</i> = size of the element,<br>
|
||||
<i>h</i><sub><i>i</i></sub> = size of the <i>i</i>-th header.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
On the other hand, the manual simulation allocates <i>N</i> nodes per
|
||||
element, the first holding the elements themselves and the rest
|
||||
storing iterators to the "base" container. In practice, an iterator
|
||||
merely holds a raw pointer to the node it is associated to, so its size
|
||||
is independent of the type of the elements. Suming all contributions,
|
||||
the space allocated per element in a manual simulation is
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<i>S<sub>M</sub></i> = (<i>e</i> + <i>h</i><sub>0</sub>) +
|
||||
(<i>p</i> + <i>h</i><sub>1</sub>) + ··· +
|
||||
(<i>p</i> + <i>h</i><sub><i>N</i>-1</sub>) =
|
||||
<i>S<sub>I</sub></i> + (<i>N</i>-1)<i>p</i>, where<br>
|
||||
<i>p</i> = size of a pointer.<br>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
The relative amount of memory taken up by <code>multi_index_container</code>
|
||||
with respect to its manual simulation is just
|
||||
<i>S<sub>I</sub></i> / <i>S<sub>M</sub></i>, which can be expressed
|
||||
then as:
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<i>S<sub>I</sub></i> / <i>S<sub>M</sub></i> =
|
||||
<i>S<sub>I</sub></i> / (<i>S<sub>I</sub></i> + (<i>N</i>-1)<i>p</i>).
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
The formula shows that <code>multi_index_container</code> is more efficient
|
||||
with regard to memory consumption as the number of indices grow.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These considerations have overlooked an aspect of the greatest practical
|
||||
importance: the fact that <code>multi_index_container</code> allocates a single
|
||||
node per element, compared to the many nodes of different sizes
|
||||
built by manual simulations, diminishes memory fragmentation, which
|
||||
can show up in more usable memory available and better performance.
|
||||
</p>
|
||||
|
||||
<h2><a name="time_efficiency">Time efficiency</a></h2>
|
||||
|
||||
<p>
|
||||
From the point of view of computational complexity (i.e. big-O
|
||||
characterization), <code>multi_index_container</code> and its corresponding manual
|
||||
simulations are equivalent: inserting an element into
|
||||
a <code>multi_index_container</code> reduces to a simple combination of
|
||||
elementary insertion operations on each of the indices, and
|
||||
similarly for deletion. Hence, the most we can expect is a reduction
|
||||
(or increase) of execution time by a roughly constant factor. As we
|
||||
will see later, the reduction can be very significative for
|
||||
<code>multi_index_container</code>s with two or more indices.
|
||||
</p>
|
||||
|
||||
<p>In the special case of <code>multi_index_container</code>s with only one index,
|
||||
the best we can hope for is equal performance: the tests show that the
|
||||
performance degradation in this particular situation ranges from negligible
|
||||
to small, depending on the compiler used.
|
||||
</p>
|
||||
|
||||
<h2><a name="tests">Performance tests</a></h2>
|
||||
|
||||
<p>
|
||||
See <a href="../perf/test_perf.cpp">source code</a> used for measurements.
|
||||
<p>
|
||||
In order to assess the efficiency of <code>multi_index_container</code>, the following
|
||||
basic algorithm
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><...></span> <span class=identifier>c</span><span class=special>;</span>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>i</span><span class=special>=</span><span class=number>0</span><span class=special>;</span><span class=identifier>i</span><span class=special><</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>();</span><span class=identifier>it</span><span class=special>!=</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</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>it</span><span class=special>++);</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
has been measured for different instantiations of <code>multi_index_container</code>
|
||||
at values of <i>n</i> 1,000, 10,000 and 100,000,
|
||||
and its execution time compared with that of the equivalent algorithm
|
||||
for the corresponding manual simulation of the data structure based on
|
||||
STL containers. The following compilers have been used:
|
||||
<ul>
|
||||
<li>GNU GCC 3.3.1 for Cygwin 1.5.7,</li>
|
||||
<li>Intel C++ Compiler for Windows 32-bit 7.1,</li>
|
||||
<li>Microsoft Visual C++ 6.0 Service Pack 5,</li>
|
||||
</ul>
|
||||
with their default release settings. All tests were performed on a Wintel
|
||||
box equipped with a P4 1.5GHz processor and 256 MB RAM, running
|
||||
Microsoft Windows 2000 Professional SP2.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The relative memory consumption (i.e. the amount of memory allocated
|
||||
by a <code>multi_index_container</code> with respect to its manual simulation)
|
||||
is determined by dividing the size of a <code>multi_index_container</code> node
|
||||
by the sum of node sizes of all the containers integrating the
|
||||
simulating data structure.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_1r">Results for 1 ordered index</a></h3>
|
||||
|
||||
<p>
|
||||
The following instantiation of <code>multi_index_container</code> was tested:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
which is functionally equivalent to <code>std::set<int></code>.
|
||||
</p>
|
||||
|
||||
<h4><a name="memory_1r">Memory consumption</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">100%</td>
|
||||
<td align="center">100%</td>
|
||||
<td align="center">100%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 1: Relative memory consumption of <code>multi_index_container</code> with 1
|
||||
ordered index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The figures confirm that in this case <code>multi_index_container</code> nodes are the
|
||||
same size than those of its <code>std::set</code> counterpart.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_1r">Execution time</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<img src="perf_1o.png" alt="performance of multi_index_container with 1 ordered index"
|
||||
width="556" height="372"><br>
|
||||
<b>Fig. 1: Performance of <code>multi_index_container</code> with 1 ordered index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As expected, <code>multi_index_container</code> does perform in this case somewhat
|
||||
worse than <code>std::set</code>. The degradation is within 10% for ICC and
|
||||
MSVC compilers, while in GCC peaks to 20%, which can be significative
|
||||
in certain applications. This latter result is presumably accounted for by
|
||||
a lower quality of the optimizing stage carried out by GCC.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_1s">Results for 1 sequenced index</a></h3>
|
||||
|
||||
<p>
|
||||
The following instantiation of <code>multi_index_container</code> was tested:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>sequenced</span><span class=special><></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
which is functionally equivalent to <code>std::list<int></code>.
|
||||
</p>
|
||||
|
||||
<h4><a name="memory_1s">Memory consumption</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">100%</td>
|
||||
<td align="center">100%</td>
|
||||
<td align="center">100%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 2: Relative memory consumption of <code>multi_index_container</code> with 1
|
||||
sequenced index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The figures confirm that in this case <code>multi_index_container</code> nodes are the
|
||||
same size than those of its <code>std::list</code> counterpart.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_1s">Execution time</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<img src="perf_1s.png" alt="performance of multi_index_container with 1 sequenced index"
|
||||
width="556" height="372"><br>
|
||||
<b>Fig. 2: Performance of <code>multi_index_container</code> with 1 sequenced index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As in the former case, <code>multi_index_container</code> does not attain the performance
|
||||
of its STL counterpart. Again, worst results are those of GCC, with a
|
||||
degradation of up to 20% , while ICC and MSVC do not exceed a mere 5%.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_2r">Results for 2 ordered indices</a></h3>
|
||||
|
||||
<p>
|
||||
The following instantiation of <code>multi_index_container</code> was tested:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h4><a name="memory_2r">Memory consumption</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">90%</td>
|
||||
<td align="center">90%</td>
|
||||
<td align="center">90%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 3: Relative memory consumption of <code>multi_index_container</code> with 2
|
||||
ordered indices.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These results concinde with the theoretical formula for
|
||||
<i>S<sub>I</sub></i>=36 and <i>p</i>=4.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_2r">Execution time</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<img src="perf_2o.png" alt="performance of multi_index_container with 2 ordered indices"
|
||||
width="556" height="372"><br>
|
||||
<b>Fig. 3: Performance of <code>multi_index_container</code> with 2 ordered indices.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The experimental results confirm our hypothesis that <code>multi_index_container</code>
|
||||
provides an improvement on execution time by an approximately constant factor,
|
||||
which in this case ranges from 65% to 75% depending on the compiler.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_1r1s">Results for 1 ordered index + 1 sequenced index</a></h3>
|
||||
|
||||
<p>
|
||||
The following instantiation of <code>multi_index_container</code> was tested:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>sequenced</span><span class=special><></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h4><a name="memory_1r1s">Memory consumption</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">87.5%</td>
|
||||
<td align="center">87.5%</td>
|
||||
<td align="center">87.5%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 4: Relative memory consumption of <code>multi_index_container</code> with 1
|
||||
ordered index + 1 sequenced index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These results concinde with the theoretical formula for
|
||||
<i>S<sub>I</sub></i>=28 and <i>p</i>=4.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_1r1s">Execution time</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<img src="perf_1o1s.png"
|
||||
alt="performance of multi_index_container with 1 ordered index + 1 sequenced index"
|
||||
width="556" height="372"><br>
|
||||
<b>Fig. 4: Performance of <code>multi_index_container</code> with 1 ordered index
|
||||
+ 1 sequenced index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For <i>n</i>=10<sup>3</sup> and <i>n</i>=10<sup>4</sup>, the results
|
||||
are in agreement with our theoretical analysis, showing a constant factor
|
||||
improvement of 60-75% with respect to the STL-based manual simulation.
|
||||
Curiously enough, this speedup gets even higher when
|
||||
<i>n</i>=10<sup>5</sup> for two of the compilers (35% for ICC,
|
||||
25% for MSVC.) In order to rule out spurious results, the tests
|
||||
have been run many times, yielding similar outcoumes. A tentative
|
||||
explanation of this unexpected behavior may point to a degradation in
|
||||
the execution time of the manual simulation, attributable to poor
|
||||
performance of the standard STL allocator in ICC and MSVC when dealing
|
||||
with many objects of diverse sizes (the manual simulation is comprised of
|
||||
an <code>std::set</code> and a <code>std::list</code>, which demand
|
||||
differently sized nodes.)
|
||||
</p>
|
||||
|
||||
<h3><a name="test_3r">Results for 3 ordered indices</a></h3>
|
||||
|
||||
<p>
|
||||
The following instantiation of <code>multi_index_container</code> was tested:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h4><a name="memory_3r">Memory consumption</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">86.7%</td>
|
||||
<td align="center">86.7%</td>
|
||||
<td align="center">86.7%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 5: Relative memory consumption of <code>multi_index_container</code> with 3
|
||||
ordered indices.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These results concinde with the theoretical formula for
|
||||
<i>S<sub>I</sub></i>=52 and <i>p</i>=4.
|
||||
|
||||
</p>
|
||||
|
||||
<h4><a name="time_3r">Execution time</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<img src="perf_3o.png" alt="performance of multi_index_container with 3 ordered indices"
|
||||
width="556" height="372"><br>
|
||||
<b>Fig. 5: Performance of <code>multi_index_container</code> with 3 ordered indices.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Execution time for this case is between 55% and 65% lower than achieved with
|
||||
an STL-based manual simulation of the same data structure.
|
||||
</p>
|
||||
|
||||
<h3><a name="test_2r1s">Results for 2 ordered indices + 1 sequenced index</a></h3>
|
||||
|
||||
<p>
|
||||
The following instantiation of <code>multi_index_container</code> was tested:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</span><span class=special>,</span>
|
||||
<span class=identifier>indexed_by</span><span class=special><</span>
|
||||
<span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>>,</span>
|
||||
<span class=identifier>sequenced</span><span class=special><></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h4><a name="memory_2r1s">Memory consumption</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th width="33%">GCC 3.1.1</th>
|
||||
<th width="33%">ICC 7.1</th>
|
||||
<th width="33%">MSVC 6.5</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">84.6%</td>
|
||||
<td align="center">84.6%</td>
|
||||
<td align="center">84.6%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>Table 6: Relative memory consumption of <code>multi_index_container</code> with 2
|
||||
ordered indices + 1 sequenced index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These results concinde with the theoretical formula for
|
||||
<i>S<sub>I</sub></i>=44 and <i>p</i>=4.
|
||||
</p>
|
||||
|
||||
<h4><a name="time_2r1s">Execution time</a></h4>
|
||||
|
||||
<p align="center">
|
||||
<img src="perf_2o1s.png"
|
||||
alt="performance of multi_index_container with 2 ordered indices + 1 sequenced index"
|
||||
width="556" height="372"><br>
|
||||
<b>Fig. 6: Performance of <code>multi_index_container</code> with 2 ordered indices
|
||||
+ 1 sequenced index.</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In accordance to the expectations, execution time is improved by a fairly constant
|
||||
factor, which ranges from 45% to 55%.
|
||||
</p>
|
||||
|
||||
<h2><a name="conclusions">Conclusions</a></h2>
|
||||
|
||||
<p>
|
||||
We have shown that <code>multi_index_container</code> outperforms, both in space and
|
||||
time efficiency, equivalent data structures obtained from the manual
|
||||
combination of STL containers. This improvement gets larger when the number
|
||||
of indices increase.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the special case of replacing standard containers with single-indexed
|
||||
<code>multi_index_container</code>s, the programmer should balance the benefits brought on
|
||||
by Boost.MultiIndex (subobject searching, in-place updating, etc.) against the
|
||||
resulting degradation in execution time. Depending on the compiler, this degradation
|
||||
can reach up to 20% of the original time.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="compiler_specifics.html"><img src="prev.gif" alt="compiler specifics" border="0"><br>
|
||||
Compiler specifics
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="examples.html"><img src="next.gif" alt="examples" border="0"><br>
|
||||
Examples
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 18th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
BIN
doc/prev.gif
|
Before Width: | Height: | Size: 852 B |
@@ -1,904 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Hashed indices reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Hashed indices reference</h1>
|
||||
|
||||
<div class="prev_link"><a href="ord_indices.html"><img src="../prev.gif" alt="ordered indices" border="0"><br>
|
||||
Ordered indices
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="seq_indices.html"><img src="../next.gif" alt="sequenced indices" border="0"><br>
|
||||
Sequenced indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#hash_index_fwd_synopsis">Header
|
||||
<code>"boost/multi_index/hashed_index_fwd.hpp"</code> synopsis</a></li>
|
||||
<li><a href="#synopsis">Header
|
||||
<code>"boost/multi_index/hashed_index.hpp"</code> synopsis</a>
|
||||
<ul>
|
||||
<li><a href="#unique_non_unique">
|
||||
Index specifiers <code>hashed_unique</code> and <code>hashed_non_unique</code>
|
||||
</a></li>
|
||||
<li><a href="#hash_indices">Hashed indices</a>
|
||||
<ul>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<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="#modifiers">Modifiers</a></li>
|
||||
<li><a href="#observers">Observers</a></li>
|
||||
<li><a href="#lookup">Lookup</a></li>
|
||||
<li><a href="#hash_policy">Hash policy</a></li>
|
||||
<li><a href="#serialization">Serialization</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a name="hash_index_fwd_synopsis">Header
|
||||
<a href="../../../../boost/multi_index/hashed_index_fwd.hpp">
|
||||
<code>"boost/multi_index/hashed_index_fwd.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=comment>// index specifiers hashed_unique and hashed_non_unique</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult hashed_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>hashed_unique</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult hashed_non_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>hashed_non_unique</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// indices</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span> <span class=keyword>class</span> <b>index name is implementation defined</b><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>hashed_index_fwd.hpp</code> provides forward declarations for index specifiers
|
||||
<a href="#unique_non_unique"><code>hashed_unique</code> and <code>hashed_non_unique</code></a> and
|
||||
their associated <a href="#hash_indices">hashed index</a> classes.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="synopsis">Header
|
||||
<a href="../../../../boost/multi_index/hashed_index.hpp">
|
||||
<code>"boost/multi_index/hashed_index.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=comment>// index specifiers hashed_unique and hashed_non_unique</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult hashed_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>hashed_unique</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult hashed_non_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>hashed_non_unique</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// indices</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span> <span class=keyword>class</span> <b>index class name implementation defined</b><span class=special>;</span>
|
||||
|
||||
<span class=comment>// index specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="unique_non_unique">
|
||||
Index specifiers <code>hashed_unique</code> and <code>hashed_non_unique</code>
|
||||
</a></h3>
|
||||
|
||||
<p>
|
||||
These <a href="indices.html#index_specification">index specifiers</a> allow
|
||||
for insertion of <a href="#hash_indices">hashed indices</a> without and with
|
||||
allowance of duplicate elements, respectively. The syntax of <code>hashed_unique</code>
|
||||
and <code>hashed_non_unique</code> coincide, thus we describe them in a grouped manner.
|
||||
<code>hashed_unique</code> and <code>hashed_non_unique</code> can be instantiated in
|
||||
two different forms, according to whether a tag list for the index is provided or not:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Hash</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special><</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Pred</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special><</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>hashed_unique</span> <span class=special>|</span> <span class=identifier>hashed_non_unique</span><span class=special>)</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>TagList</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Hash</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special><</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Pred</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special><</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>hashed_unique</span> <span class=special>|</span> <span class=identifier>hashed_non_unique</span><span class=special>)</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
If provided, <code>TagList</code> must be an instantiation of the class template
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
The template arguments are used by the corresponding index implementation,
|
||||
refer to the <a href="#hash_indices">hashed indices</a> reference section for further
|
||||
explanations on their acceptable type values.
|
||||
</p>
|
||||
|
||||
<h3><a name="hash_indices">Hashed indices</a></h3>
|
||||
|
||||
<p>
|
||||
A hashed index provides fast retrieval of elements of a <code>multi_index_container</code>
|
||||
through hashing tecnhiques. The interface and semantics of hashed indices are modeled according
|
||||
to the proposal for unordered associative containers given in the C++
|
||||
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf">Proposed
|
||||
Draft Tecnhical Report on Standard Library Extensions</a>, also known as TR1. A hashed
|
||||
index is particularized according to a given
|
||||
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
|
||||
that retrieves keys from elements of <code>multi_index_container</code>, a <code>Hash</code>
|
||||
function object which returns hash values for the keys and a binary predicate <code>Pred</code>
|
||||
acting as an equivalence relation on values of <code>Key</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are two variants of hashed indices: <i>unique</i>, which do
|
||||
not allow duplicate elements (with respect to its associated equality
|
||||
predicate) and <i>non-unique</i>, which accept those duplicates.
|
||||
The interface of these two variants is the same, so they are documented
|
||||
together, with minor differences explicitly stated when they exist.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Except where noted, hashed indices (both unique and non-unique) are models of
|
||||
<code>Unordered Associative Container</code>, in the spirit of
|
||||
<code>std::tr1::unordered_set</code>s. Validity of iterators and references to
|
||||
elements is preserved in all cases. Occasionally, the exception safety guarantees provided
|
||||
are actually stronger than required by the extension draft. We only provide descriptions
|
||||
of those types and operations that are either not present in the concepts modeled or
|
||||
do not exactly conform to the requirements for unordered associative containers.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined: dependent on types Value, Allocator,
|
||||
TagList, KeyFromValue, Hash, Pred</b><span class=special>></span>
|
||||
<span class=keyword>class</span> <b>name is implementation defined</b>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>public</span><span class=special>:</span>
|
||||
<span class=comment>// types:</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span> <span class=identifier>key_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>KeyFromValue</span> <span class=identifier>key_from_value</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Hash</span> <span class=identifier>hasher</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Pred</span> <span class=identifier>key_equal</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>tuple</span><span class=special><</span>
|
||||
<span class=identifier>size_type</span><span class=special>,</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>hasher</span><span class=special>,</span><span class=identifier>key_equal</span><span class=special>></span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>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>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>size_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>difference_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>const_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>local_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>const_local_iterator</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// construct/destroy/copy:</span>
|
||||
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// size and 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>
|
||||
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// iterators:</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>();</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span><span class=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=comment>// modifiers:</span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>erase</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>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>void</span> <span class=identifier>clear</span><span class=special>();</span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// observers:</span>
|
||||
|
||||
<span class=identifier>key_from_value</span> <span class=identifier>key_extractor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>hasher</span> <span class=identifier>hash_function</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>key_equal</span> <span class=identifier>key_eq</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// lookup:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>find</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleHash</span><span class=special>,</span> <span class=keyword>typename</span> <span class=identifier>CompatiblePred</span>
|
||||
<span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>find</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleHash</span><span class=special>&</span> <span class=identifier>hash</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatiblePred</span><span class=special>&</span> <span class=identifier>eq</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleHash</span><span class=special>,</span> <span class=keyword>typename</span> <span class=identifier>CompatiblePred</span>
|
||||
<span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleHash</span><span class=special>&</span> <span class=identifier>hash</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatiblePred</span><span class=special>&</span> <span class=identifier>eq</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>></span> <span class=identifier>equal_range</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleHash</span><span class=special>,</span> <span class=keyword>typename</span> <span class=identifier>CompatiblePred</span>
|
||||
<span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>></span> <span class=identifier>equal_range</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,
|
||||
</span><span class=keyword>const</span> <span class=identifier>CompatibleHash</span><span class=special>&</span> <span class=identifier>hash</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatiblePred</span><span class=special>&</span> <span class=identifier>eq</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// bucket interface:</span>
|
||||
|
||||
<span class=identifier>size_type</span> <span class=identifier>bucket_count</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_bucket_count</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>bucket_size</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>bucket</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&</span> <span class=identifier>k</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>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=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=comment>// hash policy:</span>
|
||||
|
||||
<span class=keyword>float</span> <span class=identifier>load_factor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>float</span> <span class=identifier>max_load_factor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>void</span> <span class=identifier>max_load_factor</span><span class=special>(</span><span class=keyword>float</span> <span class=identifier>z</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>rehash</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>);</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=comment>// index specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h4><a name="complexity_signature">Complexity signature</a></h4>
|
||||
|
||||
<p>
|
||||
Here and in the descriptions of operations of hashed indices, we adopt the
|
||||
scheme outlined in the
|
||||
<a href="indices.html#complexity_signature">complexity signature
|
||||
section</a>. The complexity signature of hashed indices is:
|
||||
<ul>
|
||||
<li>copying: <code>c(n)=n*log(n)</code>,</li>
|
||||
<li>insertion: average case <code>i(n)=1</code> (constant),
|
||||
worst case <code>i(n)=n</code>,</li>
|
||||
<li>hinted insertion: average case <code>h(n)=1</code> (constant),
|
||||
worst case <code>h(n)=n</code>,</li>
|
||||
<li>deletion: average case <code>d(n)=1</code> (constant),
|
||||
worst case <code>d(n)=n</code>,</li>
|
||||
<li>replacement:
|
||||
<ul>
|
||||
<li>if the new element key is equivalent to the original, <code>r(n)=1</code> (constant),</li>
|
||||
<li>otherwise, average case <code>r(n)=1</code> (constant),
|
||||
worst case <code>r(n)=n</code>,</li>
|
||||
</ul></li>
|
||||
<li>modifying: average case <code>m(n)=1</code> (constant),
|
||||
worst case <code>m(n)=n</code>.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h4><a name="instantiation_types">Instantiation types</a></h4>
|
||||
|
||||
<p>Hashed indices are instantiated internally to <code>multi_index_container</code> and
|
||||
specified by means of <a href="indices.html#indexed_by"><code>indexed_by</code></a>
|
||||
with <a href="#unique_non_unique"> index specifiers <code>hashed_unique</code>
|
||||
and <code>hashed_non_unique</code></a>. Instantiations are dependent on the
|
||||
following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided),</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>
|
||||
</ul>
|
||||
<code>TagList</code> must be an instantiation of
|
||||
<a href="indices.html#tag"><code>tag</code></a>. The type <code>KeyFromValue</code>,
|
||||
which determines the mechanism for extracting a key from <code>Value</code>,
|
||||
must be a model of <a href="key_extraction.html#key_extractors">
|
||||
<code>Key Extractor</code></a> from <code>Value</code>. <code>Hash</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"><code>Unary Function</code></a>
|
||||
taking a single argument of type <code>KeyFromValue::result_type</code> and returning a
|
||||
value of type <code>std::size_t</code> in the range
|
||||
<code>[0, std::numeric_limits<std::size_t>::max())</code>.
|
||||
<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 elements of <code>KeyFromValue::result_type</code>. It is required that
|
||||
the <code>Hash</code> object return the same value for keys
|
||||
equivalent under <code>Pred</code>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>ctor_args</code>
|
||||
|
||||
<blockquote>
|
||||
The first element of this tuple indicates the minimum number of buckets
|
||||
set up by the index on construction time. If the default value 0 is used,
|
||||
an implementation defined number is used instead.
|
||||
</blockquote>
|
||||
|
||||
<code>iterator<br>
|
||||
const_iterator<br>
|
||||
local_iterator<br>
|
||||
const_local_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types are models of
|
||||
<a href="http://www.sgi.com/tech/stl/ForwardIterator.html"><code>Forward
|
||||
Iterator</code></a>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<p>
|
||||
As explained in the <a href="indices.html#index_concepts">index
|
||||
concepts section</a>, indices do not have public constructors or destructors.
|
||||
Assignment, on the other hand, is provided. Upon construction,
|
||||
<code>max_load_factor()</code> is 1.0.
|
||||
</p>
|
||||
|
||||
<code><b>index class name</b>& operator=(const <b>index class name</b>& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>a</span><span class=special>=</span><span class=identifier>b</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
where <code>a</code> and <code>b</code> are the <code>multi_index_container</code>
|
||||
objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="modifiers">Modifiers</a></h4>
|
||||
|
||||
<code>std::pair<iterator,bool> insert(const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful insertion,
|
||||
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator insert(iterator position,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<code>position</code> is used as a hint to improve the efficiency of the
|
||||
operation.<br>
|
||||
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
|
||||
element. Otherwise, an iterator to an element that caused the insertion to be
|
||||
banned. Note that more than one element can be causing insertion not to be
|
||||
allowed.<br>
|
||||
<b>Complexity:</b> <code>O(H(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename InputIterator><br>
|
||||
void insert(InputIterator first,InputIterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<b>Effects:</b>
|
||||
<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>
|
||||
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>hint</span><span class=special>=</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>hint</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
|
||||
</pre></blockquote>
|
||||
<b>Complexity:</b> <code>O(m*H(n+m))</code>, where
|
||||
<code>m</code> is the number of elements in [<code>first</code>,
|
||||
<code>last</code>).<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator erase(iterator position);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
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>
|
||||
if no such element exists.<br>
|
||||
<b>Complexity:</b> <code>O(D(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>size_type erase(const key_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Deletes the elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Returns:</b> Number of elements deleted.<br>
|
||||
<b>Complexity:</b> Average case, <code>O(1 + m*D(n))</code>, worst case
|
||||
<code>O(n + m*D(n))</code>, where <code>m</code> is
|
||||
the number of elements deleted.<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator erase(iterator first,iterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> [<code>first</code>,<code>last</code>) is a valid
|
||||
range of the index.<br>
|
||||
<b>Effects:</b> Deletes the elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Returns:</b> <code>last</code>.<br>
|
||||
<b>Complexity:</b> <code>O(m*D(n))</code>, where <code>m</code> is
|
||||
the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<a name="replace"><code>bool replace(iterator position,const value_type& x);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
to by <code>position</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if, for the value <code>x</code>
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists
|
||||
(except possibly <code>*position</code>) with equivalent key,</li>
|
||||
<li>AND replacing is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved
|
||||
in all cases.<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>
|
||||
<b>Exception safety:</b> Strong. If an exception is thrown by some
|
||||
user-provided operation the <code>multi_index_container</code> to which the index
|
||||
belongs remains in its original state.
|
||||
</blockquote>
|
||||
|
||||
<a name="modify">
|
||||
<code>template<typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <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>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
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
|
||||
<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.
|
||||
</blockquote>
|
||||
|
||||
<a name="modify_key">
|
||||
<code>template<typename Modifier> bool modify_key(iterator position,Modifier mod);</code></a>
|
||||
|
||||
<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> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<code>key_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
<b>Effects:</b> Calls <code>mod(k)</code> where <code>k</code> is the key
|
||||
obtained by the internal <code>KeyFromValue</code> object of the index from
|
||||
the element pointed to by <code>position</code>, and rearranges
|
||||
<code>*position</code> into all the indices of the <code>multi_index_container</code>.
|
||||
Rearrangement is successful if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists
|
||||
with equivalent key,</li>
|
||||
<li>AND rearrangement is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
If the rearrangement fails, the element is erased.<br>
|
||||
<b>Postconditions:</b>Validity of <code>position</code> is preserved if
|
||||
the operation succeeds.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
<b>Exception safety:</b> Basic. If an exception is thrown by some
|
||||
user-provided operation (except possibly <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="observers">Observers</a></h4>
|
||||
|
||||
<p>Apart from standard <code>hash_function</code> and <code>key_eq</code>,
|
||||
hashed indices have a member function for retrieving the internal key extractor
|
||||
used.
|
||||
</p>
|
||||
|
||||
<code>key_from_value key_extractor()const;</code>
|
||||
|
||||
<blockquote>
|
||||
Returns a copy of the <code>key_from_value</code> object used to construct
|
||||
the index.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="lookup">Lookup</a></h4>
|
||||
|
||||
<p>
|
||||
Hashed indices provide the full lookup functionality required by
|
||||
unordered associative containers, namely <code>find</code>,
|
||||
<code>count</code>, and <code>equal_range</code>. Additionally,
|
||||
these member functions are templatized to allow for non-standard
|
||||
arguments, so extending the types of search operations allowed.
|
||||
The kind of arguments permissible when invoking the lookup member
|
||||
functions is defined by the following concept.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider a pair (<code>Hash</code>, <code>Pred</code>) where
|
||||
<code>Hash</code> is a hash functor over values of type <code>Key</code>
|
||||
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
|
||||
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>
|
||||
of (<code>Hash</code>, <code>Pred</code>) if
|
||||
<ol>
|
||||
<li><code>CompatibleHash</code> is a hash functor on values of
|
||||
type <code>CompatibleKey</code>,</li>
|
||||
<li><code>CompatiblePred</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
|
||||
<code>Binary Predicate</code></a> over (<code>Key</code>,
|
||||
<code>CompatibleKey</code>),</li>
|
||||
<li><code>CompatiblePred</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
|
||||
<code>Binary Predicate</code></a> over (<code>CompatibleKey</code>,
|
||||
<code>Key</code>),</li>
|
||||
<li>if <code>c_eq(ck,k1)</code> then <code>c_eq(k1,ck)</code>,</li>
|
||||
<li>if <code>c_eq(ck,k1)</code> and <code>eq(k1,k2)</code> then
|
||||
<code>c_eq(ck,k2)</code>,</li>
|
||||
<li>if <code>c_eq(ck,k1)</code> and <code>c_eq(ck,k2)</code> then
|
||||
<code>eq(k1,k2)</code>,</li>
|
||||
<li>if <code>c_eq(ck,k1)</code> then <code>c_hash(ck)==hash(k1)</code>,</li>
|
||||
</ol>
|
||||
for every <code>c_hash</code> of type <code>CompatibleHash</code>,
|
||||
<code>c_eq</code> of type <code>CompatiblePred</code>,
|
||||
<code>hash</code> of type <code>Hash</code>,
|
||||
<code>eq</code> of type <code>Pred</code>, <code>ck</code> of type
|
||||
<code>CompatibleKey</code> and <code>k1</code>, <code>k2</code> of type
|
||||
<code>Key</code>.
|
||||
</p>
|
||||
|
||||
<p>Additionally, a type <code>CompatibleKey</code> is said to be a
|
||||
<i>compatible key</i> of (<code>Hash</code>, <code>Pred</code>) if
|
||||
(<code>CompatibleKey</code>, <code>Hash</code>, <code>Pred</code>)
|
||||
is a compatible extension of (<code>Hash</code>, <code>Pred</code>).
|
||||
This implies that <code>Hash</code> and <code>Pred</code> accept arguments
|
||||
of type <code>CompatibleKey</code>, which usually means they have
|
||||
several overloads of therir corresponding <code>operator()</code>
|
||||
member functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the context of a compatible extension or a compatible key, the expression
|
||||
"equivalent key" takes on its obvious interpretation.
|
||||
</p>
|
||||
|
||||
<code>template<typename CompatibleKey> iterator find(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
(<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
|
||||
<code>O(n)</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<<br>
|
||||
typename CompatibleKey,typename CompatibleHash, typename CompatiblePred<br>
|
||||
><br>
|
||||
iterator find(<br>
|
||||
const CompatibleKey& x,<br>
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const;
|
||||
</code>
|
||||
|
||||
<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>
|
||||
<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
|
||||
<code>O(n)</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
size_type count(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
(<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>
|
||||
</blockquote>
|
||||
|
||||
<code>template<<br>
|
||||
typename CompatibleKey,typename CompatibleHash, typename CompatiblePred<br>
|
||||
><br>
|
||||
size_type count(<br>
|
||||
const CompatibleKey& x,<br>
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const;
|
||||
</code>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
std::pair<iterator,iterator> equal_range(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
(<code>hasher</code>, <code>key_equal</code>).</br>
|
||||
<b>Effects:</b> Returns a range containing all elements with keys equivalent
|
||||
to <code>x</code> (and only those).<br>
|
||||
<b>Complexity:</b> Average case <code>O(count(x))</code>, worst case
|
||||
<code>O(n)</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<<br>
|
||||
typename CompatibleKey,typename CompatibleHash, typename CompatiblePred<br>
|
||||
><br>
|
||||
std::pair<iterator,iterator> equal_range(</br>
|
||||
const CompatibleKey& x,<br>
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const;
|
||||
</code>
|
||||
|
||||
<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>
|
||||
<b>Effects:</b> Returns a range containing all elements with keys equivalent
|
||||
to <code>x</code> (and only those).<br>
|
||||
<b>Complexity:</b> Average case <code>O(count(x,hash,eq))</code>, worst case
|
||||
<code>O(n)</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h4><a name="hash_policy">Hash policy</a></h4>
|
||||
|
||||
<code>void rehash(size_type n);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Increases if necessary the number of internal buckets
|
||||
so that <code>size()/bucket_count()</code> does not exceed the maximum
|
||||
load factor, and <code>bucket_count()>=n</code>.<br>
|
||||
<b>Postconditions:</b> Validity of iterators and references to the
|
||||
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.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="serialization">Serialization</a></h4>
|
||||
|
||||
<p>
|
||||
Indices cannot be serialized on their own, but only as part of the
|
||||
<code>multi_index_container</code> into which they are embedded. In describing
|
||||
the additional preconditions and guarantees associated to hashed indices
|
||||
with respect to serialization of their embedding containers, we
|
||||
use the concepts defined in the <code>multi_index_container</code>
|
||||
<a href="multi_index_container.html#serialization">serialization section</a>.
|
||||
</p>
|
||||
|
||||
Operation: saving of a <code>multi_index_container</code> <code>m</code> to an
|
||||
output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> No additional requirements to those imposed by the container.
|
||||
</blockquote>
|
||||
|
||||
Operation: loading of a <code>multi_index_container</code> <code>m'</code> from an
|
||||
input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> Additionally to the general requirements, <code>key_eq()</code>
|
||||
must be serialization-compatible with <code>m.get<i>().key_eq()</code>,
|
||||
where <code>i</code> is the position of the hashed index in the container.<br>
|
||||
<b>Postconditions:</b> On succesful loading, the range
|
||||
[<code>begin()</code>, <code>end()</code>) contains restored copies of every
|
||||
element in [<code>m.get<i>().begin()</code>, <code>m.get<i>().end()</code>),
|
||||
though not necessarily in the same order.
|
||||
</blockquote>
|
||||
|
||||
Operation: saving of an <code>iterator</code> or <code>const_iterator</code>
|
||||
<code>it</code> to an output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>it</code> is a valid iterator of the index. The associated
|
||||
<code>multi_index_container</code> has been previously saved.
|
||||
</blockquote>
|
||||
|
||||
Operation: loading of an <code>iterator</code> or <code>const_iterator</code>
|
||||
<code>it'</code> from an input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Postconditions:</b> On succesful loading, if <code>it</code> was dereferenceable
|
||||
then <code>*it'</code> is the restored copy of <code>*it</code>, otherwise
|
||||
<code>it'==end()</code>.<br>
|
||||
<b>Note:</b> It is allowed that <code>it</code> be a <code>const_iterator</code>
|
||||
and the restored <code>it'</code> an <code>iterator</code>, or viceversa.
|
||||
</blockquote>
|
||||
|
||||
Operation: saving of a <code>local_iterator</code> or
|
||||
<code>const_local_iterator</code>
|
||||
<code>it</code> to an output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>it</code> is a valid local iterator of the index. The
|
||||
associated <code>multi_index_container</code> has been previously saved.
|
||||
</blockquote>
|
||||
|
||||
Operation: loading of a <code>local_iterator</code> or
|
||||
<code>const_local_iterator</code>
|
||||
<code>it'</code> from an input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Postconditions:</b> On succesful loading, if <code>it</code> was dereferenceable
|
||||
then <code>*it'</code> is the restored copy of <code>*it</code>; if <code>it</code>
|
||||
was <code>m.get<i>().end(n)</code> for some <code>n</code>, then
|
||||
<code>it'==m'.get<i>().end(n)</code> (where <code>m</code> is the original
|
||||
<code>multi_index_container</code>, <code>m'</code> its restored copy
|
||||
and <code>i</code> is the ordinal of the index.)<br>
|
||||
<b>Note:</b> It is allowed that <code>it</code> be a <code>const_local_iterator</code>
|
||||
and the restored <code>it'</code> a <code>local_iterator</code>, or viceversa.
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="ord_indices.html"><img src="../prev.gif" alt="ordered indices" border="0"><br>
|
||||
Ordered indices
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="seq_indices.html"><img src="../next.gif" alt="sequenced indices" border="0"><br>
|
||||
Sequenced indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised August 24th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,126 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Reference</h1>
|
||||
|
||||
<div class="prev_link"><a href="../advanced_topics.html"><img src="../prev.gif" alt="advanced topics" border="0"><br>
|
||||
Advanced topics
|
||||
</a></div>
|
||||
<div class="up_link"><a href="../index.html"><img src="../up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="multi_index_container.html"><img src="../next.gif" alt="multi_index_container reference" border="0"><br>
|
||||
<code>multi_index_container</code> reference
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#header_dependencies">Header dependencies</a></li>
|
||||
<li><a href="multi_index_container.html">Class template <code>multi_index_container</code></a></li>
|
||||
<li><a href="indices.html">Index reference</a></li>
|
||||
<li><a href="ord_indices.html">Ordered indices</a></li>
|
||||
<li><a href="hash_indices.html">Hashed indices</a></li>
|
||||
<li><a href="seq_indices.html">Sequenced indices</a></li>
|
||||
<li><a href="key_extraction.html">Key Extraction</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="header_dependencies">Header dependencies</a></h2>
|
||||
|
||||
<p>
|
||||
The following dependencies among headers of Boost.MultiIndex hold:
|
||||
<ul>
|
||||
<li><a href="multi_index_container.html#synopsis"><code>"boost/multi_index_container.hpp"</code></a>
|
||||
includes
|
||||
<ul>
|
||||
<li><a href="indices.html#indexed_by_synopsis">
|
||||
<code>"boost/multi_index/indexed_by.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="ord_indices.html#synopsis">
|
||||
<code>"boost/multi_index/ordered_index.hpp"</code></a> includes
|
||||
<ul>
|
||||
<li><a href="indices.html#tag_synopsis">
|
||||
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="hash_indices.html#synopsis">
|
||||
<code>"boost/multi_index/hashed_index.hpp"</code></a> includes
|
||||
<ul>
|
||||
<li><a href="indices.html#tag_synopsis">
|
||||
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="seq_indices.html#synopsis">
|
||||
<code>"boost/multi_index/sequenced_index.hpp"</code></a> includes
|
||||
<ul>
|
||||
<li><a href="indices.html#tag_synopsis">
|
||||
<code>"boost/multi_index/tag.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="key_extraction.html#synopsis"><code>"boost/multi_index/key_extractors.hpp"</code></a>
|
||||
includes
|
||||
<ul>
|
||||
<li><a href="key_extraction.html#identity_synopsis">
|
||||
<code>"boost/multi_index/identity.hpp"</code></a>,</li>
|
||||
<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>
|
||||
<li><a href="key_extraction.html#composite_key_synopsis">
|
||||
<code>"boost/multi_index/composite_key.hpp"</code></a>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
So, a program using Boost.MultiIndex must include
|
||||
<a href="multi_index_container.html#synopsis">
|
||||
<code>"boost/multi_index_container.hpp"</code></a>,
|
||||
the headers defining the index types to be used and possibly one or more key
|
||||
extraction headers for key-based indices. Note that all the key extractors
|
||||
provided by Boost.MultiIndex are automatically included with
|
||||
<a href="key_extraction.html#synopsis">
|
||||
<code>"boost/multi_index/key_extractors.hpp"</code></a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In order to use the serialization capabilities of Boost.MultiIndex,
|
||||
the appropriate Boost.Serialization library module must be linked. Other
|
||||
than that, Boost.MultiIndex is a header-only library, requiring no additional
|
||||
object modules.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="../advanced_topics.html"><img src="../prev.gif" alt="advanced topics" border="0"><br>
|
||||
Advanced topics
|
||||
</a></div>
|
||||
<div class="up_link"><a href="../index.html"><img src="../up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="multi_index_container.html"><img src="../next.gif" alt="multi_index_container reference" border="0"><br>
|
||||
<code>multi_index_container</code> reference
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 30th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,335 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Index reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Index reference</h1>
|
||||
|
||||
<div class="prev_link"><a href="multi_index_container.html"><img src="../prev.gif" alt="multi_index_container reference" border="0"><br>
|
||||
<code>multi_index_container</code> reference
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="ord_indices.html"><img src="../next.gif" alt="ordered indices" border="0"><br>
|
||||
Ordered indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#index_concepts">Index concepts</a></li>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<li><a href="#index_specification">Index specification</a></li>
|
||||
<li><a href="#indexed_by_synopsis">Header
|
||||
<code>"boost/multi_index/indexed_by.hpp"</code> synopsis</a>
|
||||
<ul>
|
||||
<li><a href="#indexed_by">Class template <code>indexed_by</code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#tags">Tags</a></li>
|
||||
<li><a href="#tag_synopsis">Header
|
||||
<code>"boost/multi_index/tag.hpp"</code> synopsis</a>
|
||||
<ul>
|
||||
<li><a href="#tag">Class template <code>tag</code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#index_catalog">Indices provided by Boost.MultiIndex</a>
|
||||
<ul>
|
||||
<li><a href="#key_based_indices">Key-based indices</a></li>
|
||||
<li><a href="#other_indices">Other types</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="index_concepts">Index concepts</a></h2>
|
||||
|
||||
<p>
|
||||
<code>multi_index_container</code> instantiations comprise one or more indices
|
||||
specified at compile time. Each index allows read/write access to the elements
|
||||
contained in a definite manner. For instance,
|
||||
<a href="ord_indices.html">ordered indices</a>
|
||||
provide a set-like interface to the elements, whereas
|
||||
<a href="seq_indices.html">sequenced indices</a> mimic the functionality
|
||||
of <code>std::list</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Indices are not isolated objects, and so cannot be constructed on their
|
||||
own. Rather they are embedded into a <code>multi_index_container</code> as specified by
|
||||
means of an <a href="#index_specification">index specifier</a>. The name of
|
||||
the index class implementation proper is never directly exposed to the user, who
|
||||
has only access to the associated index specifier.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Insertion and erasing of elements are always performed through the
|
||||
appropriate interface of some index of the <code>multi_index_container</code>;
|
||||
these operations, however, do have an impact on all other indices as
|
||||
well: for instance, insertion through a given index may fail because
|
||||
there exists another index which bans the operation in order to preserve
|
||||
its invariant (like uniqueness of elements.) This circumstance, rather
|
||||
than an obstacle, yields much of the power of Boost.MultiIndex:
|
||||
equivalent constructions based on manual composition of standard
|
||||
containers would have to add a fair amount of code in order to
|
||||
globally preserve the invariants of each container while guaranteeing
|
||||
that all of them are synchronized. The global operations performed
|
||||
in a joint manner among the various indices can be reduced to
|
||||
six primitives:
|
||||
<ul>
|
||||
<li>Copying,</li>
|
||||
<li>insertion of an element,</li>
|
||||
<li>hinted insertion, where a preexisting element is suggested in
|
||||
order to improve the efficiency of the operation,</li>
|
||||
<li>deletion of an element,</li>
|
||||
<li>replacement of the value of an element,
|
||||
which may trigger the rearrangement of this element in one or
|
||||
more indices, or the banning of the replacement,</li>
|
||||
<li>modification of an element, and its subsequent
|
||||
rearrangement/banning by the various indices.
|
||||
</ul>
|
||||
The last two primitives deserve some further explanation: in order to
|
||||
guarantee the invariants associated to each index (e.g. some definite
|
||||
ordering,) elements of a <code>multi_index_container</code> are not mutable.
|
||||
To overcome this restriction, indices expose member functions
|
||||
for updating and modifying, which allow for the mutation of elements
|
||||
in a controlled fashion. Immutability of elements does not significantly
|
||||
impact the interface of ordered indices, as it is based upon that of
|
||||
<code>std::set</code> and <code>std:multiset</code>, and these containers
|
||||
also have non-mutable elements; but it may come as a surprise when dealing
|
||||
with sequenced indices, which are designed upon the functionality provided
|
||||
by <code>std::list</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These global operations are not directly exposed to the user, but rather
|
||||
they are wrapped as appropriate by each index (for instance, ordered indices
|
||||
provide a set-like suite of insertion member functions, whereas sequenced
|
||||
indices do have <code>push_back</code> and <code>push_front</code>
|
||||
operations.) Boost.MultiIndex poses no particular conditions on
|
||||
the interface of indices, save that they must model
|
||||
<a href="http://www.sgi.com/tech/stl/Container.html">
|
||||
<code>Container</code></a> (without the requirement of being
|
||||
<a href="http://www.sgi.com/tech/stl/Assignable.html">
|
||||
<code>Assignable</code></a>.)
|
||||
</p>
|
||||
|
||||
<h2><a name="complexity_signature">Complexity signature</a></h2>
|
||||
|
||||
<p>
|
||||
Some member functions of an index interface are implemented by
|
||||
global primitives from the list above. Complexity of these operations
|
||||
thus depends on all indices of a given <code>multi_index_container</code>, not just
|
||||
the currently used index.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In order to establish complexity estimates, an index is characterized
|
||||
by its <i>complexity signature</i>, consisting of the following
|
||||
associated functions on the number of elements:
|
||||
<ul>
|
||||
<li><code>c(n)</code>: copying,
|
||||
<li><code>i(n)</code>: insertion,
|
||||
<li><code>h(n)</code>: hinted insertion,
|
||||
<li><code>d(n)</code>: deletion,
|
||||
<li><code>r(n)</code>: replacement,
|
||||
<li><code>m(n)</code>: modifying.
|
||||
</ul>
|
||||
|
||||
</p>
|
||||
Each function yields the complexity estimate of the contribution of the index
|
||||
to the corresponding global primitive. Let us consider
|
||||
an instantiation of <code>multi_index_container</code>
|
||||
with <code>N</code> indices labelled <code>0</code>,...,<code>N-1</code>
|
||||
whose complexity signatures are
|
||||
(<code>c<sub>i</sub></code>,<code>i<sub>i</sub></code>,<code>h<sub>i</sub></code>,<code>d<sub>i</sub></code>,<code>r<sub>i</sub></code>,<code>m<sub>i</sub></code>);
|
||||
the insertion of an element in such a container is then of complexity
|
||||
<code>O(i<sub>0</sub>(n)+···+i<sub>N-1</sub>(n))</code> where <code>n</code>
|
||||
is the number of elements. To abbreviate notation, we adopt the
|
||||
following definitions:
|
||||
<ul>
|
||||
<li><code>C(n)=c<sub>0</sub>(n)+···+c<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>I(n)=i<sub>0</sub>(n)+···+i<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>H(n)=h<sub>0</sub>(n)+···+h<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>D(n)=d<sub>0</sub>(n)+···+d<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>R(n)=r<sub>0</sub>(n)+···+r<sub>N-1</sub>(n)</code>,</li>
|
||||
<li><code>M(n)=m<sub>0</sub>(n)+···+m<sub>N-1</sub>(n)</code>.</li>
|
||||
</ul>
|
||||
For instance, consider a <code>multi_index_container</code> with two ordered indices,
|
||||
for which <code>i(n)=log(n)</code>, and a sequenced index with <code>i(n)=1</code>
|
||||
(constant time insertion). Insertion of an element into this <code>multi_index_container</code>
|
||||
is then of complexity
|
||||
<blockquote>
|
||||
<code>O(I(n))=O(2*log(n)+1)=O(log(n))</code>.
|
||||
</blockquote>
|
||||
</p>
|
||||
|
||||
<h2><a name="index_specification">Index specification</a></h2>
|
||||
|
||||
<p>
|
||||
Index specifiers are passed as instantiation arguments to
|
||||
<code>multi_index_container</code> and provide the information needed to incorporate
|
||||
the corresponding indices. Future releases of Boost.MultiIndex may allow for
|
||||
specification of user-defined indices. Meanwhile, the requirements for an index
|
||||
specifier remain implementation defined. Currently, Boost.MultiIndex provides the
|
||||
index specifiers
|
||||
<ul>
|
||||
<li><a href="ord_indices.html#unique_non_unique"><code>ordered_unique</code> and
|
||||
<code>ordered_non_unique</code></a> for
|
||||
<a href="ord_indices.html">ordered indices</a>,</li>
|
||||
<li><a href="hash_indices.html#unique_non_unique"><code>hashed_unique</code> and
|
||||
<code>hashed_non_unique</code></a> for
|
||||
<a href="hash_indices.html">hashed indices</a>,</li>
|
||||
<li>and <a href="seq_indices.html#sequenced"><code>sequenced</code></a> for
|
||||
<a href="seq_indices.html">sequenced indices</a>.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="indexed_by_synopsis">Header
|
||||
<a href="../../../../boost/multi_index/indexed_by.hpp">
|
||||
<code>"boost/multi_index/indexed_by.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>indexed_by</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="indexed_by">Class template <code>indexed_by</code></a></h3>
|
||||
|
||||
<p>
|
||||
<code>indexed_by</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> meant to be used to specify a
|
||||
compile-time list of indices as the <code>IndexSpecifierList</code> of
|
||||
<code>multi_index_container</code>.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>indexed_by</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Each user-provided element of <code>indexed_list</code> must be an index
|
||||
specifier. At least an element must be provided. The maximum number of elements
|
||||
of an <code>indexed_by</code> sequence is implementation defined.
|
||||
</p>
|
||||
|
||||
<h2><a name="tags">Tags</a></h2>
|
||||
|
||||
<p>
|
||||
Tags are just conventional types used as mnemonics for indices of an
|
||||
<code>multi_index_container</code>, as for instance in member function <code>get</code>.
|
||||
Each index can have none, one or more tags associated. The way tags are assigned
|
||||
to a given index is dependent on the particular index specifier. However,
|
||||
for convenience all indices of Boost.MultiIndex support tagging through the
|
||||
class template <a href="#tag"><code>tag</code></a>.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="tag_synopsis">Header
|
||||
<a href="../../../../boost/multi_index/tag.hpp">
|
||||
<code>"boost/multi_index/tag.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>tag</span><span class=special>;</span>
|
||||
|
||||
<span class=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="tag">Class template <code>tag</code></a></h3>
|
||||
|
||||
<p>
|
||||
<code>tag</code> is a typelist construct used to specify a compile-time
|
||||
sequence of tags to be assigned to an index in instantiation time.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>T0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Tn</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>tag</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h2><a name="index_catalog">Indices provided by Boost.MultiIndex</a></h2>
|
||||
|
||||
|
||||
<h3><a name="key_based_indices">Key-based indices</a></h3>
|
||||
|
||||
<p>
|
||||
Indices of this type are organized around <i>keys</i> obtained from the
|
||||
elements, as described in the <a href="key_extraction.html">key extraction
|
||||
reference</a>.
|
||||
<ul>
|
||||
<li><a href="ord_indices.html">Ordered indices</a> sort the elements
|
||||
on the key and provide fast lookup capabilites.</li>
|
||||
<li><a href="hash_indices.html">Hashed indices</a> offer high
|
||||
efficiency access through hashing techniques.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h3><a name="other_indices">Other types</a></h3>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li><a href="seq_indices.html">Sequenced indices</a> allow to arrange
|
||||
elements as in a bidirectional list. </li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="multi_index_container.html"><img src="../prev.gif" alt="multi_index_container reference" border="0"><br>
|
||||
<code>multi_index_container</code> reference
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="ord_indices.html"><img src="../next.gif" alt="ordered indices" border="0"><br>
|
||||
Ordered indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 30th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,891 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - multi_index_container reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex
|
||||
<code>multi_index_container</code> reference</h1>
|
||||
|
||||
<div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="indices.html"><img src="../next.gif" alt="index reference" border="0"><br>
|
||||
Index reference
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#multi_index_container_fwd_synopsis">Header
|
||||
<code>"boost/multi_index_container_fwd.hpp"</code> synopsis</a></li>
|
||||
<li><a href="#synopsis">Header
|
||||
<code>"boost/multi_index_container.hpp"</code> synopsis</a>
|
||||
<ul>
|
||||
<li><a href="#multi_index_container">Class template <code>multi_index_container</code></a>
|
||||
<ul>
|
||||
<li><a href="#complexity">Complexity</a></li>
|
||||
<li><a href="#instantiation_types">Instantiation types</a></li>
|
||||
<li><a href="#types">Nested types</a></li>
|
||||
<li><a href="#nested_templates">Nested class templates</a></li>
|
||||
<li><a href="#constructors">Constructors, copy and assignment</a></li>
|
||||
<li><a href="#index_retrieval">Index retrieval operations</a></li>
|
||||
<li><a href="#projection">Projection operations</a></li>
|
||||
<li><a href="#serialization">Serialization</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a name="multi_index_container_fwd_synopsis">Header
|
||||
<a href="../../../../boost/multi_index_container_fwd.hpp"><code>"boost/multi_index_container_fwd.hpp"</code></a>
|
||||
synopsis</a>
|
||||
</h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</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=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>Value</span><span class=special>></span> <span class=special>></span> <span class=special>>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span><span class=identifier>Value</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=keyword>class</span> <span class=identifier>multi_index_container</span><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=keyword>using</span> <span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>multi_index_container_fwd.hpp</code> forward declares the class template
|
||||
<a href="#multi_index_container"><code>multi_index_container</code></a> and specifies its default parameters.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="synopsis">Header
|
||||
<a href="../../../../boost/multi_index_container.hpp"><code>"boost/multi_index_container.hpp"</code></a>
|
||||
synopsis</a>
|
||||
</h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>></span>
|
||||
<span class=keyword>class</span> <span class=identifier>multi_index_container</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// multi_index_container associated global class templates:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// multi_index_container global functions for index retrieval:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// multi_index_container global functions for projection of iterators:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// comparison:</span>
|
||||
|
||||
<span class=comment>// <b>OP</b> is any of ==,<,!=,>,>=,<=</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator1</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value2</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList2</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator2</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value1</span><span class=special>,</span><span class=identifier>IndexSpecifierList1</span><span class=special>,</span><span class=identifier>Allocator1</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value2</span><span class=special>,</span><span class=identifier>IndexSpecifierList2</span><span class=special>,</span><span class=identifier>Allocator2</span><span class=special>>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=keyword>using</span> <span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special>;</span>
|
||||
<span class=keyword>using</span> <span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>get</span><span class=special>;</span>
|
||||
<span class=keyword>using</span> <span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>project</span><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="multi_index_container">
|
||||
Class template <code>multi_index_container</code>
|
||||
</a></h3>
|
||||
|
||||
<p>
|
||||
This is the main component of Boost.MultiIndex. A <code>multi_index_container</code>
|
||||
is a container class template holding a compile-time user-defined list of
|
||||
<a href="indices.html">indices</a>. These indices provide different interfaces
|
||||
for the management of the elements of the <code>multi_index_container</code>. By itself,
|
||||
<code>multi_index_container</code> only provides basic functionality for construction
|
||||
and for access to the indices held.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A <code>multi_index_container</code> type is instantiated with the type of the
|
||||
elements contained and a non-empty
|
||||
<a href="../../../../libs/mpl/doc/refmanual/forward-sequence.html">
|
||||
<code>MPL Forward Sequence</code></a> specifying which indices conform the
|
||||
class.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For convenience of use, all public methods and types of the first index
|
||||
specified are inherited by <code>multi_index_container</code>. This also includes global
|
||||
operators and functions associated with the index (vg. comparison and
|
||||
<code>swap</code>.)
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</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=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>Value</span><span class=special>></span> <span class=special>></span> <span class=special>>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span><span class=identifier>Value</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=keyword>class</span> <span class=identifier>multi_index_container</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>public</span><span class=special>:</span>
|
||||
|
||||
<span class=comment>// types:</span>
|
||||
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>ctor_args_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>index_specifier_type_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>index_type_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>iterator_type_list</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>const_iterator_type_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=comment>// nested class templates:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>index_const_iterator</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
|
||||
|
||||
<span class=comment>// construct/copy/destroy:</span>
|
||||
|
||||
<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(
|
||||
</span><span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
|
||||
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
|
||||
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=special>~</span><span class=identifier>multi_index_container</span><span class=special>();</span>
|
||||
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=keyword>operator</span><span class=special>=(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// retrieval of indices</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>();</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span><span class=special>&</span> <span class=identifier>get</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// projection of iterators</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>project</span><span class=special>(</span><span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=comment>// multi_index_container associated global class templates:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index</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</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index</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</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>nth_index_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>nth_index_const_iterator</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>nth_index_const_iterator</span><span class=special><</span><span class=identifier>N</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_iterator</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>></span> <span class=keyword>struct</span> <span class=identifier>index_const_iterator</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>MultiIndexContainer</span><span class=special>::</span><span class=identifier>index_const_iterator</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>::</span><span class=identifier>type</span> <span class=identifier>type</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=comment>// multi_index_container global functions for index retrieval:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=identifier>N</span><span class=special>>();</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>nth_index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=identifier>N</span><span class=special>>();</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>();</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>const</span> <span class=keyword>typename</span> <span class=identifier>index</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span><span class=special>&</span>
|
||||
<span class=identifier>get</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>();</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// multi_index_container global functions for projection of iterators:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_iterator</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>int</span> <span class=identifier>N</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>nth_index_const_iterator</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>N</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>N</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_iterator</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IteratorType</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>typename</span> <span class=identifier>index_const_iterator</span><span class=special><</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>,</span><span class=identifier>Tag</span>
|
||||
<span class=special>>::</span><span class=identifier>type</span>
|
||||
<span class=identifier>project</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>m</span><span class=special>,</span>
|
||||
<span class=identifier>IteratorType</span> <span class=identifier>it</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>m</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=identifier>Tag</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// comparison:</span>
|
||||
|
||||
<span class=comment>// <b>OP</b> is any of ==,<,!=,>,>=,<=</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator1</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Value2</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList2</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator2</span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value1</span><span class=special>,</span><span class=identifier>IndexSpecifierList1</span><span class=special>,</span><span class=identifier>Allocator1</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value2</span><span class=special>,</span><span class=identifier>IndexSpecifierList2</span><span class=special>,</span><span class=identifier>Allocator2</span><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>get</span><span class=special><</span><span class=number>0</span><span class=special>>(</span><span class=identifier>x</span><span class=special>)</span> <b><i>OP</i></b> <span class=identifier>get</span><span class=special><</span><span class=number>0</span><span class=special>>(</span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=identifier>x</span><span class=special>.</span><span class=identifier>swap</span><span class=special>(</span><span class=identifier>y</span><span class=special>);</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>
|
||||
|
||||
<h4><a name="complexity">Complexity</a></h4>
|
||||
|
||||
<p>
|
||||
In the descriptions of operations of <code>multi_index_container</code>, we adopt the
|
||||
scheme outlined in the
|
||||
<a href="indices.html#complexity_signature">complexity signature section</a>.
|
||||
</p>
|
||||
|
||||
<h4><a name="instantiation_types">Instantiation types</a></h4>
|
||||
|
||||
<p>
|
||||
<code>multi_index_container</code> is instantiated with the following types:
|
||||
<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>
|
||||
<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">
|
||||
<code>MPL Forward Sequence</code></a> (and, preferrably,
|
||||
an <a href="../../../../libs/mpl/doc/refmanual/random-access-sequence.html">
|
||||
<code>MPL Random Access Sequence</code></a>) of index specifiers. For
|
||||
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>.
|
||||
</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
|
||||
index or in two different indices.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>ctor_args_list</code>
|
||||
|
||||
<blockquote>
|
||||
Although the exact definition of <code>ctor_args_list</code> is
|
||||
implementation defined, from the user point of view this type can be
|
||||
treated as equivalent to
|
||||
<code>::boost::tuple<C<sub>0</sub>,...,C<sub>I-1</sub>></code>,
|
||||
where <code>C<sub>i</sub></code> is the <code>ctor_args</code> type of the
|
||||
<code>i</code>-th index held by the <code>multi_index_container</code>, in the
|
||||
same order as they were specified. Strictly speaking, there is an
|
||||
implicit conversion from
|
||||
<code>const ::boost::tuple<C<sub>0</sub>,...,C<sub>I-1</sub>>&</code>
|
||||
to <code>const ctor_args_list&</code>. This type is used for
|
||||
providing the construction arguments of the indices of the
|
||||
<code>multi_index_container</code>. <code>ctor_args_list</code> is
|
||||
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"><code>Default
|
||||
Constructible</code></a>, provided that all <code>ctor_args</code> types
|
||||
involved are default constructible.
|
||||
</blockquote>
|
||||
|
||||
<code>index_specifier_type_list</code>
|
||||
|
||||
<blockquote>
|
||||
Same type as <code>IndexSpecifierList</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>index_type_list</code>
|
||||
|
||||
<blockquote>
|
||||
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 of the indices held by
|
||||
the <code>multi_index_container</code>, in the same order as they were specified.
|
||||
</blockquote>
|
||||
|
||||
<code>iterator_type_list</code>
|
||||
|
||||
<blockquote>
|
||||
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 of the iterators of
|
||||
the indices held by the <code>multi_index_container</code>, in the same order as they were
|
||||
specified.
|
||||
</blockquote>
|
||||
|
||||
<code>const_iterator_type_list</code>
|
||||
|
||||
<blockquote>
|
||||
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 of the constant
|
||||
iterators of the indices held by the <code>multi_index_container</code>, in the same order
|
||||
as they were specified.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="nested_templates">Nested class templates</a></h4>
|
||||
|
||||
<code>template<int N> struct nth_index</code>
|
||||
|
||||
<blockquote>
|
||||
<code>nth_index<N>::type</code> yields the type of the
|
||||
<code>N</code>-th (0-based) index held by the <code>multi_index_container</code>, in
|
||||
the same order as they were specified.<br>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> struct index</code>
|
||||
|
||||
<blockquote>
|
||||
<code>index<Tag>::type</code> yields the type of the index which
|
||||
has <code>Tag</code> as an associated <a href="indices.html#tags">tag type</a>.</br>
|
||||
<b>Requires:</b> Some index of the <code>multi_index_container</code> has <code>Tag</code>
|
||||
as an associated tag type.
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N> struct nth_index_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
<code>nth_index_iterator<N>::type</code> is equivalent to
|
||||
<code>nth_index<N>::type::iterator</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N> struct nth_index_const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
<code>nth_index_const_iterator<N>::type</code> is equivalent to
|
||||
<code>nth_index<N>::type::const_iterator</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> struct index_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
<code>index_iterator<Tag>::type</code> is equivalent to
|
||||
<code>index<Tag>::type::iterator</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> struct index_const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
<code>index_const_iterator<Tag>::type</code> is equivalent to
|
||||
<code>index<Tag>::type::const_iterator</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<code>explicit multi_index_container(<br>
|
||||
const ctor_args_list& comp=ctor_args_list(),<br>
|
||||
const allocator_type& al=allocator_type());</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Constructs an empty <code>multi_index_container</code> using the
|
||||
specified argument list and allocator.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename InputIterator><br>
|
||||
multi_index_container(<br>
|
||||
InputIterator first,InputIterator last,<br>
|
||||
const ctor_args_list& comp=ctor_args_list(),<br>
|
||||
const allocator_type& al=allocator_type());</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>Value</code> or a type convertible to <code>Value</code>.
|
||||
<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>).
|
||||
Insertion of each element may or may not succeed depending
|
||||
on the acceptance by all the indices of the <code>multi_index_container</code>.<br>
|
||||
<b>Complexity:</b> <code>O(m*H(m))</code>, where <code>m</code> is
|
||||
the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
</blockquote>
|
||||
|
||||
<code>multi_index_container(<br>
|
||||
const multi_index_container<Value,IndexSpecifierList,Allocator>& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Constructs a copy of <code>x</code>, copying its
|
||||
elements as well as its internal objects (key extractors, comparison objects,
|
||||
allocator.)<br>
|
||||
<b>Postconditions:</b> <code>*this==x</code>. The order on every index
|
||||
of the <code>multi_index_container</code> is preserved as well.<br>
|
||||
<b>Complexity:</b> <code>O(x.size()*log(x.size()) + C(x.size()))</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>~multi_index_container()</code>
|
||||
<blockquote>
|
||||
<b>Effects:</b> Destroys the <code>multi_index_container</code> and all the elements
|
||||
contained. The order in which the elements are destroyed is not specified.<br>
|
||||
<b>Complexity:</b> <code>O(n)</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(<br>
|
||||
const multi_index_container<Value,IndexSpecifierList,Allocator>& x);</code>
|
||||
|
||||
<blockquote>
|
||||
Replaces the elements and internal objects of the <code>multi_index_container</code>
|
||||
with copies from <code>x</code>.<br>
|
||||
<b>Postconditions:</b> <code>*this==x</code>. The order on every index
|
||||
of the <code>multi_index_container</code> is preserved as well.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
<b>Complexity:</b> <code>O(n + x.size()*log(x.size()) +
|
||||
C(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> Strong, provided the copy and assignment operations
|
||||
of the types of <code>ctor_args_list</code> do not throw.
|
||||
</blockquote>
|
||||
|
||||
<code>allocator_type get_allocator()const;</code>
|
||||
|
||||
<blockquote>
|
||||
Returns a copy of the <code>allocator_type</code> object used to construct
|
||||
the <code>multi_index_container</code>.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="index_retrieval">Index retrieval operations</a></h4>
|
||||
|
||||
<code>template<int N> typename nth_index<N>::type& get();</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>.<br>
|
||||
<b>Effects:</b> Returns a reference to the
|
||||
<code>nth_index<N>::type</code> index held by <code>*this</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N> const typename nth_index<N>::type& get()const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>.<br>
|
||||
<b>Effects:</b> Returns a <code>const</code> reference to the
|
||||
<code>nth_index<N>::type</code> index held by <code>*this</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> typename index<Tag>::type& get()</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that <code>index<Tag>::type</code>
|
||||
is valid.<br>
|
||||
<b>Effects:</b> Returns a reference to the
|
||||
<code>index<Tag>::type</code> index held by
|
||||
<code>*this</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag> const typename index<Tag>::type& get()const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that <code>index<Tag>::type</code>
|
||||
is valid.<br>
|
||||
<b>Effects:</b> Returns a <code>const</code> reference to the
|
||||
<code>index<Tag>::type</code> index held by
|
||||
<code>*this</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="projection">Projection operations</a></h4>
|
||||
|
||||
<p>
|
||||
Given a <code>multi_index_container</code> with indices <code>i1</code>
|
||||
and <code>i2</code>, we say than an <code>i1</code>-iterator
|
||||
<code>it1</code> and an <code>i2</code>-iterator <code>it2</code>
|
||||
are <i>equivalent</i> if:
|
||||
<ul>
|
||||
<li> <code>it1==i1.end()</code> AND <code>it2==i2.end()</code>,</li>
|
||||
<li> OR <code>it1</code> and <code>it2</code> point to the
|
||||
same element.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<code>template<int N,typename IteratorType><br>
|
||||
typename nth_index_iterator<N>::type project(IteratorType it);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>. <code>IteratorType</code>
|
||||
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
iterator of some index of <code>*this</code> (i.e. does not refer to some
|
||||
other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>nth_index_iterator<N>::type</code> iterator
|
||||
equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<int N,typename IteratorType><br>
|
||||
typename nth_index_const_iterator<N>::type project(IteratorType it)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>0 <= N < I</code>. <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>nth_index_const_iterator<N>::type</code>
|
||||
iterator equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag,typename IteratorType><br>
|
||||
typename index_iterator<Tag>::type project(IteratorType it);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that
|
||||
<code>index_iterator<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
belongs to <code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
iterator of some index of <code>*this</code> (i.e. does not refer to some
|
||||
other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>index_iterator<Tag>::type</code> iterator
|
||||
equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Tag,typename IteratorType><br>
|
||||
typename index_const_iterator<Tag>::type project(IteratorType it)const;</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Tag</code> is such that
|
||||
<code>index_const_iterator<Tag>::type</code> is valid. <code>IteratorType</code>
|
||||
belongs to <code>const_iterator_type_list</code> or
|
||||
<code>iterator_type_list</code>. <code>it</code> is a valid
|
||||
(constant or non-constant) iterator of some index of <code>*this</code>
|
||||
(i.e. does not refer to some other <code>multi_index_container</code>.)<br>
|
||||
<b>Effects:</b> Returns an <code>index_const_iterator<Tag>::type</code>
|
||||
iterator equivalent to <code>it</code>.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="serialization">Serialization</a></h4>
|
||||
|
||||
<p>
|
||||
<code>multi_index_container</code>s can be archived/retrieved by means of
|
||||
<a href="../../../serialization/index.html">Boost.Serialization</a>.
|
||||
Boost.MultiIndex does not expose a public serialization interface, as this
|
||||
is provided by Boost.Serialization itself. Both regular and XML
|
||||
archives are supported.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Each of the indices comprising a given <code>multi_index_container</code> contributes
|
||||
its own preconditions as well as guarantees on the retrieved containers. In describing
|
||||
these, the following concepts are used. A type <code>T</code> is <i>serializable</i>
|
||||
(resp. XML-serializable) if any object of type <code>T</code> can be saved to an output
|
||||
archive (XML archive) and later retrieved from an input archive (XML archive) associated to
|
||||
the same storage. If <code>x'</code> of type <code>T</code> is loaded from the
|
||||
serialization information saved from another object <code>x</code>, we say that
|
||||
<code>x'</code> is a <i>restored copy</i> of <code>x</code>. Given a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html"><code>Binary Predicate</code></a>
|
||||
<code>Pred</code> over (<code>T</code>, <code>T</code>), and objects <code>p</code>
|
||||
and <code>q</code> of type <code>Pred</code>, we say that <code>q</code>
|
||||
is <i>serialization-compatible</i> with <code>p</code> if
|
||||
<blockquote>
|
||||
<code>p(x,y) == q(x',y')</code>
|
||||
</blockquote>
|
||||
for every <code>x</code> and <code>y</code> of type <code>T</code> and <code>x'</code> and
|
||||
<code>y'</code> being restored copies of <code>x</code> and <code>y</code>,
|
||||
respectively.
|
||||
</p>
|
||||
|
||||
Operation: saving of a <code>multi_index_container</code> <code>m</code> to an
|
||||
output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Value</code> is serializable (XML-serializable). Additionally,
|
||||
each of the indices of <code>m</code> can impose another requirements.<br>
|
||||
<b>Exception safety:</b> Strong with respect to <code>m</code>. If an exception
|
||||
is thrown, <code>ar</code> may be left in an inconsistent state.
|
||||
</blockquote>
|
||||
|
||||
Operation: loading of a <code>multi_index_container</code> <code>m'</code> from an
|
||||
input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Value</code> is serializable (XML-serializable). Additionally,
|
||||
each of the indices of <code>m'</code> can impose another requirements.<br>
|
||||
<b>Exception safety:</b> Basic. If an exception is thrown, <code>ar</code> may be
|
||||
left in an inconsistent state.
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="indices.html"><img src="../next.gif" alt="index reference" border="0"><br>
|
||||
Index reference
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 30th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,963 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Ordered indices reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Ordered indices reference</h1>
|
||||
|
||||
<div class="prev_link"><a href="indices.html"><img src="../prev.gif" alt="index reference" border="0"><br>
|
||||
Index reference
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
|
||||
Hashed indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#ord_index_fwd_synopsis">Header
|
||||
<code>"boost/multi_index/ordered_index_fwd.hpp"</code> synopsis</a></li>
|
||||
<li><a href="#synopsis">Header
|
||||
<code>"boost/multi_index/ordered_index.hpp"</code> synopsis</a>
|
||||
<ul>
|
||||
<li><a href="#unique_non_unique">
|
||||
Index specifiers <code>ordered_unique</code> and <code>ordered_non_unique</code>
|
||||
</a></li>
|
||||
<li><a href="#ord_indices">Ordered indices</a>
|
||||
<ul>
|
||||
<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="#modifiers">Modifiers</a></li>
|
||||
<li><a href="#observers">Observers</a></li>
|
||||
<li><a href="#set_operations">Set operations</a></li>
|
||||
<li><a href="#range_operations">Range operations</a></li>
|
||||
<li><a href="#serialization">Serialization</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a name="ord_index_fwd_synopsis">Header
|
||||
<a href="../../../../boost/multi_index/ordered_index_fwd.hpp">
|
||||
<code>"boost/multi_index/ordered_index_fwd.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=comment>// index specifiers ordered_unique and ordered_non_unique</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult ordered_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ordered_unique</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult ordered_non_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ordered_non_unique</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// indices</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span> <span class=keyword>class</span> <b>index name is implementation defined</b><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>ordered_index_fwd.hpp</code> provides forward declarations for index specifiers
|
||||
<a href="#unique_non_unique"><code>ordered_unique</code> and <code>ordered_non_unique</code></a> and
|
||||
their associated <a href="#ord_indices">ordered index</a> classes.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="synopsis">Header
|
||||
<a href="../../../../boost/multi_index/ordered_index.hpp">
|
||||
<code>"boost/multi_index/ordered_index.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=comment>// index specifiers ordered_unique and ordered_non_unique</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult ordered_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ordered_unique</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><b>consult ordered_non_unique reference for arguments</b><span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=identifier>ordered_non_unique</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// indices</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span> <span class=keyword>class</span> <b>index class name implementation defined</b><span class=special>;</span>
|
||||
|
||||
<span class=comment>// index comparison:</span>
|
||||
|
||||
<span class=comment>// <b>OP</b> is any of ==,<,!=,>,>=,<=</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// index specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="unique_non_unique">
|
||||
Index specifiers <code>ordered_unique</code> and <code>ordered_non_unique</code>
|
||||
</a></h3>
|
||||
|
||||
<p>
|
||||
These <a href="indices.html#index_specification">index specifiers</a> allow
|
||||
for insertion of <a href="#ord_indices">ordered indices</a> without and with
|
||||
allowance of duplicate elements, respectively. The syntax of <code>ordered_unique</code>
|
||||
and <code>ordered_non_unique</code> coincide, thus we describe them in a grouped manner.
|
||||
<code>ordered_unique</code> and <code>ordered_non_unique</code> can be instantiated in
|
||||
two different forms, according to whether a tag list for the index is provided or not:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>ordered_unique</span> <span class=special>|</span> <span class=identifier>ordered_non_unique</span><span class=special>)</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>TagList</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=keyword>struct</span> <span class=special>(</span><span class=identifier>ordered_unique</span> <span class=special>|</span> <span class=identifier>ordered_non_unique</span><span class=special>)</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
If provided, <code>TagList</code> must be an instantiation of the class template
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
The template arguments are used by the corresponding index implementation,
|
||||
refer to the <a href="#ord_indices">ordered indices</a> reference section for further
|
||||
explanations on their acceptable type values.
|
||||
</p>
|
||||
|
||||
<h3><a name="ord_indices">Ordered indices</a></h3>
|
||||
|
||||
<p>
|
||||
An ordered index provides a set-like interface to the underlying heap of
|
||||
elements contained in a <code>multi_index_container</code>. An ordered index is
|
||||
particularized according to a given
|
||||
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
|
||||
that retrieves keys from elements of <code>multi_index_container</code> and a comparison
|
||||
predicate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are two variants of ordered indices: <i>unique</i>, which do
|
||||
not allow duplicate elements (with respect to its associated comparison
|
||||
predicate) and <i>non-unique</i>, which accept those duplicates.
|
||||
The interface of these two variants is the same, so they are documented
|
||||
together, with minor differences explicitly stated when they exist.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Except where noted, ordered indices (both unique and non-unique) are models of
|
||||
<a href="http://www.sgi.com/tech/stl/SortedAssociativeContainer.html">
|
||||
<code>Sorted Associative Container</code></a> and
|
||||
<a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html">
|
||||
<code>Unique Associative Container</code></a>, much as <code>std::set</code>s
|
||||
are. Accordingly, validity of iterators and references to elements is
|
||||
preserved. We only provide descriptions of those types and operations that are
|
||||
either not present in the concepts modeled or do not exactly conform to the
|
||||
requirements for these types of containers.
|
||||
</p>
|
||||
|
||||
<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>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>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined: dependent on types Value, Allocator,
|
||||
TagList, KeyFromValue, Compare</b><span class=special>></span>
|
||||
<span class=keyword>class</span> <b>name is implementation defined</b>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>public</span><span class=special>:</span>
|
||||
<span class=comment>// types:</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>::</span><span class=identifier>result_type</span> <span class=identifier>key_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>KeyFromValue</span> <span class=identifier>key_from_value</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Compare</span> <span class=identifier>key_compare</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>value_compare</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>tuple</span><span class=special><</span><span class=identifier>key_from_value</span><span class=special>,</span><span class=identifier>key_compare</span><span class=special>></span> <span class=identifier>ctor_args</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>reference</span> <span class=identifier>reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_reference</span> <span class=identifier>const_reference</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>const_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>size_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>implementation defined </b><span class=identifier>difference_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>pointer</span> <span class=identifier>pointer</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=identifier>const_pointer</span> <span class=identifier>const_pointer</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<iterator></b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<const_iterator></b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// construct/copy/destroy:</span>
|
||||
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// iterators:</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>();</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span><span class=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>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>();</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span><span class=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=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>
|
||||
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// modifiers:</span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>erase</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>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>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
|
||||
|
||||
<span class=comment>// observers:</span>
|
||||
|
||||
<span class=identifier>key_from_value</span> <span class=identifier>key_extractor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>key_compare</span> <span class=identifier>key_comp</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>value_compare</span> <span class=identifier>value_comp</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// set operations:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>find</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>find</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>count</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>lower_bound</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>lower_bound</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>upper_bound</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>upper_bound</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>></span> <span class=identifier>equal_range</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>CompatibleKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompatibleCompare</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>></span> <span class=identifier>equal_range</span><span class=special>(</span>
|
||||
<span class=keyword>const</span> <span class=identifier>CompatibleKey</span><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>CompatibleCompare</span><span class=special>&</span> <span class=identifier>comp</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// range:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>LowerBounder</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>UpperBounder</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>></span> <span class=identifier>range</span><span class=special>(</span>
|
||||
<span class=identifier>LowerBounder</span> <span class=identifier>lower</span><span class=special>,</span><span class=identifier>UpperBounder</span> <span class=identifier>upper</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=special>};</span>
|
||||
|
||||
<span class=comment>// index comparison:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>==(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>size</span><span class=special>()==</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>size</span><span class=special>()&&</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>equal</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>begin</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special><(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>lexicographical_compare</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>!=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special>==</span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>>(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>y</span><span class=special><</span><span class=identifier>x</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>>=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special><</span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special><=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special>></span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// index specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h4><a name="complexity_signature">Complexity signature</a></h4>
|
||||
|
||||
<p>
|
||||
Here and in the descriptions of operations of ordered indices, we adopt the
|
||||
scheme outlined in the
|
||||
<a href="indices.html#complexity_signature">complexity signature
|
||||
section</a>. The complexity signature of ordered indices is:
|
||||
<ul>
|
||||
<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>
|
||||
<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
|
||||
change, <code>m(n)=log(n)</code> otherwise.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h4><a name="instantiation_types">Instantiation types</a></h4>
|
||||
|
||||
<p>Ordered indices are instantiated internally to <code>multi_index_container</code> and
|
||||
specified by means of <a href="indices.html#indexed_by"><code>indexed_by</code></a>
|
||||
with <a href="#unique_non_unique"> index specifiers <code>ordered_unique</code>
|
||||
and <code>ordered_non_unique</code></a>. Instantiations are dependent on the
|
||||
following types:
|
||||
<ul>
|
||||
<li><code>Value</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>Allocator</code> from <code>multi_index_container</code>,</li>
|
||||
<li><code>TagList</code> from the index specifier (if provided),</li>
|
||||
<li><code>KeyFromValue</code> from the index specifier,</li>
|
||||
<li><code>Compare</code> from the index specifier.</li>
|
||||
</ul>
|
||||
<code>TagList</code> must be an instantiation of
|
||||
<a href="indices.html#tag"><code>tag</code></a>. The type <code>KeyFromValue</code>,
|
||||
which determines the mechanism for extracting a key from <code>Value</code>,
|
||||
must be a model of <a href="key_extraction.html#key_extractors">
|
||||
<code>Key Extractor</code></a> from <code>Value</code>. <code>Compare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> on elements of
|
||||
<code>KeyFromValue::result_type</code>.
|
||||
</p>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<p>
|
||||
As explained in the <a href="indices.html#index_concepts">index
|
||||
concepts section</a>, indices do not have public constructors or destructors.
|
||||
Assignment, on the other hand, is provided.
|
||||
</p>
|
||||
|
||||
<code><b>index class name</b>& operator=(const <b>index class name</b>& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>a</span><span class=special>=</span><span class=identifier>b</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
where <code>a</code> and <code>b</code> are the <code>multi_index_container</code>
|
||||
objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="modifiers">Modifiers</a></h4>
|
||||
|
||||
<code>std::pair<iterator,bool> insert(const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful insertion,
|
||||
<code>p.first</code> points to the element inserted; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator insert(iterator position,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<code>position</code> is used as a hint to improve the efficiency of the
|
||||
operation.<br>
|
||||
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
|
||||
element. Otherwise, an iterator to an element that caused the insertion to be
|
||||
banned. Note that more than one element can be causing insertion not to be
|
||||
allowed.<br>
|
||||
<b>Complexity:</b> <code>O(H(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename InputIterator><br>
|
||||
void insert(InputIterator first,InputIterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<b>Effects:</b>
|
||||
<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>
|
||||
<span class=keyword>while</span><span class=special>(</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>)</span><span class=identifier>hint</span><span class=special>=</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>hint</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
|
||||
</pre></blockquote>
|
||||
<b>Complexity:</b> <code>O(m*H(n+m))</code>, where
|
||||
<code>m</code> is the number of elements in [<code>first</code>,
|
||||
<code>last</code>).<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator erase(iterator position);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
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>
|
||||
if no such element exists.<br>
|
||||
<b>Complexity:</b> <code>O(D(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>size_type erase(const key_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Deletes the elements with key equivalent to <code>x</code>.<br>
|
||||
<b>Returns:</b> Number of elements deleted.<br>
|
||||
<b>Complexity:</b> <code>O(log(n) + m*D(n))</code>, where <code>m</code> is
|
||||
the number of elements deleted.<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator erase(iterator first,iterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> [<code>first</code>,<code>last</code>) is a valid
|
||||
range of the index.<br>
|
||||
<b>Effects:</b> Deletes the elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Returns:</b> <code>last</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n) + m*D(n))</code>, where <code>m</code> is
|
||||
the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<a name="replace"><code>bool replace(iterator position,const value_type& x);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
to by <code>position</code> into the <code>multi_index_container</code> to which
|
||||
the index belongs if, for the value <code>x</code>
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists
|
||||
(except possibly <code>*position</code>) with equivalent key,</li>
|
||||
<li>AND replacing is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved
|
||||
in all cases.<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>
|
||||
<b>Exception safety:</b> Strong. If an exception is thrown by some
|
||||
user-provided operation the <code>multi_index_container</code> to which the index
|
||||
belongs remains in its original state.
|
||||
</blockquote>
|
||||
|
||||
<a name="modify">
|
||||
<code>template<typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <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>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
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
|
||||
<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.
|
||||
</blockquote>
|
||||
|
||||
<a name="modify_key">
|
||||
<code>template<typename Modifier> bool modify_key(iterator position,Modifier mod);</code></a>
|
||||
|
||||
<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> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
|
||||
<code>Unary Function</code></a> accepting arguments of type
|
||||
<code>key_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
iterator of the index.</br>
|
||||
<b>Effects:</b> Calls <code>mod(k)</code> where <code>k</code> is the key
|
||||
obtained by the internal <code>KeyFromValue</code> object of the index from
|
||||
the element pointed to by <code>position</code>, and rearranges
|
||||
<code>*position</code> into all the indices of the <code>multi_index_container</code>.
|
||||
Rearrangement is successful if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists
|
||||
with equivalent key,</li>
|
||||
<li>AND rearrangement is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
If the rearrangement fails, the element is erased.<br>
|
||||
<b>Postconditions:</b>Validity of <code>position</code> is preserved if
|
||||
the operation succeeds.<br>
|
||||
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
|
||||
otherwise.<br>
|
||||
<b>Complexity:</b> <code>O(M(n))</code>.<br>
|
||||
<b>Exception safety:</b> Basic. If an exception is thrown by some
|
||||
user-provided operation (except possibly <code>mod</code>), then
|
||||
the element pointed to by <code>position</code> is erased.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="observers">Observers</a></h4>
|
||||
|
||||
<p>Apart from standard <code>key_comp</code> and <code>value_comp</code>,
|
||||
ordered indices have a member function for retrieving the internal key extractor
|
||||
used.
|
||||
</p>
|
||||
|
||||
<code>key_from_value key_extractor()const;</code>
|
||||
|
||||
<blockquote>
|
||||
Returns a copy of the <code>key_from_value</code> object used to construct
|
||||
the index.<br>
|
||||
<b>Complexity:</b> Constant.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="set_operations">Set operations</a></h4>
|
||||
|
||||
<p>
|
||||
Ordered indices provide the full lookup functionality required by
|
||||
<a href="http://www.sgi.com/tech/stl/SortedAssociativeContainer.html">
|
||||
<code>Sorted Associative Containers</code></a> and
|
||||
<a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html">
|
||||
<code>Unique Associative Containers</code></a>, namely <code>find</code>,
|
||||
<code>count</code>, <code>lower_bound</code>, <code>upper_bound</code>
|
||||
and <code>equal_range</code>. Additionally, these member functions are
|
||||
templatized to allow for non-standard arguments, so extending
|
||||
the types of search operations allowed. The kind of arguments permissible
|
||||
when invoking the lookup member functions is defined by the following
|
||||
concept.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> <code>Compare</code> over values
|
||||
of type <code>Key</code>. A pair of types (<code>CompatibleKey</code>,
|
||||
<code>CompatibleCompare</code>) is said to be a <i>compatible extension</i>
|
||||
of <code>Compare</code> if
|
||||
<ol>
|
||||
<li><code>CompatibleCompare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
|
||||
<code>Binary Predicate</code></a> over (<code>Key</code>,
|
||||
<code>CompatibleKey</code>),</li>
|
||||
<li><code>CompatibleCompare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
|
||||
<code>Binary Predicate</code></a> over (<code>CompatibleKey</code>,
|
||||
<code>Key</code>),</li>
|
||||
<li>if <code>c_comp(ck,k1)</code> then <code>!c_comp(k1,ck)</code>,</li>
|
||||
<li>if <code>!c_comp(ck,k1)</code> and <code>!comp(k1,k2)</code> then
|
||||
<code>!c_comp(ck,k2)</code>,</li>
|
||||
<li>if <code>!c_comp(k1,ck)</code> and <code>!comp(k2,k1)</code> then
|
||||
<code>!c_comp(k2,ck)</code>,</li>
|
||||
</ol>
|
||||
for every <code>c_comp</code> of type <code>CompatibleCompare</code>,
|
||||
<code>comp</code> of type <code>Compare</code>, <code>ck</code> of type
|
||||
<code>CompatibleKey</code> and <code>k1</code>, <code>k2</code> of type
|
||||
<code>Key</code>.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<p>Additionally, a type <code>CompatibleKey</code> is said to be a
|
||||
<i>compatible key</i> of <code>Compare</code> if (<code>CompatibleKey</code>,
|
||||
<code>Compare</code>) is a compatible extension of <code>Compare</code>.
|
||||
This implies that <code>Compare</code>, as well as being a strict
|
||||
weak ordering, accepts arguments of type <code>CompatibleKey</code>,
|
||||
which usually means it has several overloads of <code>operator()</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the context of a compatible extension or a compatible key, the expressions
|
||||
"equivalent", "less than" and "greater than" take on their obvious
|
||||
interpretations.
|
||||
</p>
|
||||
|
||||
<code>template<typename CompatibleKey> iterator find(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key 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>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
iterator find(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
<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>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey> size_type<br>
|
||||
count(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key 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))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
<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>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
iterator lower_bound(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key 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>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
iterator lower_bound(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
<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>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
iterator upper_bound(const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key 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>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
iterator upper_bound(const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
<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>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey><br>
|
||||
std::pair<iterator,iterator> equal_range(<br>
|
||||
const CompatibleKey& x)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>CompatibleKey</code> is a compatible key of
|
||||
<code>key_compare</code>.</br>
|
||||
<b>Effects:</b> Equivalent to <code>make_pair(lower_bound(x),upper_bound(x))</code>.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename CompatibleKey,typename CompatibleCompare><br>
|
||||
std::pair<iterator,iterator> equal_range(</br>
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> (<code>CompatibleKey</code>, <code>CompatibleCompare</code>)
|
||||
is a compatible extension of <code>key_compare</code>.</br>
|
||||
<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>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h4><a name="range_operations">Range operations</a></h4>
|
||||
|
||||
<p>
|
||||
The member function <code>range</code> is not defined for sorted associative
|
||||
containers, but ordered indices provide it as a convenient utility. A range
|
||||
or interval is defined by two conditions for the lower and upper bounds, which
|
||||
are modeled after the following concepts.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> <code>Compare</code> over values
|
||||
of type <code>Key</code>. A type <code>LowerBounder</code> is said to be
|
||||
a <i>lower bounder</i> of <code>Compare</code> if
|
||||
<ol>
|
||||
<li><code>LowerBounder</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/Predicate.html">
|
||||
<code>Predicate</code></a> over <code>Key</code>,</li>
|
||||
<li>if <code>lower(k1)</code> and <code>!comp(k2,k1)</code> then
|
||||
<code>lower(k2)</code>,</li>
|
||||
</ol>
|
||||
for every <code>lower</code> of type <code>LowerBounder</code>,
|
||||
<code>comp</code> of type <code>Compare</code>, and <code>k1</code>,
|
||||
<code>k2</code> of type <code>Key</code>. Similarly, an <i>upper bounder</i>
|
||||
is a type <code>UpperBounder</code> such that
|
||||
<ol>
|
||||
<li><code>UpperBounder</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/Predicate.html">
|
||||
<code>Predicate</code></a> over <code>Key</code>,</li>
|
||||
<li>if <code>upper(k1)</code> and <code>!comp(k1,k2)</code> then
|
||||
<code>upper(k2)</code>,</li>
|
||||
</ol>
|
||||
for every <code>upper</code> of type <code>UpperBounder</code>,
|
||||
<code>comp</code> of type <code>Compare</code>, and <code>k1</code>,
|
||||
<code>k2</code> of type <code>Key</code>.
|
||||
</p>
|
||||
|
||||
<code>template<typename LowerBounder,typename UpperBounder><br>
|
||||
std::pair<iterator,iterator> range(<br>
|
||||
LowerBounder lower,UpperBounder upper)const;
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>LowerBounder</code> and <code>UpperBounder</code> are
|
||||
a lower and upper bounder of <code>key_compare</code>, respectively.</br>
|
||||
<b>Effects:</b> 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
|
||||
both point to the first element satisfying <code>lower</code>, or else
|
||||
are equal to <code>end()</code> if this latter element does not exist.<br>
|
||||
<b>Complexity:</b> <code>O(log(n))</code>.<br>
|
||||
<b>Variants:</b> In place of <code>lower</code> or <code>upper</code> (or both),
|
||||
the singular value <code>boost::multi_index::unbounded</code> can be
|
||||
provided. This acts as a predicate which all values of type <code>key_type</code>
|
||||
satisfy.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="serialization">Serialization</a></h4>
|
||||
|
||||
<p>
|
||||
Indices cannot be serialized on their own, but only as part of the
|
||||
<code>multi_index_container</code> into which they are embedded. In describing
|
||||
the additional preconditions and guarantees associated to ordered indices
|
||||
with respect to serialization of their embedding containers, we
|
||||
use the concepts defined in the <code>multi_index_container</code>
|
||||
<a href="multi_index_container.html#serialization">serialization section</a>.
|
||||
</p>
|
||||
|
||||
Operation: saving of a <code>multi_index_container</code> <code>m</code> to an
|
||||
output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> No additional requirements to those imposed by the container.
|
||||
</blockquote>
|
||||
|
||||
Operation: loading of a <code>multi_index_container</code> <code>m'</code> from an
|
||||
input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> Additionally to the general requirements, <code>value_comp()</code>
|
||||
must be serialization-compatible with <code>m.get<i>().value_comp()</code>,
|
||||
where <code>i</code> is the position of the ordered index in the container.<br>
|
||||
<b>Postconditions:</b> On succesful loading, each of the elements of
|
||||
[<code>begin()</code>, <code>end()</code>) is a restored copy of the corresponding
|
||||
element in [<code>m.get<i>().begin()</code>, <code>m.get<i>().end()</code>).
|
||||
</blockquote>
|
||||
|
||||
Operation: saving of an <code>iterator</code> or <code>const_iterator</code>
|
||||
<code>it</code> to an output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>it</code> is a valid iterator of the index. The associated
|
||||
<code>multi_index_container</code> has been previously saved.
|
||||
</blockquote>
|
||||
|
||||
Operation: loading of an <code>iterator</code> or <code>const_iterator</code>
|
||||
<code>it'</code> from an input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Postconditions:</b> On succesful loading, if <code>it</code> was dereferenceable
|
||||
then <code>*it'</code> is the restored copy of <code>*it</code>, otherwise
|
||||
<code>it'==end()</code>.<br>
|
||||
<b>Note:</b> It is allowed that <code>it</code> be a <code>const_iterator</code>
|
||||
and the restored <code>it'</code> an <code>iterator</code>, or viceversa.
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="indices.html"><img src="../prev.gif" alt="index reference" border="0"><br>
|
||||
Index reference
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="hash_indices.html"><img src="../next.gif" alt="hashed indices" border="0"><br>
|
||||
Hashed indices
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised August 24th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,892 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Sequenced indices reference</title>
|
||||
<link rel="stylesheet" href="../style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Sequenced indices reference</h1>
|
||||
|
||||
<div class="prev_link"><a href="hash_indices.html"><img src="../prev.gif" alt="hashed indices" border="0"><br>
|
||||
Hashed indices
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="key_extraction.html"><img src="../next.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#seq_index_fwd_synopsis">Header
|
||||
<code>"boost/multi_index/sequenced_index_fwd.hpp"</code> synopsis</a></li>
|
||||
<li><a href="#synopsis">Header
|
||||
<code>"boost/multi_index/sequenced_index.hpp"</code> synopsis</a>
|
||||
<ul>
|
||||
<li><a href="#sequenced"><code>sequenced</code> index specifier</a></li>
|
||||
<li><a href="#seq_indices">Sequenced indices</a>
|
||||
<ul>
|
||||
<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="#capacity">Capacity operations</a></li>
|
||||
<li><a href="#modifiers">Modifiers</a></li>
|
||||
<li><a href="#list_operations">List operations</a></li>
|
||||
<li><a href="#special_list_operations">Special list operations</a></li>
|
||||
<li><a href="#serialization">Serialization</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a name="seq_index_fwd_synopsis">Header
|
||||
<a href="../../../../boost/multi_index/sequenced_index_fwd.hpp">
|
||||
<code>"boost/multi_index/sequenced_index_fwd.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=comment>// sequenced index specifier</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>TagList</span><span class=special>=</span><span class=identifier>tag</span><span class=special><></span> <span class=special>></span> <span class=keyword>struct</span> <span class=identifier>sequenced</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// indices</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span> <span class=keyword>class</span> <b>index class name implementation defined</b><span class=special>;</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>sequenced_index_fwd.hpp</code> provides forward declarations for the
|
||||
<a href="#sequenced"><code>sequenced</code></a> index specifier and
|
||||
its associated <a href="#seq_indices">sequenced index</a> class.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="synopsis">Header
|
||||
<a href="../../../../boost/multi_index/sequenced_index.hpp">
|
||||
<code>"boost/multi_index/sequenced_index.hpp"</code></a> synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=comment>// sequenced index specifier</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>TagList</span><span class=special>=</span><span class=identifier>tag</span><span class=special><></span> <span class=special>></span> <span class=keyword>struct</span> <span class=identifier>sequenced</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// indices</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span> <span class=keyword>class</span> <b>index class name implementation defined</b><span class=special>;</span>
|
||||
|
||||
<span class=comment>// index comparison:</span>
|
||||
|
||||
<span class=comment>// <b>OP</b> is any of ==,<,!=,>,>=,<=</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span> <b><i>OP</i></b><span class=special>(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// index specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="sequenced">
|
||||
<code>sequenced</code> index specifier
|
||||
</a></h3>
|
||||
|
||||
<p>
|
||||
This index specifier allows for insertion of a <a href="#seq_indices">sequenced
|
||||
index</a>.</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>TagList</span><span class=special>=</span><span class=identifier>tag</span><span class=special><></span> <span class=special>></span> <span class=keyword>struct</span> <span class=identifier>sequenced</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>If provided, <code>TagList</code> must be an instantiation of
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
</p>
|
||||
|
||||
<h3><a name="seq_indices">Sequenced indices</a></h3>
|
||||
|
||||
<p>
|
||||
Sequenced indices are modeled after the semantics of a bidirectional list
|
||||
like <code>std::list</code>. Elements in a sequenced index are by default
|
||||
sorted according to their order of insertion: this means that new elements
|
||||
inserted through a different index of the <code>multi_index_container</code> are appended
|
||||
to the end of the sequenced index. Additionally, the index allows for free
|
||||
reordering of elements in the same vein as <code>std::list</code> does. Validity
|
||||
of iterators and references to elements is preserved in all operations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are a number of differences with respect to <code>std::lists</code>:
|
||||
<ul>
|
||||
<li>Sequenced indices are not <a href="http://www.sgi.com/tech/stl/Assignable.html">
|
||||
<code>Assignable</code></a> (like any other index.)</li>
|
||||
<li>Unlike as in <code>std::list</code>, insertions into a sequenced index
|
||||
may fail due to clashings with other indices. This alters the semantics
|
||||
of the operations provided with respect to their analogues in
|
||||
<code>std::list</code>.
|
||||
</li>
|
||||
<li>Elements in a sequenced index are not mutable, and can only be changed
|
||||
by means of <a href="#replace"><code>replace</code></a> and
|
||||
<a href="#modify"><code>modify</code></a> member functions.
|
||||
</li>
|
||||
</ul>
|
||||
Having these restrictions into account, sequenced indices are models
|
||||
of <a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">
|
||||
<code>Reversible Container</code></a>,
|
||||
<a href="http://www.sgi.com/tech/stl/FrontInsertionSequence.html">
|
||||
<code>Front Insertion Sequence</code></a> and
|
||||
<a href="http://www.sgi.com/tech/stl/BackInsertionSequence.html">
|
||||
<code>Back Insertion Sequence</code></a>. We only provide descriptions
|
||||
of those types and operations that are that are either not present in the
|
||||
concepts modeled or do not exactly conform to the requirements for these
|
||||
types of containers.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>namespace</span> <span class=identifier>detail</span><span class=special>{</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined: dependent on types Value, Allocator, TagList</b><span class=special>></span>
|
||||
<span class=keyword>class</span> <b>name is implementation defined</b>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>public</span><span class=special>:</span>
|
||||
<span class=comment>// types:</span>
|
||||
|
||||
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>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=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>
|
||||
<span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>const_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>size_type</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>ptrdiff_t</span> <span class=identifier>difference_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>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_type</span><span class=special>::</span><span class=identifier>const_pointer</span> <span class=identifier>const_pointer</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<iterator></b> <span class=identifier>reverse_iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef</span> <b>equivalent to
|
||||
std::reverse_iterator<const_iterator></b> <span class=identifier>const_reverse_iterator</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// construct/copy/destroy:</span>
|
||||
|
||||
<b>index class name</b><span class=special>&</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>value</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// iterators:</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>begin</span><span class=special>();</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>begin</span><span class=special>()</span><span class=keyword>const</span><span class=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>reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>();</span>
|
||||
<span class=identifier>const_reverse_iterator</span> <span class=identifier>rbegin</span><span class=special>()</span><span class=keyword>const</span><span class=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=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>
|
||||
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>value_type</span><span class=special>());</span>
|
||||
|
||||
<span class=comment>// access:</span>
|
||||
|
||||
<span class=identifier>const_reference</span> <span class=identifier>front</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
<span class=identifier>const_reference</span> <span class=identifier>back</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=comment>// modifiers:</span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>push_front</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>pop_front</span><span class=special>();</span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>push_back</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>pop_back</span><span class=special>();</span>
|
||||
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>></span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>();</span>
|
||||
|
||||
<span class=comment>// list operations:</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>remove</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>value</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Predicate</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>remove_if</span><span class=special>(</span><span class=identifier>Predicate</span> <span class=identifier>pred</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>unique</span><span class=special>();</span>
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>class</span> <span class=identifier>BinaryPredicate</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>unique</span><span class=special>(</span><span class=identifier>BinaryPredicate</span> <span class=identifier>binary_pred</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>Compare</span> <span class=identifier>comp</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>sort</span><span class=special>();</span>
|
||||
<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>sort</span><span class=special>(</span><span class=identifier>Compare</span> <span class=identifier>comp</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>reverse</span><span class=special>();</span>
|
||||
|
||||
<span class=comment>// relocate operations:</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>relocate</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>relocate</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// index comparison:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>==(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>size</span><span class=special>()==</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>size</span><span class=special>()&&</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>equal</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>begin</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special><(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>lexicographical_compare</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>!=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special>==</span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>>(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span>
|
||||
<span class=special>,</span><span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=identifier>y</span><span class=special><</span><span class=identifier>x</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>>=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special><</span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>arg set 1</b><span class=special>,</span><b>arg set 2</b><span class=special>></span>
|
||||
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special><=(</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 1</b><span class=special>>&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>const</span> <b>index class name</b><span class=special><</span><b>arg set 2</b><span class=special>>&</span> <span class=identifier>y</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=keyword>return</span> <span class=special>!(</span><span class=identifier>x</span><span class=special>></span><span class=identifier>y</span><span class=special>);</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=comment>// index specialized algorithms:</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><b>implementation defined</b><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>y</span><span class=special>);</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index::detail</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
|
||||
|
||||
<span class=special>}</span> <span class=comment>// namespace boost</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<h4><a name="complexity_signature">Complexity signature</a></h4>
|
||||
|
||||
<p>
|
||||
Here and in the descriptions of operations of sequenced indices, we adopt the
|
||||
scheme outlined in the
|
||||
<a href="indices.html#complexity_signature">complexity signature
|
||||
section</a>. The complexity signature of sequenced indices is:
|
||||
<ul>
|
||||
<li>copying: <code>c(n)=n*log(n)</code>,</li>
|
||||
<li>insertion: <code>i(n)=1</code> (constant),</li>
|
||||
<li>hinted insertion: <code>h(n)=1</code> (constant),</li>
|
||||
<li>deletion: <code>d(n)=1</code> (constant),</li>
|
||||
<li>replacement: <code>r(n)=1</code> (constant),</li>
|
||||
<li>modifying: <code>m(n)=1</code> (constant).</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h4><a name="instantiation_types">Instantiation types</a></h4>
|
||||
|
||||
<p>Sequenced indices are instantiated internally to <code>multi_index_container</code>
|
||||
and specified by means of <a href="indices.html#indexed_by">
|
||||
<code>indexed_by</code></a> with the <a href="#sequenced"><code>sequenced</code></a>
|
||||
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>
|
||||
</ul>
|
||||
<code>TagList</code> must be an instantiation of
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
</p>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<p>
|
||||
As explained in the <a href="indices.html#index_concepts">index
|
||||
concepts section</a>, indices do not have public constructors or destructors.
|
||||
Assignment, on the other hand, is provided.
|
||||
</p>
|
||||
|
||||
<code><b>index class name</b>& operator=(const <b>index class name</b>& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>a</span><span class=special>=</span><span class=identifier>b</span><span class=special>;</span>
|
||||
</pre></blockquote>
|
||||
where <code>a</code> and <code>b</code> are the <code>multi_index_container</code>
|
||||
objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
|
||||
<b>Returns:</b> <code>*this</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template <class InputIterator><br>
|
||||
void assign(InputIterator first,InputIterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>clear</span><span class=special>();</span>
|
||||
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>first</span><span class=special>,</span><span class=identifier>last</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>void assign(size_type n,const value_type& value);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>clear</span><span class=special>();</span>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>i</span><span class=special>=</span><span class=number>0</span><span class=special>;</span><span class=identifier>i</span><span class=special><</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>n</span><span class=special>)</span><span class=identifier>push_back</span><span class=special>(</span><span class=identifier>v</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="capacity">Capacity operations</a></h4>
|
||||
|
||||
<code>void resize(size_type n,const value_type& x=value_type());</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>></span><span class=identifier>size</span><span class=special>())</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>n</span><span class=special>-</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>else</span> <span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special><</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>n</span><span class=special>,</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
<b>Note:</b> If an expansion is requested, the size of the index is not guaranteed
|
||||
to be <code>n</code> after this operation (other indices may ban insertions.)
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="modifiers">Modifiers</a></h4>
|
||||
|
||||
<code>std::pair<iterator,bool> push_front(const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Inserts <code>x</code> at the beginning of the sequence if
|
||||
no other index of the <code>multi_index_container</code> bans the insertion.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful
|
||||
insertion, <code>p.first</code> points to the element inserted; otherwise,
|
||||
<code>p.first</code> points to an element that caused the insertion to be banned.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.
|
||||
</blockquote>
|
||||
|
||||
<code>std::pair<iterator,bool> push_back(const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Inserts <code>x</code> at the end of the sequence if
|
||||
no other index of the <code>multi_index_container</code> bans the insertion.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion took place. On successful
|
||||
insertion, <code>p.first</code> points to the element inserted; otherwise,
|
||||
<code>p.first</code> points to an element that caused the insertion to be banned.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.
|
||||
</blockquote>
|
||||
|
||||
<code>std::pair<iterator,bool> insert(iterator position,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>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>
|
||||
is <code>true</code> if and only if insertion took place. On successful
|
||||
insertion, <code>p.first</code> points to the element inserted; otherwise,
|
||||
<code>p.first</code> points to an element that caused the insertion to be banned.
|
||||
Note that more than one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> <code>O(I(n))</code>.<br>
|
||||
<b>Exception safety:</b> Strong.
|
||||
</blockquote>
|
||||
|
||||
<code>void insert(iterator position,size_type n,const value_type& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.</br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>i</span><span class=special>=</span><span class=number>0</span><span class=special>;</span><span class=identifier>i</span><span class=special><</span><span class=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename InputIterator><br>
|
||||
void insert(iterator position,InputIterator first,InputIterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>InputIterator</code> is a model of
|
||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
||||
<code>Input Iterator</code></a> over elements of type
|
||||
<code>value_type</code> or a type convertible to <code>value_type</code>.
|
||||
<code>first</code> and <code>last</code> are not iterators into any
|
||||
index of the <code>multi_index_container</code> to which this index belongs.
|
||||
<code>last</code> is reachable from <code>first</code>.</br>
|
||||
<b>Effects:</b>
|
||||
<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>
|
||||
</pre></blockquote>
|
||||
<b>Complexity:</b> <code>O(m*I(n+m))</code>, where <code>m</code> is the
|
||||
number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> Basic.
|
||||
</blockquote>
|
||||
|
||||
<code>iterator erase(iterator position);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
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>
|
||||
if no such element exists.<br>
|
||||
<b>Complexity:</b> <code>O(D(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>iterator erase(iterator first,iterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> [<code>first</code>,<code>last</code>) is a valid
|
||||
range of the index.<br>
|
||||
<b>Effects:</b> Deletes the elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Returns:</b> <code>last</code>.<br>
|
||||
<b>Complexity:</b> <code>O(m*D(n))</code>, where <code>m</code> is
|
||||
the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<a name="replace"><code>bool replace(iterator position,const value_type& x);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
|
||||
of the index.</br>
|
||||
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
|
||||
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
|
||||
<code>multi_index_container</code>.<br>
|
||||
<b>Postconditions:</b> Validity of <code>position</code> is preserved
|
||||
in all cases.<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>
|
||||
<b>Exception safety:</b> Strong. If an exception is thrown by some
|
||||
user-provided operation the <code>multi_index_container</code> to which the index
|
||||
belongs remains in its original state.
|
||||
</blockquote>
|
||||
|
||||
<a name="modify">
|
||||
<code>template<typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <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>value_type&</code>. <code>position</code> is a valid dereferenceable
|
||||
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
|
||||
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.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="list_operations">List operations</a></h4>
|
||||
|
||||
<p>
|
||||
Sequenced indices provides the full set of list operations provided by
|
||||
<code>std::list</code>; the semantics of these member functions, however,
|
||||
differ from that of <code>std::list</code> in some cases as insertions
|
||||
might not succeed due to banning by other indices. Similarly, the complexity
|
||||
of the operations may depend on the other indices belonging to the
|
||||
same <code>multi_index_container</code>.
|
||||
</p>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name</b>& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>&x!=this</code>.</br>
|
||||
<b>Effects:</b> Inserts the contents of <code>x</code> before <code>position</code>,
|
||||
in the same order as they were in <code>x</code>. Those elements succesfully
|
||||
inserted are erased from <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name</b>& x,iterator i);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>i</code> is a valid dereferenceable iterator <code>x</code>.<br>
|
||||
<b>Effects:</b> Inserts the element pointed to by <code>i</code> before
|
||||
<code>position</code>: if insertion is succesful, the element is erased from
|
||||
<code>x</code>. In the special case <code>&x==this</code>, no copy or
|
||||
deletion is performed, and the operation is always succesful. If
|
||||
<code>position==i</code>, no operation is performed.<br>
|
||||
<b>Postconditions:</b> If <code>&x==this</code>, no iterator or reference
|
||||
is invalidated.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(I(n) + D(n))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, strong.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name&</b> x,iterator first,iterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>first</code> and <code>last</code> are valid iterators of <code>x</code>.
|
||||
<code>last</code> is reachable from <code>first</code>. <code>position</code>
|
||||
is not in the range [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Effects:</b> For each element in the range [<code>first</code>,<code>last</code>),
|
||||
insertion is tried before <code>position</code>; if the operation is succesful,
|
||||
the element is erased from <code>x</code>. In the special case
|
||||
<code>&x==this</code>, no copy or deletion is performed, and insertions are
|
||||
always succesful.<br>
|
||||
<b>Postconditions:</b> If <code>&x==this</code>, no iterator or reference
|
||||
is invalidated.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(m*I(n+m) + m*D(x.size()))</code> where <code>m</code> is the number
|
||||
of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>void remove(const value_type& value);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Erases all elements of the index which compare equal to
|
||||
<code>value</code>.<br>
|
||||
<b>Complexity:</b> <code>O(n + m*D(n))</code>, where <code>m</code>
|
||||
is the number of elements erased.<br>
|
||||
<b>Exception safety:</b> Basic.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Predicate> void remove_if(Predicate pred);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Erases all elements <code>x</code> of the index for which
|
||||
<code>pred(x)</code> holds..<br>
|
||||
<b>Complexity:</b> <code>O(n + m*D(n))</code>, where <code>m</code>
|
||||
is the number of elements erased.<br>
|
||||
<b>Exception safety:</b> Basic.
|
||||
</blockquote>
|
||||
|
||||
<code>void unique();</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Eliminates all but the first element from every consecutive
|
||||
group of equal elements referred to by the iterator <code>i</code> in the range
|
||||
[<code>first+1</code>,<code>last</code>) for which <code>*i==*(i-1)</code>.<br>
|
||||
<b>Complexity:</b> <code>O(n + m*D(n))</code>, where <code>m</code>
|
||||
is the number of elements erased.<br>
|
||||
<b>Exception safety:</b> Basic.
|
||||
</blockquote>
|
||||
|
||||
<code>template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Eliminates all but the first element from every consecutive
|
||||
group of elements referred to by the iterator <code>i</code> in the range
|
||||
[<code>first+1</code>,<code>last</code>) for which
|
||||
<code>binary_pred(*i,*(i-1))</code> holds.<br>
|
||||
<b>Complexity:</b> <code>O(n + m*D(n))</code>, where <code>m</code>
|
||||
is the number of elements erased.<br>
|
||||
<b>Exception safety:</b> Basic.
|
||||
</blockquote>
|
||||
|
||||
<code>void merge(index class name& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>std::less<value_type></code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
|
||||
Both the index and <code>x</code> are sorted according to
|
||||
<code>std::less<value_type></code>.<br>
|
||||
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the
|
||||
corresponding position of the index (according to the order). Elements
|
||||
successfully inserted are erased from <code>x</code>. The resulting sequence
|
||||
is stable, i.e. equivalent elements of either container preserve their
|
||||
relative position. In the special case <code>&x==this</code>, no operation
|
||||
is performed.<br>
|
||||
<b>Postconditions:</b> Elements in the index and remaining elements in
|
||||
<code>x</code> are sorted.
|
||||
Validity of iterators to the index and of non-erased elements of <code>x</code>
|
||||
references is preserved.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(n + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>template <typename Compare> void merge(index class name& x,Compare comp);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Compare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
|
||||
Both the index and <code>x</code> are sorted according to <code>comp</code>.<br>
|
||||
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the
|
||||
corresponding position of the index (according to <code>comp</code>).
|
||||
Elements successfully inserted are erased from <code>x</code>. The resulting
|
||||
sequence is stable, i.e. equivalent elements of either container preserve
|
||||
their relative position. In the special case <code>&x==this</code>, no
|
||||
operation is performed.<br>
|
||||
<b>Postconditions:</b> Elements in the index and remaining elements in
|
||||
<code>x</code> are sorted according to <code>comp</code>.
|
||||
Validity of iterators to the index and of non-erased elements of <code>x</code>
|
||||
references is preserved.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(n + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, basic.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>void sort();</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>std::less<value_type></code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
|
||||
<b>Effects:</b> Sorts the index according to
|
||||
<code>std::less<value_type></code>. The sorting is stable, i.e.
|
||||
equivalent elements preserve their relative position.<br>
|
||||
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
|
||||
<b>Complexity:</b> <code>O(n*log(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code> if
|
||||
<code>std::less<value_type></code> does not throw; otherwise, basic.
|
||||
</blockquote>
|
||||
|
||||
<code>template <typename Compare> void sort(Compare comp);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Compare</code> is a
|
||||
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
|
||||
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
|
||||
<b>Effects:</b> Sorts the index according to <code>comp</code>. The sorting
|
||||
is stable, i.e. equivalent elements preserve their relative position.<br>
|
||||
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
|
||||
<b>Complexity:</b> <code>O(n*log(n))</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code> if <code>comp</code> does
|
||||
not throw; otherwise, basic.
|
||||
</blockquote>
|
||||
|
||||
<code>void reverse();</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Effects:</b> Reverses the order of the elements in the index.<br>
|
||||
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
|
||||
<b>Complexity:</b> <code>O(n)</code>.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="special_list_operations">Special list operations</a></h4>
|
||||
|
||||
<p>
|
||||
Sequenced indices provide some convenience member functions without
|
||||
counterparts in <code>std::list</code>. These operations are aimed at
|
||||
improving the usability of sequenced indices in points where
|
||||
the support offered by standard list operations is insufficient or
|
||||
difficult to use.
|
||||
</p>
|
||||
|
||||
<code>void relocate(iterator position,iterator i);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>i</code> is a valid dereferenceable iterator of the index.<br>
|
||||
<b>Effects:</b> Inserts the element pointed to by <code>i</code> before
|
||||
<code>position</code>. If <code>position==i</code>, no operation is
|
||||
performed.<br>
|
||||
<b>Postconditions:</b> No iterator or reference is invalidated.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<code>void relocate(iterator position,iterator first,iterator last);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>first</code> and <code>last</code> are valid iterators of the index.
|
||||
<code>last</code> is reachable from <code>first</code>. <code>position</code>
|
||||
is not in the range [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Effects:</b> The range of elements [<code>first</code>,<code>last</code>)
|
||||
is repositioned just before <code>position</code>.<br>
|
||||
<b>Postconditions:</b> No iterator or reference is invalidated.<br>
|
||||
<b>Complexity:</b> Constant.<br>
|
||||
<b>Exception safety:</b> <code>nothrow</code>.<br>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="serialization">Serialization</a></h4>
|
||||
|
||||
<p>
|
||||
Indices cannot be serialized on their own, but only as part of the
|
||||
<code>multi_index_container</code> into which they are embedded. In describing
|
||||
the additional preconditions and guarantees associated to sequenced indices
|
||||
with respect to serialization of their embedding containers, we
|
||||
use the concepts defined in the <code>multi_index_container</code>
|
||||
<a href="multi_index_container.html#serialization">serialization section</a>.
|
||||
</p>
|
||||
|
||||
Operation: saving of a <code>multi_index_container</code> <code>m</code> to an
|
||||
output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> No additional requirements to those imposed by the container.
|
||||
</blockquote>
|
||||
|
||||
Operation: loading of a <code>multi_index_container</code> <code>m'</code> from an
|
||||
input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> No additional requirements to those imposed by the container.<br>
|
||||
<b>Postconditions:</b> On succesful loading, each of the elements of
|
||||
[<code>begin()</code>, <code>end()</code>) is a restored copy of the corresponding
|
||||
element in [<code>m.get<i>().begin()</code>, <code>m.get<i>().end()</code>),
|
||||
where <code>i</code> is the position of the sequenced index in the container.
|
||||
</blockquote>
|
||||
|
||||
Operation: saving of an <code>iterator</code> or <code>const_iterator</code>
|
||||
<code>it</code> to an output archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>it</code> is a valid iterator of the index. The associated
|
||||
<code>multi_index_container</code> has been previously saved.
|
||||
</blockquote>
|
||||
|
||||
Operation: loading of an <code>iterator</code> or <code>const_iterator</code>
|
||||
<code>it'</code> from an input archive (XML archive) <code>ar</code>.
|
||||
|
||||
<blockquote>
|
||||
<b>Postconditions:</b> On succesful loading, if <code>it</code> was dereferenceable
|
||||
then <code>*it'</code> is the restored copy of <code>*it</code>, otherwise
|
||||
<code>it'==end()</code>.<br>
|
||||
<b>Note:</b> It is allowed that <code>it</code> be a <code>const_iterator</code>
|
||||
and the restored <code>it'</code> an <code>iterator</code>, or viceversa.
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="hash_indices.html"><img src="../prev.gif" alt="hashed indices" border="0"><br>
|
||||
Hashed indices
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex reference" border="0"><br>
|
||||
Boost.MultiIndex reference
|
||||
</a></div>
|
||||
<div class="next_link"><a href="key_extraction.html"><img src="../next.gif" alt="key extraction" border="0"><br>
|
||||
Key extraction
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised August 22nd 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,112 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Release notes</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Release notes</h1>
|
||||
|
||||
<div class="prev_link"><a href="future_work.html"><img src="prev.gif" alt="future work" border="0"><br>
|
||||
Future work
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="acknowledgements.html"><img src="next.gif" alt="acknowledgements" border="0"><br>
|
||||
Acknowledgements
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<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_33_1">Boost 1.33.1 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>For ordered and hashed indices, <code>erase(it)</code> and
|
||||
<code>erase(first,last)</code> now return an iterator to the element
|
||||
following those being deleted (previously nothing was returned), in
|
||||
accordance with the C++ Standard Library
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">Defect
|
||||
Report 130</a> and issue 6.19 of TR1
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Issues
|
||||
List</a>.
|
||||
</li>
|
||||
<li>Boost.MultiIndex offers the usual guarantees with respect to
|
||||
multithreading code provided by most STL implementations:
|
||||
<ol>
|
||||
<li>Concurrent access to different containers is safe.</li>
|
||||
<li>Concurrent read-only access to the same container is safe.</li>
|
||||
</ol>
|
||||
In previous versions of the library, the latter guarantee was not properly
|
||||
maintained if the <a href="advanced_topics.html#safe_mode">safe
|
||||
mode</a> was set. This problem has been fixed now.
|
||||
</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="boost_1_33">Boost 1.33 release</a></h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Added <a href="advanced_topics.html#hashed_indices">hashed indices</a>,
|
||||
whose interface is based on the specification for unordered associative
|
||||
containers by the C++ Standard Library Technical Report (TR1).
|
||||
</li>
|
||||
<li>Added <a href="advanced_topics.html#serialization">serialization support</a>
|
||||
for <a href="../../serialization/index.html">Boost.Serialization</a>.
|
||||
</li>
|
||||
<li>Destruction of <code>multi_index_container</code>s and <code>clear</code>
|
||||
memfuns now perform faster.
|
||||
</li>
|
||||
<li>Internal changes aimed at reducing the length of symbol names generated
|
||||
by the compiler; cuts of up to a 50% can be achieved with respect to the
|
||||
Boost 1.32 release. This results in much shorter and more readable error
|
||||
messages and has also a beneficial impact on compilers with strict limits on
|
||||
symbol name lengths. Additionally, a section on further
|
||||
<a href="compiler_specifics.html#symbol_reduction">reduction of symbol name
|
||||
lengths</a> has been added.
|
||||
</li>
|
||||
<li>Restructured some parts of the documentation, new examples.</li>
|
||||
<li>Maintenance fixes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="future_work.html"><img src="prev.gif" alt="future work" border="0"><br>
|
||||
Future work
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="acknowledgements.html"><img src="next.gif" alt="acknowledgements" border="0"><br>
|
||||
Acknowledgements
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised September 5th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,54 +0,0 @@
|
||||
/* 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)
|
||||
*/
|
||||
|
||||
pre{
|
||||
BORDER-RIGHT: gray 1pt solid;
|
||||
PADDING-RIGHT: 2pt;
|
||||
BORDER-TOP: gray 1pt solid;
|
||||
DISPLAY: block;
|
||||
PADDING-LEFT: 2pt;
|
||||
PADDING-BOTTOM: 2pt;
|
||||
BORDER-LEFT: gray 1pt solid;
|
||||
MARGIN-RIGHT: 32pt;
|
||||
PADDING-TOP: 2pt;
|
||||
BORDER-BOTTOM: gray 1pt solid;
|
||||
FONT-FAMILY: "Courier New", Courier, mono;
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
table{
|
||||
PADDING-RIGHT: 2pt;
|
||||
BORDER-TOP: gray 1pt solid;
|
||||
DISPLAY: block;
|
||||
PADDING-LEFT: 2pt;
|
||||
PADDING-BOTTOM: 2pt;
|
||||
BORDER-LEFT: gray 1pt solid;
|
||||
MARGIN-RIGHT: 32pt;
|
||||
PADDING-TOP: 2pt;
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
td{
|
||||
BORDER-STYLE: solid;
|
||||
BORDER-WIDTH: 1pt;
|
||||
BORDER-LEFT: ;
|
||||
BORDER-RIGHT: gray 1pt solid;
|
||||
BORDER-TOP: ;
|
||||
BORDER-BOTTOM: gray 1pt solid;
|
||||
}
|
||||
th{color: #ffffff; background-color: #000000;}
|
||||
.odd_tr{background-color: #ffffff;}
|
||||
|
||||
.keyword{color: #0000FF;}
|
||||
.identifier{}
|
||||
.comment{font-style: italic; color: #008000;}
|
||||
.special{color: #800040;}
|
||||
.preprocessor{color: #3F007F;}
|
||||
.string{font-style: italic; color: #666666;}
|
||||
.literal{font-style: italic; color: #666666;}
|
||||
|
||||
.prev_link{width: 30%; float: left; text-align: left;}
|
||||
.up_link{width: 39.9%; float: left; text-align: center;}
|
||||
.next_link{width: 30%; float: left; text-align: right;}
|
||||
157
doc/tests.html
@@ -1,157 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.MultiIndex Documentation - Tests</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Boost.MultiIndex Tests</h1>
|
||||
|
||||
<div class="prev_link"><a href="examples.html"><img src="prev.gif" alt="examples" border="0"><br>
|
||||
Examples
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="future_work.html"><img src="next.gif" alt="future work" border="0"><br>
|
||||
Future work
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
The Boost.MultiIndex test suite exercises the whole spectrum of
|
||||
functionalities provided by the library. Although the tests are not meant
|
||||
to serve as a learning guide, the interested reader may find it
|
||||
useful to inspect the source code to gain familiarity
|
||||
with some of the least common features offered by Boost.MultiIndex.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<table cellspacing="0" cellpadding="5">
|
||||
<caption><b>Boost.MultiIndex test suite.</b></caption>
|
||||
<tr>
|
||||
<th>Program</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_basic.cpp"><code>test_basic.cpp</code></a></td>
|
||||
<td>Simple program along the lines of the employees example studied in the
|
||||
tutorial.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_capacity.cpp"><code>test_capacity.cpp</code></a></td>
|
||||
<td><code>empty</code>, <code>size</code> and (sequenced indices only)
|
||||
<code>resize</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_comparison.cpp"><code>test_comparison.cpp</code></a></td>
|
||||
<td>Comparison between indices.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_composite_key.cpp"><code>test_composite_key.cpp</code></a></td>
|
||||
<td><code>composite_key</code> and <code>composite_key_compare</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_conv_iterators.cpp"><code>test_conv_iterators.cpp</code></a></td>
|
||||
<td>Checks convertibility of non-constant to constant iterators.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_copy_assignment.cpp"><code>test_copy_assignment.cpp</code></a></td>
|
||||
<td>Various forms of assignment: copy, <code>operator =</code>, insertion,
|
||||
(sequenced indices only) <code>assign</code> .
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_hash_ops.cpp"><code>test_hash_ops.cpp</code></a></td>
|
||||
<td>Hashing operations.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_iterators.cpp"><code>test_iterators.cpp</code></a></td>
|
||||
<td>Constant and non-constant iterators and their reverse variants.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_key_extractors.cpp"><code>test_key_extractors.cpp</code></a></td>
|
||||
<td>Covers all use cases of key extractors shipped with the library.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_list_ops.cpp"><code>test_list_ops.cpp</code></a></td>
|
||||
<td>List-like operations particular to sequenced indices.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_modifiers.cpp"><code>test_modifiers.cpp</code></a></td>
|
||||
<td>Checks the family of insertion and erasing operations.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_mpl_ops.cpp"><code>test_mpl_ops.cpp</code></a></td>
|
||||
<td>Metaprogramming manipulations of <code>multi_index_container</code> types.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_observers.cpp"><code>test_observers.cpp</code></a></td>
|
||||
<td>Checks observer member functions of ordered and hashed indices.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_projection.cpp"><code>test_projection.cpp</code></a></td>
|
||||
<td>Projection of iterators among indices.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_range.cpp"><code>test_range.cpp</code></a></td>
|
||||
<td>Exercises the <code>range</code> facility (ordered indices only).</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_safe_mode.cpp"><code>test_safe_mode.cpp</code></a></td>
|
||||
<td>Comprehensive coverage of all conditions checked in safe mode.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_serialization.cpp"><code>test_serialization.cpp</code></a></td>
|
||||
<td>Serialization support.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_set_ops.cpp"><code>test_set_ops.cpp</code></a></td>
|
||||
<td>Set-like operations particular to ordered indices.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_special_list_ops.cpp"><code>test_special_list_ops.cpp</code></a></td>
|
||||
<td>Convenience functions of sequenced indices not present in
|
||||
<code>std::list</code>.</td>
|
||||
</tr>
|
||||
<tr class="odd_tr">
|
||||
<td><a href="../test/test_special_set_ops.cpp"><code>test_special_set_ops.cpp</code></a></td>
|
||||
<td>Checks special lookup operations using compatible sorting criteria.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../test/test_update.cpp"><code>test_update.cpp</code></a></td>
|
||||
<td><code>replace</code>, <code>modify</code> and <code>modify_key</code>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="prev_link"><a href="examples.html"><img src="prev.gif" alt="examples" border="0"><br>
|
||||
Examples
|
||||
</a></div>
|
||||
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
|
||||
Index
|
||||
</a></div>
|
||||
<div class="next_link"><a href="future_work.html"><img src="next.gif" alt="future work" border="0"><br>
|
||||
Future work
|
||||
</a></div><br clear="all" style="clear: all;">
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
<p>Revised July 27th 2005</p>
|
||||
|
||||
<p>© Copyright 2003-2005 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1292
doc/tutorial.html
BIN
doc/up.gif
|
Before Width: | Height: | Size: 853 B |
@@ -1,57 +0,0 @@
|
||||
# Boost.MultiIndex examples Jamfile
|
||||
#
|
||||
# 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.
|
||||
|
||||
subproject libs/multi_index/example ;
|
||||
|
||||
exe basic
|
||||
: basic.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe bimap
|
||||
: bimap.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe complex_structs
|
||||
: complex_structs.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe composite_keys
|
||||
: composite_keys.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe hashed
|
||||
: hashed.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe memfun_key
|
||||
: memfun_key.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe non_default_ctor
|
||||
: non_default_ctor.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe sequenced
|
||||
: sequenced.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
exe serialization
|
||||
: serialization.cpp
|
||||
<lib>../../serialization/build/boost_serialization
|
||||
: <include>$(BOOST_ROOT)
|
||||
std::locale-support
|
||||
;
|
||||
@@ -1,122 +0,0 @@
|
||||
/* Boost.MultiIndex basic example.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* an employee record holds its ID, name and age */
|
||||
|
||||
struct employee
|
||||
{
|
||||
int id;
|
||||
std::string name;
|
||||
int age;
|
||||
|
||||
employee(int id_,std::string name_,int age_):id(id_),name(name_),age(age_){}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,const employee& e)
|
||||
{
|
||||
os<<e.id<<" "<<e.name<<" "<<e.age<<std::endl;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/* tags for accessing the corresponding indices of employee_set */
|
||||
|
||||
struct id{};
|
||||
struct name{};
|
||||
struct age{};
|
||||
|
||||
/* see Compiler specifics: Use of member_offset for info on
|
||||
* BOOST_MULTI_INDEX_MEMBER
|
||||
*/
|
||||
|
||||
/* Define a multi_index_container of employees with following indices:
|
||||
* - a unique index sorted by employee::int,
|
||||
* - a non-unique index sorted by employee::name,
|
||||
* - a non-unique index sorted by employee::age.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
employee,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
|
||||
ordered_non_unique<
|
||||
tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
|
||||
ordered_non_unique<
|
||||
tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >
|
||||
> employee_set;
|
||||
|
||||
template<typename Tag,typename MultiIndexContainer>
|
||||
void print_out_by(
|
||||
const MultiIndexContainer& s,
|
||||
Tag* =0 /* fixes a MSVC++ 6.0 bug with implicit template function parms */
|
||||
)
|
||||
{
|
||||
/* obtain a reference to the index tagged by Tag */
|
||||
|
||||
const typename boost::multi_index::index<MultiIndexContainer,Tag>::type& i=
|
||||
get<Tag>(s);
|
||||
|
||||
typedef typename MultiIndexContainer::value_type value_type;
|
||||
|
||||
/* dump the elements of the index to cout */
|
||||
|
||||
std::copy(i.begin(),i.end(),std::ostream_iterator<value_type>(std::cout));
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
employee_set es;
|
||||
|
||||
es.insert(employee(0,"Joe",31));
|
||||
es.insert(employee(1,"Robert",27));
|
||||
es.insert(employee(2,"John",40));
|
||||
|
||||
/* next insertion will fail, as there is an employee with
|
||||
* the same ID
|
||||
*/
|
||||
|
||||
es.insert(employee(2,"Aristotle",2387));
|
||||
|
||||
es.insert(employee(3,"Albert",20));
|
||||
es.insert(employee(4,"John",57));
|
||||
|
||||
/* list the employees sorted by ID, name and age */
|
||||
|
||||
std::cout<<"by ID"<<std::endl;
|
||||
print_out_by<id>(es);
|
||||
std::cout<<std::endl;
|
||||
|
||||
std::cout<<"by name"<<std::endl;
|
||||
print_out_by<name>(es);
|
||||
std::cout<<std::endl;
|
||||
|
||||
std::cout<<"by age"<<std::endl;
|
||||
print_out_by<age>(es);
|
||||
std::cout<<std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/* Boost.MultiIndex example of a bidirectional map.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* tags for accessing both sides of a bidirectional map */
|
||||
|
||||
struct from{};
|
||||
struct to{};
|
||||
|
||||
/* The class template bidirectional_map wraps the specification
|
||||
* of a bidirectional map based on multi_index_container.
|
||||
*/
|
||||
|
||||
template<typename FromType,typename ToType>
|
||||
struct bidirectional_map
|
||||
{
|
||||
typedef std::pair<FromType,ToType> value_type;
|
||||
|
||||
#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) ||\
|
||||
defined(BOOST_MSVC)&&(BOOST_MSVC<1300) ||\
|
||||
defined(BOOST_INTEL_CXX_VERSION)&&defined(_MSC_VER)&&\
|
||||
(BOOST_INTEL_CXX_VERSION<=700)
|
||||
|
||||
/* see Compiler specifics: Use of member_offset for info on member<> and
|
||||
* member_offset<>
|
||||
*/
|
||||
|
||||
BOOST_STATIC_CONSTANT(unsigned,from_offset=offsetof(value_type,first));
|
||||
BOOST_STATIC_CONSTANT(unsigned,to_offset =offsetof(value_type,second));
|
||||
|
||||
typedef multi_index_container<
|
||||
value_type,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
tag<from>,member_offset<value_type,FromType,from_offset> >,
|
||||
ordered_unique<
|
||||
tag<to>, member_offset<value_type,ToType,to_offset> >
|
||||
>
|
||||
> type;
|
||||
|
||||
#else
|
||||
|
||||
/* A bidirectional map can be simulated as a multi_index_container
|
||||
* of pairs of (FromType,ToType) with two unique indices, one
|
||||
* for each member of the pair.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
value_type,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
tag<from>,member<value_type,FromType,&value_type::first> >,
|
||||
ordered_unique<
|
||||
tag<to>, member<value_type,ToType,&value_type::second> >
|
||||
>
|
||||
> type;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
/* a dictionary is a bidirectional map from strings to strings */
|
||||
|
||||
typedef bidirectional_map<std::string,std::string>::type dictionary;
|
||||
|
||||
int main()
|
||||
{
|
||||
dictionary d;
|
||||
|
||||
/* Fill up our microdictionary. first members Spanish, second members
|
||||
* English.
|
||||
*/
|
||||
|
||||
d.insert(dictionary::value_type("hola","hello"));
|
||||
d.insert(dictionary::value_type("adios","goodbye"));
|
||||
d.insert(dictionary::value_type("rosa","rose"));
|
||||
d.insert(dictionary::value_type("mesa","table"));
|
||||
|
||||
|
||||
std::cout<<"enter a word"<<std::endl;
|
||||
std::string word;
|
||||
std::getline(std::cin,word);
|
||||
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) /* use global get<> and family instead */
|
||||
|
||||
dictionary::iterator it=get<from>(d).find(word);
|
||||
if(it!=d.end()){
|
||||
std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
|
||||
}
|
||||
else{
|
||||
nth_index_iterator<dictionary,1>::type it2=get<1>(d).find(word);
|
||||
if(it2!=get<1>(d).end()){
|
||||
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
|
||||
}
|
||||
else std::cout<<"No such word in the dictionary"<<std::endl;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* search the queried word on the from index (Spanish) */
|
||||
|
||||
dictionary::iterator it=d.get<from>().find(word);
|
||||
if(it!=d.end()){ /* found */
|
||||
|
||||
/* the second part of the element is the equivalent in English */
|
||||
|
||||
std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
|
||||
}
|
||||
else{
|
||||
/* word not found in Spanish, try our luck in English */
|
||||
|
||||
dictionary::index_iterator<to>::type it2=d.get<to>().find(word);
|
||||
if(it2!=d.get<to>().end()){
|
||||
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
|
||||
}
|
||||
else std::cout<<"No such word in the dictionary"<<std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,315 +0,0 @@
|
||||
/* Boost.MultiIndex example: complex searches and foreign keys.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* This small utility that cascades two key extractors will be
|
||||
* used througout the example.
|
||||
*/
|
||||
|
||||
template<class KeyExtractor1,class KeyExtractor2>
|
||||
struct key_from_key
|
||||
{
|
||||
public:
|
||||
typedef typename KeyExtractor1::result_type result_type;
|
||||
|
||||
key_from_key(
|
||||
const KeyExtractor1& key1_=KeyExtractor1(),
|
||||
const KeyExtractor2& key2_=KeyExtractor2()):
|
||||
key1(key1_),key2(key2_)
|
||||
{}
|
||||
|
||||
template<typename Arg>
|
||||
result_type operator()(Arg& arg)const
|
||||
{
|
||||
return key1(key2(arg));
|
||||
}
|
||||
|
||||
private:
|
||||
KeyExtractor1 key1;
|
||||
KeyExtractor2 key2;
|
||||
};
|
||||
|
||||
/* tags for accessing several indices defined below */
|
||||
|
||||
struct model{};
|
||||
struct manufacturer{};
|
||||
struct price{};
|
||||
|
||||
/* a manufacturer struct just holds the name of the manufacturer */
|
||||
|
||||
struct car_manufacturer
|
||||
{
|
||||
std::string name;
|
||||
|
||||
car_manufacturer(const std::string& name_):name(name_){}
|
||||
};
|
||||
|
||||
/* car_model holds the model of car, its price and a pointer to the
|
||||
* manufacturer. The pointer thing eliminates duplication of the same
|
||||
* data among cars of the same manufacturer.
|
||||
*/
|
||||
|
||||
struct car_model
|
||||
{
|
||||
std::string model;
|
||||
const car_manufacturer* manufacturer;
|
||||
int price;
|
||||
|
||||
car_model(
|
||||
const std::string& model_,const car_manufacturer* manufacturer_,int price_):
|
||||
model(model_),manufacturer(manufacturer_),price(price_)
|
||||
{}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,const car_model& c)
|
||||
{
|
||||
os<<c.manufacturer->name<<" "<<c.model<<" $"<<c.price<<std::endl;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/* see Compiler specifics: Use of member_offset for info on
|
||||
* BOOST_MULTI_INDEX_MEMBER
|
||||
*/
|
||||
|
||||
/* Car manufacturers are stored in a multi_index_container with one single
|
||||
* index on the name member. This is functionally equivalent to an std::set,
|
||||
* though in this latter case we woud have to define a non-default comparison
|
||||
* predicate (with multi_index_container, member<> does the work for us.)
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
car_manufacturer,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
BOOST_MULTI_INDEX_MEMBER(car_manufacturer,std::string,name)
|
||||
>
|
||||
>
|
||||
> car_manufacturer_table;
|
||||
|
||||
/* Define a multi_index_container of car_models with following indices:
|
||||
* - a unique index sorted by car_model::model,
|
||||
* - a non-unique index sorted by car_model::manufacturer; note the
|
||||
* non-standard manufacturer_extractor used.
|
||||
* - a non-unique index sorted by car_model::price.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
car_model,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
tag<model>,BOOST_MULTI_INDEX_MEMBER(car_model,std::string,model)
|
||||
>,
|
||||
ordered_non_unique<
|
||||
tag<manufacturer>,
|
||||
key_from_key<
|
||||
BOOST_MULTI_INDEX_MEMBER(car_manufacturer,const std::string,name),
|
||||
BOOST_MULTI_INDEX_MEMBER(
|
||||
car_model,const car_manufacturer *,manufacturer)
|
||||
>
|
||||
>,
|
||||
ordered_non_unique<
|
||||
tag<price>,BOOST_MULTI_INDEX_MEMBER(car_model,int,price)
|
||||
>
|
||||
>
|
||||
> car_table;
|
||||
|
||||
/* We call a *view* to a multi_index_container storing pointers instead of
|
||||
* actual objects. These views are used in the complex search performed
|
||||
* in the program. Resorting to multi_index of pointers eliminates
|
||||
* unnecessary copying of objects, and provides us with an opportunity
|
||||
* to show how BOOST_MULTI_INDEX_MEMBER can be used with pointer
|
||||
* type elements.
|
||||
* car_table_price_view indexes (pointers to) car_models by price.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
const car_model*,
|
||||
indexed_by<
|
||||
ordered_non_unique<BOOST_MULTI_INDEX_MEMBER(car_model,const int,price)>
|
||||
>
|
||||
> car_table_price_view;
|
||||
|
||||
/* car_table_manufacturer_view indexes (pointers to) car_models by
|
||||
* manufacturer
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
const car_model*,
|
||||
indexed_by<
|
||||
ordered_non_unique<
|
||||
key_from_key<
|
||||
BOOST_MULTI_INDEX_MEMBER(car_manufacturer,const std::string,name),
|
||||
BOOST_MULTI_INDEX_MEMBER(
|
||||
car_model,const car_manufacturer * const,manufacturer)
|
||||
>
|
||||
>
|
||||
>
|
||||
> car_table_manufacturer_view;
|
||||
|
||||
int main()
|
||||
{
|
||||
car_manufacturer_table cmt;
|
||||
|
||||
/* Fill the car_manufacturer table and keep pointers to the
|
||||
* elements inserted.
|
||||
*/
|
||||
|
||||
const car_manufacturer * cadillac=
|
||||
&*(cmt.insert(car_manufacturer("Cadillac")).first);
|
||||
const car_manufacturer * ford =
|
||||
&*(cmt.insert(car_manufacturer("Ford")).first);
|
||||
const car_manufacturer * bmw =
|
||||
&*(cmt.insert(car_manufacturer("BMW")).first);
|
||||
const car_manufacturer * audi =
|
||||
&*(cmt.insert(car_manufacturer("Audi")).first);
|
||||
|
||||
car_table ct;
|
||||
|
||||
/* Fill the car_model_table. We use the previously initialized
|
||||
* pointers to the elements of cmt.
|
||||
*/
|
||||
|
||||
ct.insert(car_model("XLR",cadillac,76200));
|
||||
ct.insert(car_model("SRX",cadillac,38690));
|
||||
ct.insert(car_model("CTS",cadillac,30695));
|
||||
ct.insert(car_model("Escalade",cadillac,54770));
|
||||
ct.insert(car_model("ESV",cadillac,57195));
|
||||
ct.insert(car_model("EXT",cadillac,52045));
|
||||
ct.insert(car_model("Deville",cadillac,45195));
|
||||
ct.insert(car_model("Seville",cadillac,46330));
|
||||
|
||||
ct.insert(car_model("ZX2",ford,15355));
|
||||
ct.insert(car_model("Thunderbird",ford,43995));
|
||||
ct.insert(car_model("Windstar",ford,35510));
|
||||
ct.insert(car_model("Focus",ford,19630));
|
||||
ct.insert(car_model("Taurus",ford,24290));
|
||||
ct.insert(car_model("Mustang",ford,39900));
|
||||
ct.insert(car_model("Crown Victoria",ford,30370));
|
||||
|
||||
ct.insert(car_model("325i",bmw,27800));
|
||||
ct.insert(car_model("545i",bmw,54300));
|
||||
ct.insert(car_model("745i",bmw,68500));
|
||||
ct.insert(car_model("M3 coupe",bmw,46500));
|
||||
ct.insert(car_model("Z4 roadster 3.0i",bmw,40250));
|
||||
ct.insert(car_model("X5 4.4i",bmw,49950));
|
||||
|
||||
ct.insert(car_model("A4 1.8T",audi,25940));
|
||||
ct.insert(car_model("TT Coupe",audi,33940));
|
||||
ct.insert(car_model("A6 3.0",audi,36640));
|
||||
ct.insert(car_model("Allroad quattro 2.7T",audi,40640));
|
||||
ct.insert(car_model("A8 L",audi,69190));
|
||||
|
||||
std::cout<<"enter a car manufacturer"<<std::endl;
|
||||
std::string cm;
|
||||
std::getline(std::cin,cm);
|
||||
|
||||
/* check for manufacturer */
|
||||
|
||||
car_manufacturer_table::iterator icm=cmt.find(cm);
|
||||
|
||||
if(icm==cmt.end()){
|
||||
std::cout<<"no such manufacturer in the table"<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cout<<"enter a minimum price"<<std::endl;
|
||||
int min_price;
|
||||
std::cin>>min_price;
|
||||
std::cout<<"enter a maximum price"<<std::endl;
|
||||
int max_price;
|
||||
std::cin>>max_price;
|
||||
|
||||
{
|
||||
/* method 1 */
|
||||
|
||||
/* find all the cars for the manufacturer given */
|
||||
|
||||
index_iterator<car_table,manufacturer>::type ic0,ic1;
|
||||
boost::tuples::tie(ic0,ic1)=get<manufacturer>(ct).equal_range(cm);
|
||||
|
||||
/* construct a view (indexed by price) with these */
|
||||
|
||||
car_table_price_view ctpv;
|
||||
while(ic0!=ic1){
|
||||
ctpv.insert(&*ic0);
|
||||
++ic0;
|
||||
}
|
||||
|
||||
/* select the cars in the range given */
|
||||
|
||||
car_table_price_view::iterator ictpv0=ctpv.lower_bound(min_price);
|
||||
car_table_price_view::iterator ictpv1=ctpv.upper_bound(max_price);
|
||||
if(ictpv0==ictpv1){
|
||||
std::cout<<"no cars in the range given"<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* list them */
|
||||
|
||||
std::cout<<"listing by method 1"<<std::endl;
|
||||
while(ictpv0!=ictpv1){
|
||||
std::cout<<**ictpv0;
|
||||
++ictpv0;
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
/* method 2 will give the same results */
|
||||
|
||||
/* find the cars in the range given */
|
||||
|
||||
index_iterator<car_table,price>::type ic0,ic1;
|
||||
ic0=get<price>(ct).lower_bound(min_price);
|
||||
ic1=get<price>(ct).upper_bound(max_price);
|
||||
|
||||
/* construct a view with these */
|
||||
|
||||
car_table_manufacturer_view ctmv;
|
||||
while(ic0!=ic1){
|
||||
ctmv.insert(&*ic0);
|
||||
++ic0;
|
||||
}
|
||||
|
||||
/* select the cars with given manufacturer */
|
||||
|
||||
car_table_manufacturer_view::iterator ictmv0,ictmv1;
|
||||
boost::tuples::tie(ictmv0,ictmv1)=ctmv.equal_range(cm);
|
||||
if(ictmv0==ictmv1){
|
||||
std::cout<<"no cars in the range given"<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* list them */
|
||||
|
||||
std::cout<<"listing by method 2"<<std::endl;
|
||||
while(ictmv0!=ictmv1){
|
||||
std::cout<<**ictmv0;
|
||||
++ictmv0;
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,294 +0,0 @@
|
||||
/* Boost.MultiIndex example of composite keys.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/composite_key.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* A file record maintains some info on name and size as well
|
||||
* as a pointer to the directory it belongs (null meaning the root
|
||||
* directory.)
|
||||
*/
|
||||
|
||||
struct file_entry
|
||||
{
|
||||
file_entry(
|
||||
std::string name_,unsigned size_,bool is_dir_,const file_entry* dir_):
|
||||
name(name_),size(size_),is_dir(is_dir_),dir(dir_)
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
unsigned size;
|
||||
bool is_dir;
|
||||
const file_entry* dir;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,const file_entry& f)
|
||||
{
|
||||
os<<f.name<<"\t"<<f.size;
|
||||
if(f.is_dir)os<<"\t <dir>";
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/* A file system is just a multi_index_container of entries with indices on
|
||||
* file and size. These indices are firstly ordered by directory, as commands
|
||||
* work on a current directory basis. Composite keys are just fine to model
|
||||
* this.
|
||||
* NB: The use of derivation here instead of simple typedef is explained in
|
||||
* Compiler specifics: type hiding.
|
||||
*/
|
||||
|
||||
struct name_key:composite_key<
|
||||
file_entry,
|
||||
BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry*,dir),
|
||||
BOOST_MULTI_INDEX_MEMBER(file_entry,std::string,name)
|
||||
>{};
|
||||
|
||||
struct size_key:composite_key<
|
||||
file_entry,
|
||||
BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry* const,dir),
|
||||
BOOST_MULTI_INDEX_MEMBER(file_entry,unsigned,size)
|
||||
>{};
|
||||
|
||||
/* see Compiler specifics: composite_key in compilers without partial
|
||||
* template specialization, for info on composite_key_result_less
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
file_entry,
|
||||
indexed_by<
|
||||
/* primary index sorted by name (inside the same directory) */
|
||||
ordered_unique<
|
||||
name_key
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
,composite_key_result_less<name_key::result_type>
|
||||
#endif
|
||||
>,
|
||||
/* secondary index sorted by size (inside the same directory) */
|
||||
ordered_non_unique<
|
||||
size_key
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
,composite_key_result_less<size_key::result_type>
|
||||
#endif
|
||||
>
|
||||
>
|
||||
> file_system;
|
||||
|
||||
/* typedef's of the two indices of file_system */
|
||||
|
||||
typedef nth_index<file_system,0>::type file_system_by_name;
|
||||
typedef nth_index<file_system,1>::type file_system_by_size;
|
||||
|
||||
/* We build a rudimentary file system simulation out of some global
|
||||
* info and a map of commands provided to the user.
|
||||
*/
|
||||
|
||||
static file_system fs; /* the one and only file system */
|
||||
static file_system_by_name& fs_by_name=fs; /* name index to fs */
|
||||
static file_system_by_size& fs_by_size=get<1>(fs); /* size index to fs */
|
||||
static const file_entry* current_dir=0; /* root directory */
|
||||
|
||||
/* command framework */
|
||||
|
||||
/* A command provides an execute memfun fed with the corresponding params
|
||||
* (first param is stripped off as it serves to identify the command
|
||||
* currently being used.)
|
||||
*/
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > command_tokenizer;
|
||||
|
||||
class command
|
||||
{
|
||||
public:
|
||||
virtual ~command(){}
|
||||
virtual void execute(
|
||||
command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)=0;
|
||||
};
|
||||
|
||||
/* available commands */
|
||||
|
||||
/* cd: syntax cd [.|..|<directory>] */
|
||||
|
||||
class command_cd:public command
|
||||
{
|
||||
public:
|
||||
virtual void execute(
|
||||
command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)
|
||||
{
|
||||
if(tok1==tok2)return;
|
||||
std::string dir=*tok1++;
|
||||
|
||||
if(dir==".")return;
|
||||
if(dir==".."){
|
||||
if(current_dir)current_dir=current_dir->dir;
|
||||
return;
|
||||
}
|
||||
|
||||
file_system_by_name::iterator it=fs.find(
|
||||
boost::make_tuple(current_dir,dir));
|
||||
if(it==fs.end()){
|
||||
std::cout<<"non-existent directory"<<std::endl;
|
||||
return;
|
||||
}
|
||||
if(!it->is_dir){
|
||||
std::cout<<dir<<" is not a directory"<<std::endl;
|
||||
return;
|
||||
}
|
||||
current_dir=&*it;
|
||||
}
|
||||
};
|
||||
static command_cd cd;
|
||||
|
||||
/* ls: syntax ls [-s] */
|
||||
|
||||
class command_ls:public command
|
||||
{
|
||||
public:
|
||||
virtual void execute(
|
||||
command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)
|
||||
{
|
||||
std::string option;
|
||||
if(tok1!=tok2)option=*tok1++;
|
||||
|
||||
if(!option.empty()){
|
||||
if(option!="-s"){
|
||||
std::cout<<"incorrect parameter"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
/* list by size */
|
||||
|
||||
file_system_by_size::iterator it0,it1;
|
||||
boost::tie(it0,it1)=fs_by_size.equal_range(
|
||||
boost::make_tuple(current_dir));
|
||||
std::copy(it0,it1,std::ostream_iterator<file_entry>(std::cout,"\n"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* list by name */
|
||||
|
||||
file_system_by_name::iterator it0,it1;
|
||||
boost::tie(it0,it1)=fs.equal_range(boost::make_tuple(current_dir));
|
||||
std::copy(it0,it1,std::ostream_iterator<file_entry>(std::cout,"\n"));
|
||||
}
|
||||
};
|
||||
static command_ls ls;
|
||||
|
||||
/* mkdir: syntax mkdir <directory> */
|
||||
|
||||
class command_mkdir:public command
|
||||
{
|
||||
public:
|
||||
virtual void execute(
|
||||
command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)
|
||||
{
|
||||
std::string dir;
|
||||
if(tok1!=tok2)dir=*tok1++;
|
||||
|
||||
if(dir.empty()){
|
||||
std::cout<<"missing parameter"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(dir=="."||dir==".."){
|
||||
std::cout<<"incorrect parameter"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fs.insert(file_entry(dir,0,true,current_dir)).second){
|
||||
std::cout<<"directory already exists"<<std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
static command_mkdir mkdir;
|
||||
|
||||
/* table of commands, a map from command names to class command pointers */
|
||||
|
||||
typedef std::map<std::string,command*> command_table;
|
||||
static command_table cmt;
|
||||
|
||||
int main()
|
||||
{
|
||||
/* fill the file system with some data */
|
||||
|
||||
file_system::iterator it0,it1;
|
||||
|
||||
fs.insert(file_entry("usr.cfg",240,false,0));
|
||||
fs.insert(file_entry("memo.txt",2430,false,0));
|
||||
it0=fs.insert(file_entry("dev",0,true,0)).first;
|
||||
fs.insert(file_entry("tty0",128,false,&*it0));
|
||||
fs.insert(file_entry("tty1",128,false,&*it0));
|
||||
it0=fs.insert(file_entry("usr",0,true,0)).first;
|
||||
it1=fs.insert(file_entry("bin",0,true,&*it0)).first;
|
||||
fs.insert(file_entry("bjam",172032,false,&*it1));
|
||||
it0=fs.insert(file_entry("home",0,true,0)).first;
|
||||
it1=fs.insert(file_entry("andy",0,true,&*it0)).first;
|
||||
fs.insert(file_entry("logo.jpg",5345,false,&*it1)).first;
|
||||
fs.insert(file_entry("foo.cpp",890,false,&*it1)).first;
|
||||
fs.insert(file_entry("foo.hpp",93,false,&*it1)).first;
|
||||
fs.insert(file_entry("foo.html",750,false,&*it1)).first;
|
||||
fs.insert(file_entry("a.obj",12302,false,&*it1)).first;
|
||||
fs.insert(file_entry(".bash_history",8780,false,&*it1)).first;
|
||||
it1=fs.insert(file_entry("rachel",0,true,&*it0)).first;
|
||||
fs.insert(file_entry("test.py",650,false,&*it1)).first;
|
||||
fs.insert(file_entry("todo.txt",241,false,&*it1)).first;
|
||||
fs.insert(file_entry(".bash_history",9510,false,&*it1)).first;
|
||||
|
||||
/* fill the command table */
|
||||
|
||||
cmt["cd"] =&cd;
|
||||
cmt["ls"] =&ls;
|
||||
cmt["mkdir"]=&mkdir;
|
||||
|
||||
/* main looop */
|
||||
|
||||
for(;;){
|
||||
/* print out the current directory and the prompt symbol */
|
||||
|
||||
if(current_dir)std::cout<<current_dir->name;
|
||||
std::cout<<">";
|
||||
|
||||
/* get an input line from the user: if empty, exit the program */
|
||||
|
||||
std::string com;
|
||||
std::getline(std::cin,com);
|
||||
command_tokenizer tok(com,boost::char_separator<char>(" \t\n"));
|
||||
if(tok.begin()==tok.end())break; /* null command, exit */
|
||||
|
||||
/* select the corresponding command and execute it */
|
||||
|
||||
command_table::iterator it=cmt.find(*tok.begin());
|
||||
if(it==cmt.end()){
|
||||
std::cout<<"invalid command"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
it->second->execute(++tok.begin(),tok.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/* Boost.MultiIndex example of use of hashed indices.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* word_counter keeps the ocurrences of words inserted. A hashed
|
||||
* index allows for fast checking of preexisting entries.
|
||||
*/
|
||||
|
||||
struct word_counter_entry
|
||||
{
|
||||
std::string word;
|
||||
unsigned int occurrences;
|
||||
|
||||
word_counter_entry(std::string word_):word(word_),occurrences(0){}
|
||||
};
|
||||
|
||||
/* see Compiler specifics: Use of member_offset for info on
|
||||
* BOOST_MULTI_INDEX_MEMBER
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
word_counter_entry,
|
||||
indexed_by<
|
||||
ordered_non_unique<
|
||||
BOOST_MULTI_INDEX_MEMBER(word_counter_entry,unsigned int,occurrences),
|
||||
std::greater<unsigned int> /* sorted beginning with most frequent */
|
||||
>,
|
||||
hashed_unique<
|
||||
BOOST_MULTI_INDEX_MEMBER(word_counter_entry,std::string,word)
|
||||
>
|
||||
>
|
||||
> word_counter;
|
||||
|
||||
/* utilities */
|
||||
|
||||
template<typename T>
|
||||
struct increment
|
||||
{
|
||||
void operator()(T& x)const{++x;}
|
||||
};
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
|
||||
|
||||
int main()
|
||||
{
|
||||
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 "
|
||||
"antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que "
|
||||
"carnero, salpicón las más noches, duelos y quebrantos los sábados, "
|
||||
"lantejas los viernes, algún palomino de añadidura los domingos, "
|
||||
"consumían las tres partes de su hacienda. El resto della concluían sayo "
|
||||
"de velarte, calzas de velludo para las fiestas, con sus pantuflos de lo "
|
||||
"mesmo, y los días de entresemana se honraba con su vellorí de lo más "
|
||||
"fino. Tenía en su casa una ama que pasaba de los cuarenta, y una "
|
||||
"sobrina que no llegaba a los veinte, y un mozo de campo y plaza, que "
|
||||
"así ensillaba el rocín como tomaba la podadera. Frisaba la edad de "
|
||||
"nuestro hidalgo con los cincuenta años; era de complexión recia, seco "
|
||||
"de carnes, enjuto de rostro, gran madrugador y amigo de la caza. "
|
||||
"Quieren decir que tenía el sobrenombre de Quijada, o Quesada, que en "
|
||||
"esto hay alguna diferencia en los autores que deste caso escriben; "
|
||||
"aunque, por conjeturas verosímiles, se deja entender que se llamaba "
|
||||
"Quejana. Pero esto importa poco a nuestro cuento; basta que en la "
|
||||
"narración dél no se salga un punto de la verdad.";
|
||||
|
||||
/* feed the text into the container */
|
||||
|
||||
word_counter wc;
|
||||
text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
|
||||
unsigned int total_occurrences=0;
|
||||
for(text_tokenizer::iterator it=tok.begin(),it_end=tok.end();
|
||||
it!=it_end;++it){
|
||||
/* Insert the word into the container. If duplicate, wit will point to
|
||||
* the preexistent entry.
|
||||
*/
|
||||
|
||||
++total_occurrences;
|
||||
word_counter::iterator wit=wc.insert(*it).first;
|
||||
|
||||
/* Increment occurrences.
|
||||
* In a lambda-capable compiler, this can be written as:
|
||||
* wc.modify_key(wit,++_1);
|
||||
*/
|
||||
|
||||
wc.modify_key(wit,increment<unsigned int>());
|
||||
}
|
||||
|
||||
/* list words by frequency of appearance */
|
||||
|
||||
std::cout<<std::fixed<<std::setprecision(2);
|
||||
for(word_counter::iterator wit=wc.begin(),wit_end=wc.end();
|
||||
wit!=wit_end;++wit){
|
||||
std::cout<<std::setw(11)<<wit->word<<": "
|
||||
<<std::setw(5) <<100.0*wit->occurrences/total_occurrences<<"%"
|
||||
<<std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Boost.MultiIndex example of member functions used as key extractors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* A name record consists of the given name (e.g. "Charlie")
|
||||
* and the family name (e.g. "Brown"). The full name, calculated
|
||||
* by name_record::name() is laid out in the "phonebook order"
|
||||
* family name + given_name.
|
||||
*/
|
||||
|
||||
struct name_record
|
||||
{
|
||||
name_record(std::string given_name,std::string family_name):
|
||||
given_name(given_name),family_name(family_name)
|
||||
{}
|
||||
|
||||
std::string name()const
|
||||
{
|
||||
std::string str=family_name;
|
||||
str+=" ";
|
||||
str+=given_name;
|
||||
return str;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string given_name;
|
||||
std::string family_name;
|
||||
};
|
||||
|
||||
/* multi_index_container with only one index based on name_record::name().
|
||||
* See Compiler specifics: Use of const_mem_fun_explicit and
|
||||
* mem_fun_explicit for info on BOOST_MULTI_INDEX_CONST_MEM_FUN.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
name_record,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
BOOST_MULTI_INDEX_CONST_MEM_FUN(name_record,std::string,name)
|
||||
>
|
||||
>
|
||||
> name_record_set;
|
||||
|
||||
int main()
|
||||
{
|
||||
name_record_set ns;
|
||||
|
||||
ns.insert(name_record("Joe","Smith"));
|
||||
ns.insert(name_record("Robert","Nightingale"));
|
||||
ns.insert(name_record("Robert","Brown"));
|
||||
ns.insert(name_record("Marc","Tuxedo"));
|
||||
|
||||
/* list the names in ns in phonebook order */
|
||||
|
||||
for(name_record_set::iterator it=ns.begin();it!=ns.end();++it){
|
||||
std::cout<<it->name()<<std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/* Boost.MultiIndex example of use of multi_index_container::ctor_args_list.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* modulo_less order numbers according to their division residual.
|
||||
* For instance, if modulo==10 then 22 is less than 15 as 22%10==2 and
|
||||
* 15%10==5.
|
||||
*/
|
||||
|
||||
template<typename IntegralType>
|
||||
struct modulo_less
|
||||
{
|
||||
modulo_less(IntegralType m):modulo(m){}
|
||||
|
||||
bool operator()(IntegralType x,IntegralType y)const
|
||||
{
|
||||
return (x%modulo)<(y%modulo);
|
||||
}
|
||||
|
||||
private:
|
||||
IntegralType modulo;
|
||||
};
|
||||
|
||||
/* multi_index_container of unsigned ints holding a "natural" index plus
|
||||
* an ordering based on modulo_less.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
unsigned int,
|
||||
indexed_by<
|
||||
ordered_unique<identity<unsigned int> >,
|
||||
ordered_non_unique<identity<unsigned int>, modulo_less<unsigned int> >
|
||||
>
|
||||
> modulo_indexed_set;
|
||||
|
||||
int main()
|
||||
{
|
||||
/* define a modulo_indexed_set with modulo==10 */
|
||||
|
||||
modulo_indexed_set::ctor_args_list args_list=
|
||||
boost::make_tuple(
|
||||
/* ctor_args for index #0 is default constructible */
|
||||
nth_index<modulo_indexed_set,0>::type::ctor_args(),
|
||||
|
||||
/* first parm is key_from_value, second is our sought for key_compare */
|
||||
boost::make_tuple(identity<unsigned int>(),modulo_less<unsigned int>(10))
|
||||
);
|
||||
|
||||
modulo_indexed_set m(args_list);
|
||||
/* this could have be written online without the args_list variable,
|
||||
* left as it is for explanatory purposes. */
|
||||
|
||||
/* insert some numbers */
|
||||
|
||||
unsigned int numbers[]={0,1,20,40,33,68,11,101,60,34,88,230,21,4,7,17};
|
||||
const std::size_t numbers_length(sizeof(numbers)/sizeof(numbers[0]));
|
||||
|
||||
m.insert(&numbers[0],&numbers[numbers_length]);
|
||||
|
||||
/* lists all numbers in order, along with their "equivalence class", that is,
|
||||
* the equivalent numbers under modulo_less
|
||||
*/
|
||||
|
||||
for(modulo_indexed_set::iterator it=m.begin();it!=m.end();++it){
|
||||
std::cout<<*it<<" -> ( ";
|
||||
|
||||
nth_index<modulo_indexed_set,1>::type::iterator it0,it1;
|
||||
boost::tie(it0,it1)=get<1>(m).equal_range(*it);
|
||||
std::copy(it0,it1,std::ostream_iterator<unsigned int>(std::cout," "));
|
||||
|
||||
std::cout<<")"<<std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/* Boost.MultiIndex example of use of sequenced indices.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
#endif
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* text_container holds words as inserted and also keep them indexed
|
||||
* by dictionary order.
|
||||
*/
|
||||
|
||||
typedef multi_index_container<
|
||||
std::string,
|
||||
indexed_by<
|
||||
sequenced<>,
|
||||
ordered_non_unique<identity<std::string> >
|
||||
>
|
||||
> text_container;
|
||||
|
||||
/* ordered index */
|
||||
|
||||
typedef nth_index<text_container,1>::type ordered_text;
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string text=
|
||||
"Alice was beginning to get very tired of sitting by her sister on the "
|
||||
"bank, and of having nothing to do: once or twice she had peeped into the "
|
||||
"book her sister was reading, but it had no pictures or conversations in "
|
||||
"it, 'and what is the use of a book,' thought Alice 'without pictures or "
|
||||
"conversation?'";
|
||||
|
||||
/* feed the text into the container */
|
||||
|
||||
text_container tc;
|
||||
text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
|
||||
std::copy(tok.begin(),tok.end(),std::back_inserter(tc));
|
||||
|
||||
/* list all words in alphabetical order along with their number
|
||||
* of occurrences
|
||||
*/
|
||||
|
||||
ordered_text& ot=get<1>(tc);
|
||||
for(ordered_text::iterator it=ot.begin();it!=ot.end();){
|
||||
std::cout<<std::left<<std::setw(14)<<*it<<":"; /* print the word */
|
||||
ordered_text::iterator it2=ot.upper_bound(*it); /* jump to next */
|
||||
std::cout<<std::right<<std::setw(3) /* and compute the distance */
|
||||
<<std::distance(it,it2)<<" times"<<std::endl;
|
||||
it=it2;
|
||||
}
|
||||
|
||||
/* reverse the text and print it out */
|
||||
|
||||
tc.reverse();
|
||||
std::cout<<std::endl;
|
||||
std::copy(
|
||||
tc.begin(),tc.end(),std::ostream_iterator<std::string>(std::cout," "));
|
||||
std::cout<<std::endl;
|
||||
tc.reverse(); /* undo */
|
||||
|
||||
/* delete most common English words and print the result */
|
||||
|
||||
std::string common_words[]=
|
||||
{"the","of","and","a","to","in","is","you","that","it",
|
||||
"he","for","was","on","are","as","with","his","they","at"};
|
||||
|
||||
for(std::size_t n=0;n<sizeof(common_words)/sizeof(common_words[0]);++n){
|
||||
ot.erase(common_words[n]);
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
std::copy(
|
||||
tc.begin(),tc.end(),std::ostream_iterator<std::string>(std::cout," "));
|
||||
std::cout<<std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/* Boost.MultiIndex example of serialization of a MRU list.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* An MRU (most recently used) list keeps record of the last n
|
||||
* inserted items, listing first the newer ones. Care has to be
|
||||
* taken when a duplicate item is inserted: instead of letting it
|
||||
* appear twice, the MRU list relocates it to the first position.
|
||||
*/
|
||||
|
||||
template <typename Item>
|
||||
class mru_list
|
||||
{
|
||||
typedef multi_index_container<
|
||||
Item,
|
||||
indexed_by<
|
||||
sequenced<>,
|
||||
hashed_unique<identity<Item> >
|
||||
>
|
||||
> item_list;
|
||||
|
||||
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){}
|
||||
|
||||
void insert(const item_type& item)
|
||||
{
|
||||
std::pair<iterator,bool> p=il.push_front(item);
|
||||
|
||||
if(!p.second){ /* duplicate item */
|
||||
il.relocate(il.begin(),p.first); /* put in front */
|
||||
}
|
||||
else if(il.size()>max_num_items){ /* keep the length <= max_num_items */
|
||||
il.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
iterator begin(){return il.begin();}
|
||||
iterator end(){return il.end();}
|
||||
|
||||
/* Utilities to save and load the MRU list, internally
|
||||
* based on Boost.Serialization.
|
||||
*/
|
||||
|
||||
void save_to_file(const char* file_name)const
|
||||
{
|
||||
std::ofstream ofs(file_name);
|
||||
boost::archive::text_oarchive oa(ofs);
|
||||
oa<<boost::serialization::make_nvp("mru",*this);
|
||||
}
|
||||
|
||||
void load_from_file(const char* file_name)
|
||||
{
|
||||
std::ifstream ifs(file_name);
|
||||
if(ifs){
|
||||
boost::archive::text_iarchive ia(ifs);
|
||||
ia>>boost::serialization::make_nvp("mru",*this);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
item_list il;
|
||||
std::size_t max_num_items;
|
||||
|
||||
/* serialization support */
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,const unsigned int)
|
||||
{
|
||||
ar&BOOST_SERIALIZATION_NVP(il);
|
||||
ar&BOOST_SERIALIZATION_NVP(max_num_items);
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
const char* mru_store="mru_store";
|
||||
|
||||
/* Construct a MRU limited to 10 items and retrieve its
|
||||
* previous contents.
|
||||
*/
|
||||
|
||||
mru_list<std::string> mru(10);
|
||||
mru.load_from_file(mru_store);
|
||||
|
||||
/* main loop */
|
||||
|
||||
for(;;){
|
||||
std::cout<<"enter a term: ";
|
||||
|
||||
std::string line;
|
||||
std::getline(std::cin,line);
|
||||
if(line.empty())break;
|
||||
|
||||
std::string term;
|
||||
std::istringstream iss(line);
|
||||
iss>>term;
|
||||
if(term.empty())break;
|
||||
|
||||
mru.insert(term);
|
||||
|
||||
std::cout<<"most recently entered terms:"<<std::endl;
|
||||
std::copy(
|
||||
mru.begin(),mru.end(),
|
||||
std::ostream_iterator<std::string>(std::cout,"\n"));
|
||||
}
|
||||
|
||||
/* persist the MRU list */
|
||||
|
||||
mru.save_to_file(mru_store);
|
||||
|
||||
return 0;
|
||||
}
|
||||
20
index.html
@@ -1,20 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
|
||||
<!--
|
||||
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)
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<meta http-equiv="refresh" content="0; URL=doc/index.html">
|
||||
<title>Boost.MultiIndex Documentation</title>
|
||||
<link rel="stylesheet" href="doc/style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="doc/index.html">doc/index.html</a>
|
||||
</body>
|
||||
</html>
|
||||
16
perf/Jamfile
@@ -1,16 +0,0 @@
|
||||
# Boost.MultiIndex performance 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/perf ;
|
||||
|
||||
exe test_perf
|
||||
: test_perf.cpp
|
||||
: <include>$(BOOST_ROOT)
|
||||
: release
|
||||
;
|
||||
@@ -1,560 +0,0 @@
|
||||
/* Boost.MultiIndex performance test.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <climits>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
/* Measurement harness by Andrew Koenig, extracted from companion code to
|
||||
* Stroustrup, B.: "Wrapping C++ Member Function Calls", The C++ Report,
|
||||
* June 2000, Vol 12/No 6.
|
||||
* Original code retrievable at: http://www.research.att.com/~bs/wrap_code.cpp
|
||||
*/
|
||||
|
||||
// How many clock units does it take to interrogate the clock?
|
||||
static double clock_overhead()
|
||||
{
|
||||
clock_t k = clock(), start, limit;
|
||||
|
||||
// Wait for the clock to tick
|
||||
do start = clock();
|
||||
while (start == k);
|
||||
|
||||
// interrogate the clock until it has advanced at least a second
|
||||
// (for reasonable accuracy)
|
||||
limit = start + CLOCKS_PER_SEC;
|
||||
|
||||
unsigned long r = 0;
|
||||
while ((k = clock()) < limit)
|
||||
++r;
|
||||
|
||||
return double(k - start) / r;
|
||||
}
|
||||
|
||||
// We'd like the odds to be factor:1 that the result is
|
||||
// within percent% of the median
|
||||
const int factor = 10;
|
||||
const int percent = 20;
|
||||
|
||||
// Measure a function (object) factor*2 times,
|
||||
// appending the measurements to the second argument
|
||||
template<class F>
|
||||
void measure_aux(F f, vector<double>& mv)
|
||||
{
|
||||
static double ovhd = clock_overhead();
|
||||
|
||||
// Ensure we don't reallocate in mid-measurement
|
||||
mv.reserve(mv.size() + factor*2);
|
||||
|
||||
// Wait for the clock to tick
|
||||
clock_t k = clock();
|
||||
clock_t start;
|
||||
|
||||
do start = clock();
|
||||
while (start == k);
|
||||
|
||||
// Do 2*factor measurements
|
||||
for (int i = 2*factor; i; --i) {
|
||||
unsigned long count = 0, limit = 1, tcount = 0;
|
||||
const clock_t clocklimit = start + CLOCKS_PER_SEC/100;
|
||||
clock_t t;
|
||||
|
||||
do {
|
||||
while (count < limit) {
|
||||
f();
|
||||
++count;
|
||||
}
|
||||
limit *= 2;
|
||||
++tcount;
|
||||
} while ((t = clock()) < clocklimit);
|
||||
|
||||
// Wait for the clock to tick again;
|
||||
clock_t t2;
|
||||
do ++tcount;
|
||||
while ((t2 = clock()) == t);
|
||||
|
||||
// Append the measurement to the vector
|
||||
mv.push_back(((t2 - start) - (tcount * ovhd)) / count);
|
||||
|
||||
// Establish a new starting point
|
||||
start = t2;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the number of clock units per iteration
|
||||
// With odds of factor:1, the measurement is within percent% of
|
||||
// the value returned, which is also the median of all measurements.
|
||||
template<class F>
|
||||
double measure(F f)
|
||||
{
|
||||
vector<double> mv;
|
||||
|
||||
int n = 0; // iteration counter
|
||||
do {
|
||||
++n;
|
||||
|
||||
// Try 2*factor measurements
|
||||
measure_aux(f, mv);
|
||||
assert(mv.size() == 2*n*factor);
|
||||
|
||||
// Compute the median. We know the size is even, so we cheat.
|
||||
sort(mv.begin(), mv.end());
|
||||
double median = (mv[n*factor] + mv[n*factor-1])/2;
|
||||
|
||||
// If the extrema are within threshold of the median, we're done
|
||||
if (mv[n] > (median * (100-percent))/100 &&
|
||||
mv[mv.size() - n - 1] < (median * (100+percent))/100)
|
||||
return median;
|
||||
|
||||
} while (mv.size() < factor * 200);
|
||||
|
||||
// Give up!
|
||||
clog << "Help!\n\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* dereferencing compare predicate */
|
||||
|
||||
template <typename Iterator,typename Compare>
|
||||
struct it_compare
|
||||
{
|
||||
bool operator()(const Iterator& x,const Iterator& y)const{return comp(*x,*y);}
|
||||
|
||||
private:
|
||||
Compare comp;
|
||||
};
|
||||
|
||||
/* list_wrapper and multiset_wrapper adapt std::lists and std::multisets
|
||||
* to make them conform to a set-like insert interface which test
|
||||
* routines do assume.
|
||||
*/
|
||||
|
||||
template <typename List>
|
||||
struct list_wrapper:List
|
||||
{
|
||||
typedef typename List::value_type value_type;
|
||||
typedef typename List::iterator iterator;
|
||||
|
||||
pair<iterator,bool> insert(const value_type& v)
|
||||
{
|
||||
List::push_back(v);
|
||||
return pair<iterator,bool>(--List::end(),true);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Multiset>
|
||||
struct multiset_wrapper:Multiset
|
||||
{
|
||||
typedef typename Multiset::value_type value_type;
|
||||
typedef typename Multiset::iterator iterator;
|
||||
|
||||
pair<iterator,bool> insert(const value_type& v)
|
||||
{
|
||||
return pair<iterator,bool>(Multiset::insert(v),true);
|
||||
}
|
||||
};
|
||||
|
||||
/* space comsumption of manual simulations is determined by checking
|
||||
* the node sizes of the containers involved. This cannot be done in a
|
||||
* portable manner, so node_size has to be written on a per stdlibrary
|
||||
* basis. Add your own versions if necessary.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_DINKUMWARE_STDLIB)
|
||||
|
||||
template<typename Container>
|
||||
size_t node_size(const Container&)
|
||||
{
|
||||
return sizeof(*Container().begin()._Mynode());
|
||||
}
|
||||
|
||||
#elif defined(__GLIBCPP__)
|
||||
|
||||
template<typename Container>
|
||||
size_t node_size(const Container&)
|
||||
{
|
||||
typedef typename Container::iterator::_Link_type node_ptr;
|
||||
node_ptr p=0;
|
||||
return sizeof(*p);
|
||||
}
|
||||
|
||||
template<typename Value,typename Allocator>
|
||||
size_t node_size(const list<Value,Allocator>&)
|
||||
{
|
||||
return sizeof(typename list<Value,Allocator>::iterator::_Node);
|
||||
}
|
||||
|
||||
template<typename List>
|
||||
size_t node_size(const list_wrapper<List>&)
|
||||
{
|
||||
return sizeof(typename List::iterator::_Node);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* default version returns 0 by convention */
|
||||
|
||||
template<typename Container>
|
||||
size_t node_size(const Container&)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* mono_container runs the tested routine on multi_index and manual
|
||||
* simulations comprised of one standard container.
|
||||
* bi_container and tri_container run the equivalent routine for manual
|
||||
* compositions of two and three standard containers, respectively.
|
||||
*/
|
||||
|
||||
template <typename Container>
|
||||
struct mono_container
|
||||
{
|
||||
mono_container(int n_):n(n_){}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
typedef typename Container::iterator iterator;
|
||||
|
||||
Container c;
|
||||
|
||||
for(int i=0;i<n;++i)c.insert(i);
|
||||
for(iterator it=c.begin();it!=c.end();)c.erase(it++);
|
||||
}
|
||||
|
||||
static size_t multi_index_node_size()
|
||||
{
|
||||
return sizeof(*Container().begin().get_node());
|
||||
}
|
||||
|
||||
static size_t node_size()
|
||||
{
|
||||
return ::node_size(Container());
|
||||
}
|
||||
|
||||
private:
|
||||
int n;
|
||||
};
|
||||
|
||||
template <typename Container1,typename Container2>
|
||||
struct bi_container
|
||||
{
|
||||
bi_container(int n_):n(n_){}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
typedef typename Container1::iterator iterator1;
|
||||
typedef typename Container2::iterator iterator2;
|
||||
|
||||
Container1 c1;
|
||||
Container2 c2;
|
||||
|
||||
for(int i=0;i<n;++i){
|
||||
iterator1 it1=c1.insert(i).first;
|
||||
c2.insert(it1);
|
||||
}
|
||||
for(iterator2 it2=c2.begin();it2!=c2.end();)
|
||||
{
|
||||
c1.erase(*it2);
|
||||
c2.erase(it2++);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t node_size()
|
||||
{
|
||||
return ::node_size(Container1())+::node_size(Container2());
|
||||
}
|
||||
|
||||
private:
|
||||
int n;
|
||||
};
|
||||
|
||||
template <typename Container1,typename Container2,typename Container3>
|
||||
struct tri_container
|
||||
{
|
||||
tri_container(int n_):n(n_){}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
typedef typename Container1::iterator iterator1;
|
||||
typedef typename Container2::iterator iterator2;
|
||||
typedef typename Container3::iterator iterator3;
|
||||
|
||||
Container1 c1;
|
||||
Container2 c2;
|
||||
Container3 c3;
|
||||
|
||||
for(int i=0;i<n;++i){
|
||||
iterator1 it1=c1.insert(i).first;
|
||||
iterator2 it2=c2.insert(it1).first;
|
||||
c3.insert(it2);
|
||||
}
|
||||
for(iterator3 it3=c3.begin();it3!=c3.end();)
|
||||
{
|
||||
c1.erase(**it3);
|
||||
c2.erase(*it3);
|
||||
c3.erase(it3++);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t node_size()
|
||||
{
|
||||
return ::node_size(Container1())+
|
||||
::node_size(Container2())+::node_size(Container3());
|
||||
}
|
||||
|
||||
private:
|
||||
int n;
|
||||
};
|
||||
|
||||
/* measure and compare two routines for several numbers of elements
|
||||
* and also estimates relative memory consumption.
|
||||
*/
|
||||
|
||||
template <typename IndexedTest,typename ManualTest>
|
||||
void run_tests(
|
||||
const char* title
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(IndexedTest)
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualTest))
|
||||
{
|
||||
cout<<fixed<<setprecision(2);
|
||||
cout<<title<<endl;
|
||||
int n=1000;
|
||||
for(int i=0;i<3;++i){
|
||||
double indexed_t=measure(IndexedTest(n));
|
||||
double manual_t=measure(ManualTest(n));
|
||||
cout<<" 10^"<<i+3<<" elmts: "
|
||||
<<setw(6)<<100.0*indexed_t/manual_t<<"% "
|
||||
<<"("
|
||||
<<setw(6)<<1000.0*indexed_t/CLOCKS_PER_SEC<<" ms / "
|
||||
<<setw(6)<<1000.0*manual_t/CLOCKS_PER_SEC<<" ms)"
|
||||
<<endl;
|
||||
n*=10;
|
||||
}
|
||||
|
||||
size_t indexed_t_node_size=IndexedTest::multi_index_node_size();
|
||||
size_t manual_t_node_size=ManualTest::node_size();
|
||||
|
||||
if(manual_t_node_size){
|
||||
cout<<" space gain: "
|
||||
<<setw(6)<<100.0*indexed_t_node_size/manual_t_node_size<<"%"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* compare_structures accept a multi_index_container instantiation and
|
||||
* several standard containers, builds a manual simulation out of the
|
||||
* latter and run the tests.
|
||||
*/
|
||||
|
||||
template <typename IndexedType,typename ManualType>
|
||||
void compare_structures(
|
||||
const char* title
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(IndexedType)
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType))
|
||||
{
|
||||
run_tests<
|
||||
mono_container<IndexedType>,
|
||||
mono_container<ManualType>
|
||||
>(title);
|
||||
}
|
||||
|
||||
template <typename IndexedType,typename ManualType1,typename ManualType2>
|
||||
void compare_structures2(
|
||||
const char* title
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(IndexedType)
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType1)
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType2))
|
||||
{
|
||||
run_tests<
|
||||
mono_container<IndexedType>,
|
||||
bi_container<ManualType1,ManualType2>
|
||||
>(title);
|
||||
}
|
||||
|
||||
template <
|
||||
typename IndexedType,
|
||||
typename ManualType1,typename ManualType2,typename ManualType3
|
||||
>
|
||||
void compare_structures3(
|
||||
const char* title
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(IndexedType)
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType1)
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType2)
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType3))
|
||||
{
|
||||
run_tests<
|
||||
mono_container<IndexedType>,
|
||||
tri_container<ManualType1,ManualType2,ManualType3>
|
||||
>(title);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
/* 1 ordered index */
|
||||
|
||||
typedef multi_index_container<int> indexed_t;
|
||||
typedef set<int> manual_t;
|
||||
indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */
|
||||
|
||||
compare_structures<indexed_t,manual_t>(
|
||||
"1 ordered index");
|
||||
}
|
||||
{
|
||||
/* 1 sequenced index */
|
||||
|
||||
typedef list_wrapper<
|
||||
multi_index_container<
|
||||
int,
|
||||
indexed_by<sequenced<> >
|
||||
>
|
||||
> indexed_t;
|
||||
typedef list_wrapper<list<int> > manual_t;
|
||||
indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */
|
||||
|
||||
compare_structures<indexed_t,manual_t>(
|
||||
"1 sequenced index");
|
||||
}
|
||||
{
|
||||
/* 2 ordered indices */
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
ordered_unique<identity<int> >,
|
||||
ordered_non_unique<identity<int> >
|
||||
>
|
||||
> indexed_t;
|
||||
typedef set<int> manual_t1;
|
||||
typedef multiset<
|
||||
manual_t1::iterator,
|
||||
it_compare<
|
||||
manual_t1::iterator,
|
||||
manual_t1::key_compare
|
||||
>
|
||||
> manual_t2;
|
||||
indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */
|
||||
|
||||
compare_structures2<indexed_t,manual_t1,manual_t2>(
|
||||
"2 ordered indices");
|
||||
}
|
||||
{
|
||||
/* 1 ordered index + 1 sequenced index */
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
boost::multi_index::ordered_unique<identity<int> >,
|
||||
sequenced<>
|
||||
>
|
||||
> indexed_t;
|
||||
typedef list_wrapper<
|
||||
list<int>
|
||||
> manual_t1;
|
||||
typedef multiset<
|
||||
manual_t1::iterator,
|
||||
it_compare<
|
||||
manual_t1::iterator,
|
||||
std::less<int>
|
||||
>
|
||||
> manual_t2;
|
||||
indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */
|
||||
|
||||
compare_structures2<indexed_t,manual_t1,manual_t2>(
|
||||
"1 ordered index + 1 sequenced index");
|
||||
}
|
||||
{
|
||||
/* 3 ordered indices */
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
ordered_unique<identity<int> >,
|
||||
ordered_non_unique<identity<int> >,
|
||||
ordered_non_unique<identity<int> >
|
||||
>
|
||||
> indexed_t;
|
||||
typedef set<int> manual_t1;
|
||||
typedef multiset_wrapper<
|
||||
multiset<
|
||||
manual_t1::iterator,
|
||||
it_compare<
|
||||
manual_t1::iterator,
|
||||
manual_t1::key_compare
|
||||
>
|
||||
>
|
||||
> manual_t2;
|
||||
typedef multiset<
|
||||
manual_t2::iterator,
|
||||
it_compare<
|
||||
manual_t2::iterator,
|
||||
manual_t2::key_compare
|
||||
>
|
||||
> manual_t3;
|
||||
indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */
|
||||
|
||||
compare_structures3<indexed_t,manual_t1,manual_t2,manual_t3>(
|
||||
"3 ordered indices");
|
||||
}
|
||||
{
|
||||
/* 2 ordered indices + 1 sequenced index */
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
ordered_unique<identity<int> >,
|
||||
ordered_non_unique<identity<int> >,
|
||||
sequenced<>
|
||||
>
|
||||
> indexed_t;
|
||||
typedef list_wrapper<
|
||||
list<int>
|
||||
> manual_t1;
|
||||
typedef multiset_wrapper<
|
||||
multiset<
|
||||
manual_t1::iterator,
|
||||
it_compare<
|
||||
manual_t1::iterator,
|
||||
std::less<int>
|
||||
>
|
||||
>
|
||||
> manual_t2;
|
||||
typedef multiset<
|
||||
manual_t2::iterator,
|
||||
it_compare<
|
||||
manual_t2::iterator,
|
||||
manual_t2::key_compare
|
||||
>
|
||||
> manual_t3;
|
||||
indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */
|
||||
|
||||
compare_structures3<indexed_t,manual_t1,manual_t2,manual_t3>(
|
||||
"2 ordered indices + 1 sequenced index");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
79
test/Jamfile
@@ -1,79 +0,0 @@
|
||||
# Boost.MultiIndex tests Jamfile
|
||||
#
|
||||
# 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.
|
||||
|
||||
subproject libs/multi_index/test ;
|
||||
|
||||
# bring in rules for testing
|
||||
|
||||
import testing ;
|
||||
|
||||
local rule special-requirements ( toolset variant : properties * )
|
||||
{
|
||||
# GCC on Tru64 has problems with long debug symbols generated by
|
||||
# Boost.MultiIndex, so we turn them off when in that platform
|
||||
|
||||
if $(UNIX) && $(OS) = OSF
|
||||
{
|
||||
switch $(toolset)
|
||||
{
|
||||
case gcc* : properties =
|
||||
[ replace-properties $(properties) : <debug-symbols>off ] ;
|
||||
}
|
||||
}
|
||||
|
||||
return $(properties) ;
|
||||
}
|
||||
|
||||
# local specialization of rule run automatically including special requirements
|
||||
|
||||
local rule local-run ( sources + : args * : input-files * : requirements *
|
||||
: name ? : default-build * : args2 * )
|
||||
{
|
||||
return [ run $(sources) : $(args) : $(input-files)
|
||||
: $(requirements) special-requirements
|
||||
: $(name) : $(default-build) : $(args2) ] ;
|
||||
}
|
||||
|
||||
# make tests run by default
|
||||
|
||||
DEPENDS all : test ;
|
||||
|
||||
# bring in Boost.Serialization rules
|
||||
|
||||
import ../../../libs/serialization/build/serialization ;
|
||||
|
||||
{
|
||||
test-suite "multi_index"
|
||||
: [ local-run test_basic.cpp test_basic_main.cpp ]
|
||||
: [ local-run test_capacity.cpp test_capacity_main.cpp ]
|
||||
: [ local-run test_comparison.cpp test_comparison_main.cpp ]
|
||||
: [ local-run test_composite_key.cpp test_composite_key_main.cpp ]
|
||||
: [ local-run test_conv_iterators.cpp test_conv_iterators_main.cpp ]
|
||||
: [ local-run test_copy_assignment.cpp test_copy_assignment_main.cpp ]
|
||||
: [ local-run test_hash_ops.cpp test_hash_ops_main.cpp ]
|
||||
: [ local-run test_iterators.cpp test_iterators_main.cpp ]
|
||||
: [ local-run test_key_extractors.cpp test_key_extractors_main.cpp ]
|
||||
: [ local-run test_list_ops.cpp test_list_ops_main.cpp ]
|
||||
: [ local-run test_modifiers.cpp test_modifiers_main.cpp ]
|
||||
: [ local-run test_mpl_ops.cpp test_mpl_ops_main.cpp ]
|
||||
: [ local-run test_observers.cpp test_observers_main.cpp ]
|
||||
: [ local-run test_projection.cpp test_projection_main.cpp ]
|
||||
: [ local-run test_range.cpp test_range_main.cpp ]
|
||||
: [ local-run test_safe_mode.cpp test_safe_mode_main.cpp ]
|
||||
: [ local-run test_serialization.cpp test_serialization_main.cpp
|
||||
<lib>../../serialization/build/boost_serialization
|
||||
: # args
|
||||
: # input files
|
||||
: std::locale-support toolset::require-boost-spirit-support ]
|
||||
: [ local-run test_set_ops.cpp test_set_ops_main.cpp ]
|
||||
: [ local-run test_special_list_ops.cpp test_special_list_ops_main.cpp ]
|
||||
: [ local-run test_special_set_ops.cpp test_special_set_ops_main.cpp ]
|
||||
: [ local-run test_update.cpp test_update_main.cpp ]
|
||||
;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
# Boost.MultiIndex 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.
|
||||
|
||||
test-suite "multi_index" :
|
||||
[ run test_basic.cpp test_basic_main.cpp ]
|
||||
[ run test_capacity.cpp test_capacity_main.cpp ]
|
||||
[ run test_comparison.cpp test_comparison_main.cpp ]
|
||||
[ run test_composite_key.cpp test_composite_key_main.cpp ]
|
||||
[ run test_conv_iterators.cpp test_conv_iterators_main.cpp ]
|
||||
[ run test_copy_assignment.cpp test_copy_assignment_main.cpp ]
|
||||
[ run test_hash_ops.cpp test_hash_ops_main.cpp ]
|
||||
[ run test_iterators.cpp test_iterators_main.cpp ]
|
||||
[ run test_key_extractors.cpp test_key_extractors_main.cpp ]
|
||||
[ run test_list_ops.cpp test_list_ops_main.cpp ]
|
||||
[ run test_modifiers.cpp test_modifiers_main.cpp ]
|
||||
[ run test_mpl_ops.cpp test_mpl_ops_main.cpp ]
|
||||
[ run test_observers.cpp test_observers_main.cpp ]
|
||||
[ run test_projection.cpp test_projection_main.cpp ]
|
||||
[ run test_range.cpp test_range_main.cpp ]
|
||||
[ run test_safe_mode.cpp test_safe_mode_main.cpp ]
|
||||
[ run test_serialization.cpp test_serialization_main.cpp
|
||||
/boost/serialization//boost_serialization ]
|
||||
[ run test_set_ops.cpp test_set_ops_main.cpp ]
|
||||
[ run test_special_list_ops.cpp test_special_list_ops_main.cpp ]
|
||||
[ run test_special_set_ops.cpp test_special_set_ops_main.cpp ]
|
||||
[ run test_update.cpp test_update_main.cpp ]
|
||||
;
|
||||
@@ -1,103 +0,0 @@
|
||||
/* Used in Boost.MultiIndex tests.
|
||||
*
|
||||
* 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_TEST_EMPLOYEE_HPP
|
||||
#define BOOST_MULTI_INDEX_TEST_EMPLOYEE_HPP
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
struct employee
|
||||
{
|
||||
int id;
|
||||
std::string name;
|
||||
int age;
|
||||
int ssn;
|
||||
|
||||
employee(int id_,std::string name_,int age_,int ssn_):
|
||||
id(id_),name(name_),age(age_),ssn(ssn_)
|
||||
{}
|
||||
|
||||
bool operator==(const employee& x)const
|
||||
{
|
||||
return id==x.id&&name==x.name&&age==x.age;
|
||||
}
|
||||
|
||||
bool operator<(const employee& x)const
|
||||
{
|
||||
return id<x.id;
|
||||
}
|
||||
|
||||
bool operator!=(const employee& x)const{return !(*this==x);}
|
||||
bool operator> (const employee& x)const{return x<*this;}
|
||||
bool operator>=(const employee& x)const{return !(*this<x);}
|
||||
bool operator<=(const employee& x)const{return !(x<*this);}
|
||||
|
||||
struct comp_id
|
||||
{
|
||||
bool operator()(int x,const employee& e2)const{return x<e2.id;}
|
||||
bool operator()(const employee& e1,int x)const{return e1.id<x;}
|
||||
};
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,const employee& e)
|
||||
{
|
||||
os<<e.id<<" "<<e.name<<" "<<e.age<<std::endl;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
struct name{};
|
||||
struct by_name{};
|
||||
struct age{};
|
||||
struct as_inserted{};
|
||||
struct ssn{};
|
||||
|
||||
typedef
|
||||
boost::multi_index::multi_index_container<
|
||||
employee,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_unique<
|
||||
boost::multi_index::identity<employee> >,
|
||||
boost::multi_index::hashed_non_unique<
|
||||
boost::multi_index::tag<name,by_name>,
|
||||
BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
|
||||
boost::multi_index::ordered_non_unique<
|
||||
boost::multi_index::tag<age>,
|
||||
BOOST_MULTI_INDEX_MEMBER(employee,int,age)>,
|
||||
boost::multi_index::sequenced<
|
||||
boost::multi_index::tag<as_inserted> >,
|
||||
boost::multi_index::hashed_unique<
|
||||
boost::multi_index::tag<ssn>,
|
||||
BOOST_MULTI_INDEX_MEMBER(employee,int,ssn)> > >
|
||||
employee_set;
|
||||
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
typedef boost::multi_index::nth_index<
|
||||
employee_set,1>::type employee_set_by_name;
|
||||
#else
|
||||
typedef employee_set::nth_index<1>::type employee_set_by_name;
|
||||
#endif
|
||||
|
||||
typedef boost::multi_index::index<
|
||||
employee_set,age>::type employee_set_by_age;
|
||||
typedef boost::multi_index::index<
|
||||
employee_set,as_inserted>::type employee_set_as_inserted;
|
||||
typedef boost::multi_index::index<
|
||||
employee_set,ssn>::type employee_set_by_ssn;
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
/* Used in Boost.MultiIndex tests.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_TEST_PAIR_OF_INTS_HPP
|
||||
#define BOOST_MULTI_INDEX_TEST_PAIR_OF_INTS_HPP
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <utility>
|
||||
|
||||
typedef std::pair<int,int> pair_of_ints;
|
||||
|
||||
inline void increment_first(pair_of_ints& p)
|
||||
{
|
||||
++p.first;
|
||||
}
|
||||
|
||||
inline void increment_second(pair_of_ints& p)
|
||||
{
|
||||
++p.second;
|
||||
}
|
||||
|
||||
inline void increment_int(int& x)
|
||||
{
|
||||
++x;
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
namespace boost{
|
||||
namespace serialization{
|
||||
#else
|
||||
namespace std{
|
||||
#endif
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,pair_of_ints& p,const unsigned int)
|
||||
{
|
||||
ar&boost::serialization::make_nvp("first",p.first);
|
||||
ar&boost::serialization::make_nvp("second",p.second);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
} /* namespace serialization */
|
||||
} /* namespace boost*/
|
||||
#else
|
||||
} /* namespace std */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
/* Used in Boost.MultiIndex tests.
|
||||
*
|
||||
* 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_TEST_PRE_MULTI_INDEX_HPP
|
||||
#define BOOST_MULTI_INDEX_TEST_PRE_MULTI_INDEX_HPP
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/multi_index/safe_mode_errors.hpp>
|
||||
|
||||
#if defined(__GNUC__)&&defined(__APPLE__)&&\
|
||||
(__GNUC__==4)&&(__GNUC_MINOR__==0)&&(__APPLE_CC__<=4061)
|
||||
/* Darwin 8.1 includes a prerelease version of GCC 4.0 that, alas,
|
||||
* has a regression as described in
|
||||
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17435
|
||||
* This compiler bug (fixed in the official 4.0 release) ruins the
|
||||
* mechanisms upon which invariant-checking scope guards are built,
|
||||
* so we can't set the invariant checking mode.
|
||||
*/
|
||||
#else
|
||||
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
||||
#endif
|
||||
|
||||
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
||||
|
||||
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
|
||||
#pragma info(nolan) /* suppress warnings about offsetof with non-POD types */
|
||||
#endif
|
||||
|
||||
struct safe_mode_exception
|
||||
{
|
||||
safe_mode_exception(boost::multi_index::safe_mode::error_code error_code_):
|
||||
error_code(error_code_)
|
||||
{}
|
||||
|
||||
boost::multi_index::safe_mode::error_code error_code;
|
||||
};
|
||||
|
||||
#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) \
|
||||
if(!(expr)){throw safe_mode_exception(error_code);}
|
||||
|
||||
#endif
|
||||
@@ -1,59 +0,0 @@
|
||||
/* Boost.MultiIndex test suite.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_basic.hpp"
|
||||
#include "test_capacity.hpp"
|
||||
#include "test_comparison.hpp"
|
||||
#include "test_composite_key.hpp"
|
||||
#include "test_conv_iterators.hpp"
|
||||
#include "test_copy_assignment.hpp"
|
||||
#include "test_hash_ops.hpp"
|
||||
#include "test_iterators.hpp"
|
||||
#include "test_key_extractors.hpp"
|
||||
#include "test_list_ops.hpp"
|
||||
#include "test_modifiers.hpp"
|
||||
#include "test_mpl_ops.hpp"
|
||||
#include "test_observers.hpp"
|
||||
#include "test_projection.hpp"
|
||||
#include "test_range.hpp"
|
||||
#include "test_safe_mode.hpp"
|
||||
#include "test_serialization.hpp"
|
||||
#include "test_set_ops.hpp"
|
||||
#include "test_special_list_ops.hpp"
|
||||
#include "test_special_set_ops.hpp"
|
||||
#include "test_update.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_basic();
|
||||
test_capacity();
|
||||
test_comparison();
|
||||
test_composite_key();
|
||||
test_conv_iterators();
|
||||
test_copy_assignment();
|
||||
test_hash_ops();
|
||||
test_iterators();
|
||||
test_key_extractors();
|
||||
test_list_ops();
|
||||
test_modifiers();
|
||||
test_mpl_ops();
|
||||
test_observers();
|
||||
test_projection();
|
||||
test_range();
|
||||
test_safe_mode();
|
||||
test_serialization();
|
||||
test_set_ops();
|
||||
test_special_list_ops();
|
||||
test_special_set_ops();
|
||||
test_update();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Boost.MultiIndex basic test.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_basic.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
struct less_by_employee_age
|
||||
{
|
||||
bool operator()(const employee& e1,const employee& e2)const
|
||||
{
|
||||
return e1.age<e2.age;
|
||||
}
|
||||
};
|
||||
|
||||
void test_basic()
|
||||
{
|
||||
employee_set es;
|
||||
std::vector<employee> v;
|
||||
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
employee_set_by_name& i1=get<by_name>(es);
|
||||
#else
|
||||
employee_set_by_name& i1=es.get<by_name>();
|
||||
#endif
|
||||
|
||||
const employee_set_by_age& i2=get<2>(es);
|
||||
employee_set_as_inserted& i3=get<3>(es);
|
||||
employee_set_by_ssn& i4=get<ssn>(es);
|
||||
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(5,"Anna",41,1123)); /* clash*/
|
||||
i1.insert(employee(1,"Robert",27,5601));
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
i3.push_back(employee(3,"Albert",20,9012));
|
||||
i4.insert(employee(4,"John",57,1002));
|
||||
i4.insert(employee(0,"Andrew",60,2302)); /* clash */
|
||||
|
||||
v.push_back(employee(0,"Joe",31,1123));
|
||||
v.push_back(employee(1,"Robert",27,5601));
|
||||
v.push_back(employee(2,"John",40,7889));
|
||||
v.push_back(employee(3,"Albert",20,9012));
|
||||
v.push_back(employee(4,"John",57,1002));
|
||||
|
||||
{
|
||||
/* by insertion order */
|
||||
|
||||
BOOST_CHECK(std::equal(i3.begin(),i3.end(),v.begin()));
|
||||
}
|
||||
|
||||
{
|
||||
/* by id */
|
||||
|
||||
std::sort(v.begin(),v.end());
|
||||
BOOST_CHECK(std::equal(es.begin(),es.end(),v.begin()));
|
||||
}
|
||||
|
||||
{
|
||||
/* by age */
|
||||
|
||||
std::sort(v.begin(),v.end(),less_by_employee_age());
|
||||
BOOST_CHECK(std::equal(i2.begin(),i2.end(),v.begin()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex basic test.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_basic();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex basic test.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_basic.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_basic();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/* Boost.MultiIndex test for capacity memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_capacity.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
void test_capacity()
|
||||
{
|
||||
employee_set es;
|
||||
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(1,"Robert",27,5601));
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
es.insert(employee(3,"Albert",20,9012));
|
||||
es.insert(employee(4,"John",57,1002));
|
||||
|
||||
BOOST_CHECK(!es.empty());
|
||||
BOOST_CHECK(es.size()==5);
|
||||
BOOST_CHECK(es.size()<=es.max_size());
|
||||
|
||||
es.erase(es.begin());
|
||||
BOOST_CHECK(!get<name>(es).empty());
|
||||
BOOST_CHECK(get<name>(es).size()==4);
|
||||
BOOST_CHECK(get<name>(es).size()<=get<name>(es).max_size());
|
||||
|
||||
es.erase(es.begin());
|
||||
BOOST_CHECK(!get<as_inserted>(es).empty());
|
||||
BOOST_CHECK(get<as_inserted>(es).size()==3);
|
||||
BOOST_CHECK(get<as_inserted>(es).size()<=get<as_inserted>(es).max_size());
|
||||
|
||||
multi_index_container<int,indexed_by<sequenced<> > > ss;
|
||||
|
||||
ss.resize(10);
|
||||
BOOST_CHECK(ss.size()==10);
|
||||
BOOST_CHECK(ss.size()<=ss.max_size());
|
||||
|
||||
ss.resize(20);
|
||||
BOOST_CHECK(ss.size()==20);
|
||||
|
||||
ss.resize(5);
|
||||
BOOST_CHECK(ss.size()==5);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for capacity memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_capacity();
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Boost.MultiIndex test for capacity memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_capacity.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_capacity();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/* Boost.MultiIndex test for comparison functions.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_comparison.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
template<typename Value>
|
||||
struct lookup_list{
|
||||
typedef multi_index_container<
|
||||
Value,
|
||||
indexed_by<
|
||||
sequenced<>,
|
||||
ordered_non_unique<identity<Value> >
|
||||
>
|
||||
> type;
|
||||
};
|
||||
|
||||
void test_comparison()
|
||||
{
|
||||
employee_set es;
|
||||
employee_set_by_age& i2=get<2>(es);
|
||||
employee_set_as_inserted& i3=get<3>(es);
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(1,"Robert",27,5601));
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
es.insert(employee(3,"Albert",20,9012));
|
||||
es.insert(employee(4,"John",57,1002));
|
||||
|
||||
employee_set es2;
|
||||
employee_set_by_age& i22=get<age>(es2);
|
||||
employee_set_as_inserted& i32=get<3>(es2);
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(1,"Robert",27,5601));
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
es.insert(employee(3,"Albert",20,9012));
|
||||
|
||||
BOOST_CHECK(es==es&&es<=es&&es>=es&&
|
||||
i22==i22&&i22<=i22&&i22>=i22&&
|
||||
i32==i32&&i32<=i32&&i32>=i32);
|
||||
BOOST_CHECK(es!=es2&&es2<es&&es>es2&&!(es<=es2)&&!(es2>=es));
|
||||
BOOST_CHECK(i2!=i22&&i22<i2&&i2>i22&&!(i2<=i22)&&!(i22>=i2));
|
||||
BOOST_CHECK(i3!=i32&&i32<i3&&i3>i32&&!(i3<=i32)&&!(i32>=i3));
|
||||
|
||||
lookup_list<int>::type l1;
|
||||
lookup_list<char>::type l2;
|
||||
lookup_list<long>::type l3;
|
||||
|
||||
l1.push_back(3);
|
||||
l1.push_back(4);
|
||||
l1.push_back(5);
|
||||
l1.push_back(1);
|
||||
l1.push_back(2);
|
||||
|
||||
l2.push_back(char(3));
|
||||
l2.push_back(char(4));
|
||||
l2.push_back(char(5));
|
||||
l2.push_back(char(1));
|
||||
l2.push_back(char(2));
|
||||
|
||||
l3.push_back(long(3));
|
||||
l3.push_back(long(4));
|
||||
l3.push_back(long(5));
|
||||
l3.push_back(long(1));
|
||||
|
||||
BOOST_CHECK(l1==l2&&l1<=l2&&l1>=l2);
|
||||
BOOST_CHECK(
|
||||
get<1>(l1)==get<1>(l2)&&get<1>(l1)<=get<1>(l2)&&get<1>(l1)>=get<1>(l2));
|
||||
BOOST_CHECK(l1!=l3&&l3<l1&&l1>l3);
|
||||
BOOST_CHECK(
|
||||
get<1>(l1)!=get<1>(l3)&&get<1>(l1)<get<1>(l3)&&get<1>(l3)>get<1>(l1));
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for comparison functions.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_comparison();
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Boost.MultiIndex test for comparison functions.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_comparison.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_comparison();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,638 +0,0 @@
|
||||
/* Boost.MultiIndex test for composite_key.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_composite_key.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/composite_key.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
using namespace boost::tuples;
|
||||
|
||||
struct is_composite_key_result_helper
|
||||
{
|
||||
typedef char yes;
|
||||
struct no{char m[2];};
|
||||
|
||||
static no test(void*);
|
||||
|
||||
template<typename CompositeKey>
|
||||
static yes test(composite_key_result<CompositeKey>*);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_composite_key_result
|
||||
{
|
||||
typedef is_composite_key_result_helper helper;
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool,
|
||||
value=(
|
||||
sizeof(helper::test((T*)0))==
|
||||
sizeof(typename helper::yes)));
|
||||
};
|
||||
|
||||
template<typename CompositeKeyResult>
|
||||
struct composite_key_result_length
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int,
|
||||
value=boost::tuples::length<
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
CompositeKeyResult::composite_key_type::key_extractor_tuple
|
||||
>::value);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct composite_object_length
|
||||
{
|
||||
typedef typename boost::mpl::if_c<
|
||||
is_composite_key_result<T>::value,
|
||||
composite_key_result_length<T>,
|
||||
boost::tuples::length<T>
|
||||
>::type type;
|
||||
|
||||
BOOST_STATIC_CONSTANT(int,value=type::value);
|
||||
};
|
||||
|
||||
template<typename CompositeKeyResult,typename T2>
|
||||
struct comparison_equal_length
|
||||
{
|
||||
static bool is_less(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
composite_key_result_equal_to<CompositeKeyResult> eq;
|
||||
composite_key_result_less<CompositeKeyResult> lt;
|
||||
composite_key_result_greater<CompositeKeyResult> gt;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
std::equal_to<CompositeKeyResult> std_eq;
|
||||
std::less<CompositeKeyResult> std_lt;
|
||||
std::greater<CompositeKeyResult> std_gt;
|
||||
#endif
|
||||
|
||||
return (x< y) && !(y< x)&&
|
||||
!(x==y) && !(y==x)&&
|
||||
(x!=y) && (y!=x)&&
|
||||
!(x> y) && (y> x)&&
|
||||
!(x>=y) && (y>=x)&&
|
||||
(x<=y) && !(y<=x)&&
|
||||
|
||||
!eq(x,y) && !eq(y,x)&&
|
||||
lt(x,y) && !lt(y,x)&&
|
||||
!gt(x,y) && gt(y,x)
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
&&
|
||||
!std_eq(x,y) && !std_eq(y,x)&&
|
||||
std_lt(x,y) && !std_lt(y,x)&&
|
||||
!std_gt(x,y) && std_gt(y,x)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
static bool is_greater(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
composite_key_result_equal_to<CompositeKeyResult> eq;
|
||||
composite_key_result_less<CompositeKeyResult> lt;
|
||||
composite_key_result_greater<CompositeKeyResult> gt;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
std::equal_to<CompositeKeyResult> std_eq;
|
||||
std::less<CompositeKeyResult> std_lt;
|
||||
std::greater<CompositeKeyResult> std_gt;
|
||||
#endif
|
||||
|
||||
return !(x< y) && (y< x)&&
|
||||
!(x==y) && !(y==x)&&
|
||||
(x!=y) && (y!=x)&&
|
||||
(x> y) && !(y> x)&&
|
||||
(x>=y) && !(y>=x)&&
|
||||
!(x<=y) && (y<=x)&&
|
||||
|
||||
!eq(x,y) && !eq(y,x)&&
|
||||
!lt(x,y) && lt(y,x)&&
|
||||
gt(x,y) && !gt(y,x)
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
&&
|
||||
!std_eq(x,y) && !std_eq(y,x)&&
|
||||
!std_lt(x,y) && std_lt(y,x)&&
|
||||
std_gt(x,y) && !std_gt(y,x)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
static bool is_equiv(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
composite_key_result_equal_to<CompositeKeyResult> eq;
|
||||
composite_key_result_less<CompositeKeyResult> lt;
|
||||
composite_key_result_greater<CompositeKeyResult> gt;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
std::equal_to<CompositeKeyResult> std_eq;
|
||||
std::less<CompositeKeyResult> std_lt;
|
||||
std::greater<CompositeKeyResult> std_gt;
|
||||
#endif
|
||||
|
||||
return !(x< y) && !(y< x)&&
|
||||
(x==y) && (y==x)&&
|
||||
!(x!=y) && !(y!=x)&&
|
||||
!(x> y) && !(y> x)&&
|
||||
(x>=y) && (y>=x)&&
|
||||
(x<=y) && (y<=x)&&
|
||||
|
||||
eq(x,y) && eq(y,x)&&
|
||||
!lt(x,y) && !lt(y,x)&&
|
||||
!gt(x,y) && !gt(y,x)
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
&&
|
||||
std_eq(x,y) && std_eq(y,x)&&
|
||||
!std_lt(x,y) && !std_lt(y,x)&&
|
||||
!std_gt(x,y) && !std_gt(y,x)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CompositeKeyResult,typename T2>
|
||||
struct comparison_different_length
|
||||
{
|
||||
static bool is_less(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
composite_key_result_less<CompositeKeyResult> lt;
|
||||
composite_key_result_greater<CompositeKeyResult> gt;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
std::less<CompositeKeyResult> std_lt;
|
||||
std::greater<CompositeKeyResult> std_gt;
|
||||
#endif
|
||||
|
||||
return (x< y) && !(y< x)&&
|
||||
!(x> y) && (y> x)&&
|
||||
!(x>=y) && (y>=x)&&
|
||||
(x<=y) && !(y<=x)&&
|
||||
|
||||
lt(x,y) && !lt(y,x)&&
|
||||
!gt(x,y) && gt(y,x)
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
&&
|
||||
std_lt(x,y) && !std_lt(y,x)&&
|
||||
!std_gt(x,y) && std_gt(y,x)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
static bool is_greater(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
composite_key_result_less<CompositeKeyResult> lt;
|
||||
composite_key_result_greater<CompositeKeyResult> gt;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
std::less<CompositeKeyResult> std_lt;
|
||||
std::greater<CompositeKeyResult> std_gt;
|
||||
#endif
|
||||
|
||||
return !(x< y) && (y< x)&&
|
||||
(x> y) && !(y> x)&&
|
||||
(x>=y) && !(y>=x)&&
|
||||
!(x<=y) && (y<=x)&&
|
||||
|
||||
!lt(x,y) && lt(y,x)&&
|
||||
gt(x,y) && !gt(y,x)
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
&&
|
||||
!std_lt(x,y) && std_lt(y,x)&&
|
||||
std_gt(x,y) && !std_gt(y,x)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
static bool is_equiv(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
composite_key_result_less<CompositeKeyResult> lt;
|
||||
composite_key_result_greater<CompositeKeyResult> gt;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
std::less<CompositeKeyResult> std_lt;
|
||||
std::greater<CompositeKeyResult> std_gt;
|
||||
#endif
|
||||
|
||||
return !(x< y) && !(y< x)&&
|
||||
!(x> y) && !(y> x)&&
|
||||
(x>=y) && (y>=x)&&
|
||||
(x<=y) && (y<=x)&&
|
||||
|
||||
!lt(x,y) && !lt(y,x)&&
|
||||
!gt(x,y) && !gt(y,x)
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
&&
|
||||
!std_lt(x,y) && !std_lt(y,x)&&
|
||||
!std_gt(x,y) && !std_gt(y,x)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CompositeKeyResult,typename T2>
|
||||
struct comparison_helper:
|
||||
boost::mpl::if_c<
|
||||
composite_key_result_length<CompositeKeyResult>::value==
|
||||
composite_object_length<T2>::value,
|
||||
comparison_equal_length<CompositeKeyResult,T2>,
|
||||
comparison_different_length<CompositeKeyResult,T2>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template<typename CompositeKeyResult,typename T2>
|
||||
static bool is_less(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
return comparison_helper<CompositeKeyResult,T2>::is_less(x,y);
|
||||
}
|
||||
|
||||
template<typename CompositeKeyResult,typename T2>
|
||||
static bool is_greater(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
return comparison_helper<CompositeKeyResult,T2>::is_greater(x,y);
|
||||
}
|
||||
|
||||
template<typename CompositeKeyResult,typename T2>
|
||||
static bool is_equiv(const CompositeKeyResult& x,const T2& y)
|
||||
{
|
||||
return comparison_helper<CompositeKeyResult,T2>::is_equiv(x,y);
|
||||
}
|
||||
|
||||
template<typename T1,typename T2,typename Compare>
|
||||
static bool is_less(const T1& x,const T2& y,const Compare& c)
|
||||
{
|
||||
return c(x,y)&&!c(y,x);
|
||||
}
|
||||
|
||||
template<typename T1,typename T2,typename Compare>
|
||||
static bool is_greater(const T1& x,const T2& y,const Compare& c)
|
||||
{
|
||||
return c(y,x)&&!c(x,y);
|
||||
}
|
||||
|
||||
template<typename T1,typename T2,typename Compare>
|
||||
static bool is_equiv(const T1& x,const T2& y,const Compare& c)
|
||||
{
|
||||
return !c(x,y)&&!c(y,x);
|
||||
}
|
||||
|
||||
template<typename T1,typename T2,typename Compare,typename Equiv>
|
||||
static bool is_less(
|
||||
const T1& x,const T2& y,const Compare& c,const Equiv& eq)
|
||||
{
|
||||
return c(x,y)&&!c(y,x)&&!eq(x,y)&&!eq(y,x);
|
||||
}
|
||||
|
||||
template<typename T1,typename T2,typename Compare,typename Equiv>
|
||||
static bool is_greater(
|
||||
const T1& x,const T2& y,const Compare& c,const Equiv& eq)
|
||||
{
|
||||
return c(y,x)&&!c(x,y)&&!eq(x,y)&&!eq(y,x);
|
||||
}
|
||||
|
||||
template<typename T1,typename T2,typename Compare,typename Equiv>
|
||||
static bool is_equiv(
|
||||
const T1& x,const T2& y,const Compare& c,const Equiv& eq)
|
||||
{
|
||||
return !c(x,y)&&!c(y,x)&&eq(x,y)&&eq(y,x);
|
||||
}
|
||||
|
||||
struct xyz
|
||||
{
|
||||
xyz(int x_=0,int y_=0,int z_=0):x(x_),y(y_),z(z_){}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
};
|
||||
|
||||
struct modulo_equal
|
||||
{
|
||||
modulo_equal(int i):i_(i){}
|
||||
bool operator ()(int x,int y)const{return (x%i_)==(y%i_);}
|
||||
|
||||
private:
|
||||
int i_;
|
||||
};
|
||||
|
||||
struct xystr
|
||||
{
|
||||
xystr(int x_=0,int y_=0,std::string str_=0):x(x_),y(y_),str(str_){}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
std::string str;
|
||||
};
|
||||
|
||||
void test_composite_key()
|
||||
{
|
||||
typedef composite_key<
|
||||
xyz,
|
||||
BOOST_MULTI_INDEX_MEMBER(xyz,int,x),
|
||||
BOOST_MULTI_INDEX_MEMBER(xyz,int,y),
|
||||
BOOST_MULTI_INDEX_MEMBER(xyz,int,z)
|
||||
> ckey_t1;
|
||||
|
||||
typedef multi_index_container<
|
||||
xyz,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
ckey_t1
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
,composite_key_result_less<ckey_t1::result_type>
|
||||
#endif
|
||||
>
|
||||
>
|
||||
> indexed_t1;
|
||||
|
||||
indexed_t1 mc1;
|
||||
mc1.insert(xyz(0,0,0));
|
||||
mc1.insert(xyz(0,0,1));
|
||||
mc1.insert(xyz(0,1,0));
|
||||
mc1.insert(xyz(0,1,1));
|
||||
mc1.insert(xyz(1,0,0));
|
||||
mc1.insert(xyz(1,0,1));
|
||||
mc1.insert(xyz(1,1,0));
|
||||
mc1.insert(xyz(1,1,1));
|
||||
|
||||
BOOST_CHECK(mc1.size()==8);
|
||||
BOOST_CHECK(
|
||||
std::distance(
|
||||
mc1.find(mc1.key_extractor()(xyz(0,0,0))),
|
||||
mc1.find(mc1.key_extractor()(xyz(1,0,0))))==4);
|
||||
BOOST_CHECK(
|
||||
std::distance(
|
||||
mc1.find(make_tuple(0,0,0)),
|
||||
mc1.find(make_tuple(1,0,0)))==4);
|
||||
BOOST_CHECK(
|
||||
std::distance(
|
||||
mc1.lower_bound(make_tuple(0,0)),
|
||||
mc1.upper_bound(make_tuple(1,0)))==6);
|
||||
|
||||
ckey_t1 ck1;
|
||||
ckey_t1 ck2(ck1);
|
||||
ckey_t1 ck3(
|
||||
boost::make_tuple(
|
||||
BOOST_MULTI_INDEX_MEMBER(xyz,int,x)(),
|
||||
BOOST_MULTI_INDEX_MEMBER(xyz,int,y)(),
|
||||
BOOST_MULTI_INDEX_MEMBER(xyz,int,z)()));
|
||||
ckey_t1 ck4(get<0>(ck1.key_extractors()));
|
||||
|
||||
ck3=ck3; /* prevent unused var */
|
||||
|
||||
get<2>(ck4.key_extractors())=
|
||||
get<2>(ck2.key_extractors());
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0))));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0))));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0))));
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0)));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(1)));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(-1)));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0)));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,1)));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,-1)));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0)));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,0,1)));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,0,-1)));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0,1)));
|
||||
|
||||
typedef composite_key_result_less<ckey_t1::result_type> ckey_comp_t1;
|
||||
typedef composite_key_result_equal_to<ckey_t1::result_type> ckey_eq_t1;
|
||||
|
||||
ckey_comp_t1 cp1;
|
||||
ckey_eq_t1 eq1;
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp1,eq1));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp1,eq1));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp1,eq1));
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0),cp1));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(1),cp1));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(-1),cp1));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0),cp1));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,1),cp1));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,-1),cp1));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0),cp1,eq1));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,0,1),cp1,eq1));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,0,-1),cp1,eq1));
|
||||
|
||||
typedef composite_key_result_greater<ckey_t1::result_type> ckey_comp_t2;
|
||||
|
||||
ckey_comp_t2 cp2;
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp2));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp2));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp2));
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0),cp2));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(1),cp2));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(-1),cp2));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0),cp2));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,1),cp2));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,-1),cp2));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0),cp2));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,0,1),cp2));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,0,-1),cp2));
|
||||
|
||||
typedef composite_key_equal_to<
|
||||
modulo_equal,
|
||||
modulo_equal,
|
||||
std::equal_to<int>,
|
||||
std::equal_to<int>
|
||||
> ckey_eq_t2;
|
||||
|
||||
ckey_eq_t2 eq2(
|
||||
boost::make_tuple(
|
||||
modulo_equal(2),
|
||||
modulo_equal(3),
|
||||
std::equal_to<int>(),
|
||||
std::equal_to<int>()));
|
||||
ckey_eq_t2 eq3(eq2);
|
||||
ckey_eq_t2 eq4(
|
||||
get<0>(eq3.key_eqs()),
|
||||
get<1>(eq3.key_eqs()));
|
||||
|
||||
eq3=eq4; /* prevent unused var */
|
||||
eq4=eq3; /* prevent unused var */
|
||||
|
||||
BOOST_CHECK( eq2(ck1(xyz(0,0,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(0,1,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(0,2,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK( eq2(ck1(xyz(0,3,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(1,0,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(1,1,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(1,2,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(1,3,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK( eq2(ck1(xyz(2,0,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(2,1,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(2,2,0)),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK( eq2(ck1(xyz(2,3,0)),ck1(xyz(0,0,0))));
|
||||
|
||||
BOOST_CHECK( eq2(make_tuple(0,0,0),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(0,1,0)) ,make_tuple(0,0,0)));
|
||||
BOOST_CHECK(!eq2(make_tuple(0,2,0),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK( eq2(ck1(xyz(0,3,0)) ,make_tuple(0,0,0)));
|
||||
BOOST_CHECK(!eq2(make_tuple(1,0,0),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(1,1,0)) ,make_tuple(0,0,0)));
|
||||
BOOST_CHECK(!eq2(make_tuple(1,2,0),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(1,3,0)) ,make_tuple(0,0,0)));
|
||||
BOOST_CHECK( eq2(make_tuple(2,0,0),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK(!eq2(ck1(xyz(2,1,0)) ,make_tuple(0,0,0)));
|
||||
BOOST_CHECK(!eq2(make_tuple(2,2,0),ck1(xyz(0,0,0))));
|
||||
BOOST_CHECK( eq2(ck1(xyz(2,3,0)) ,make_tuple(0,0,0)));
|
||||
|
||||
typedef composite_key_compare<
|
||||
std::less<int>,
|
||||
std::greater<int>, /* order reversed */
|
||||
std::less<int>
|
||||
> ckey_comp_t3;
|
||||
|
||||
ckey_comp_t3 cp3;
|
||||
ckey_comp_t3 cp4(cp3);
|
||||
ckey_comp_t3 cp5(
|
||||
boost::make_tuple(
|
||||
std::less<int>(),
|
||||
std::greater<int>(),
|
||||
std::less<int>()));
|
||||
ckey_comp_t3 cp6(get<0>(cp3.key_comps()));
|
||||
|
||||
cp4=cp5; /* prevent unused var */
|
||||
cp5=cp6; /* prevent unused var */
|
||||
cp6=cp4; /* prevent unused var */
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp3));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp3));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp3));
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0),cp3));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(1),cp3));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(-1),cp3));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0),cp3));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,-1),cp3));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,1),cp3));
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0),cp3));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,0,1),cp3));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,0,-1),cp3));
|
||||
|
||||
typedef composite_key<
|
||||
xyz,
|
||||
BOOST_MULTI_INDEX_MEMBER(xyz,int,y), /* members reversed */
|
||||
BOOST_MULTI_INDEX_MEMBER(xyz,int,x)
|
||||
> ckey_t2;
|
||||
|
||||
ckey_t2 ck5;
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0))));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0))));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0))));
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp1));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp1));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp1));
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp2));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp2));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp2));
|
||||
|
||||
BOOST_CHECK(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp3));
|
||||
BOOST_CHECK(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp3));
|
||||
BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp3));
|
||||
|
||||
typedef multi_index_container<
|
||||
xyz,
|
||||
indexed_by<
|
||||
hashed_unique<
|
||||
ckey_t1
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
,composite_key_result_hash<ckey_t1::result_type>
|
||||
,composite_key_result_equal_to<ckey_t1::result_type>
|
||||
#endif
|
||||
>
|
||||
>
|
||||
> indexed_t2;
|
||||
|
||||
indexed_t2 mc2;
|
||||
mc2.insert(xyz(0,0,0));
|
||||
mc2.insert(xyz(0,0,1));
|
||||
mc2.insert(xyz(0,1,0));
|
||||
mc2.insert(xyz(0,1,1));
|
||||
mc2.insert(xyz(1,0,0));
|
||||
mc2.insert(xyz(1,0,1));
|
||||
mc2.insert(xyz(1,1,0));
|
||||
mc2.insert(xyz(1,1,1));
|
||||
mc2.insert(xyz(0,0,0));
|
||||
mc2.insert(xyz(0,0,1));
|
||||
mc2.insert(xyz(0,1,0));
|
||||
mc2.insert(xyz(0,1,1));
|
||||
mc2.insert(xyz(1,0,0));
|
||||
mc2.insert(xyz(1,0,1));
|
||||
mc2.insert(xyz(1,1,0));
|
||||
mc2.insert(xyz(1,1,1));
|
||||
|
||||
BOOST_CHECK(mc2.size()==8);
|
||||
BOOST_CHECK(mc2.find(make_tuple(0,0,1))->z==1);
|
||||
BOOST_CHECK(ck1(*(mc2.find(make_tuple(1,0,1))))==make_tuple(1,0,1));
|
||||
|
||||
typedef composite_key<
|
||||
xystr,
|
||||
BOOST_MULTI_INDEX_MEMBER(xystr,std::string,str),
|
||||
BOOST_MULTI_INDEX_MEMBER(xystr,int,x),
|
||||
BOOST_MULTI_INDEX_MEMBER(xystr,int,y)
|
||||
> ckey_t3;
|
||||
|
||||
ckey_t3 ck6;
|
||||
|
||||
typedef composite_key_hash<
|
||||
boost::hash<std::string>,
|
||||
boost::hash<int>,
|
||||
boost::hash<int>
|
||||
> ckey_hash_t;
|
||||
|
||||
ckey_hash_t ch1;
|
||||
ckey_hash_t ch2(ch1);
|
||||
ckey_hash_t ch3(
|
||||
boost::make_tuple(
|
||||
boost::hash<std::string>(),
|
||||
boost::hash<int>(),
|
||||
boost::hash<int>()));
|
||||
ckey_hash_t ch4(get<0>(ch1.key_hash_functions()));
|
||||
|
||||
ch2=ch3; /* prevent unused var */
|
||||
ch3=ch4; /* prevent unused var */
|
||||
ch4=ch2; /* prevent unused var */
|
||||
|
||||
BOOST_CHECK(
|
||||
ch1(ck6(xystr(0,0,"hello")))==ch1(make_tuple(std::string("hello"),0,0)));
|
||||
BOOST_CHECK(
|
||||
ch1(ck6(xystr(4,5,"world")))==ch1(make_tuple(std::string("world"),4,5)));
|
||||
|
||||
typedef boost::hash<composite_key_result<ckey_t3> > ckeyres_hash_t;
|
||||
|
||||
ckeyres_hash_t crh;
|
||||
|
||||
BOOST_CHECK(
|
||||
ch1(ck6(xystr(0,0,"hello")))==crh(ck6(xystr(0,0,"hello"))));
|
||||
BOOST_CHECK(
|
||||
ch1(ck6(xystr(4,5,"world")))==crh(ck6(xystr(4,5,"world"))));
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for composite_key.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_composite_key();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for composite_key.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_composite_key.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_composite_key();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/* Boost.MultiIndex test for interconvertibilty between const and
|
||||
* non-const iterators.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_conv_iterators.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
void test_conv_iterators()
|
||||
{
|
||||
employee_set es;
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
|
||||
{
|
||||
const employee_set& ces=es;
|
||||
employee_set::iterator it=es.find(employee(2,"John",40,7889));
|
||||
employee_set::const_iterator it1=es.find(employee(2,"John",40,7889));
|
||||
employee_set::const_iterator it2=ces.find(employee(2,"John",40,7889));
|
||||
|
||||
BOOST_CHECK(it==it1&&it1==it2&&it2==it);
|
||||
BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it);
|
||||
}
|
||||
{
|
||||
employee_set_by_name& i1=get<1>(es);
|
||||
const employee_set_by_name& ci1=get<1>(es);
|
||||
employee_set_by_name::iterator it=i1.find("John");
|
||||
employee_set_by_name::const_iterator it1=i1.find("John");
|
||||
employee_set_by_name::const_iterator it2=ci1.find("John");
|
||||
|
||||
BOOST_CHECK(it==it1&&it1==it2&&it2==it);
|
||||
BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it);
|
||||
}
|
||||
{
|
||||
employee_set_by_name& i1=get<1>(es);
|
||||
const employee_set_by_name& ci1=get<1>(es);
|
||||
employee_set_by_name::local_iterator it=i1.begin(i1.bucket("John"));
|
||||
employee_set_by_name::const_local_iterator it1=i1.begin(i1.bucket("John"));
|
||||
employee_set_by_name::const_local_iterator it2=ci1.begin(ci1.bucket("John"));
|
||||
|
||||
BOOST_CHECK(it==it1&&it1==it2&&it2==it);
|
||||
BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it);
|
||||
}
|
||||
{
|
||||
employee_set_as_inserted& i3=get<3>(es);
|
||||
const employee_set_as_inserted& ci3=get<3>(es);
|
||||
employee_set_as_inserted::iterator it=i3.begin();
|
||||
employee_set_as_inserted::const_iterator it1=i3.begin();
|
||||
employee_set_as_inserted::const_iterator it2=ci3.begin();
|
||||
|
||||
BOOST_CHECK(it==it1&&it1==it2&&it2==it);
|
||||
BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
/* Boost.MultiIndex test for interconvertibilty between const and
|
||||
* non-const iterators.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_conv_iterators();
|
||||
@@ -1,21 +0,0 @@
|
||||
/* Boost.MultiIndex test for interconvertibilty between const and
|
||||
* non-const iterators.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_conv_iterators.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_conv_iterators();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/* Boost.MultiIndex test for copying and assignment.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_copy_assignment.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
void test_copy_assignment()
|
||||
{
|
||||
employee_set es;
|
||||
employee_set es2(es);
|
||||
|
||||
employee_set::allocator_type al=es.get_allocator();
|
||||
al=get<1>(es).get_allocator();
|
||||
al=get<2>(es).get_allocator();
|
||||
al=get<3>(es).get_allocator();
|
||||
al=get<4>(es).get_allocator();
|
||||
|
||||
BOOST_CHECK(es2.empty());
|
||||
|
||||
es2.insert(employee(0,"Joe",31,1123));
|
||||
es2.insert(employee(1,"Robert",27,5601));
|
||||
es2.insert(employee(2,"John",40,7889));
|
||||
es2.insert(employee(2,"Aristotle",2388,3357)); /* clash */
|
||||
es2.insert(employee(3,"Albert",20,9012));
|
||||
es2.insert(employee(4,"John",57,1002));
|
||||
es2.insert(employee(0,"Andrew",60,2302)); /* clash */
|
||||
|
||||
employee_set es3(es2);
|
||||
|
||||
BOOST_CHECK(es2==es3);
|
||||
BOOST_CHECK(get<2>(es2)==get<2>(es3));
|
||||
BOOST_CHECK(get<3>(es2)==get<3>(es3));
|
||||
|
||||
employee_set es4;
|
||||
employee_set_by_name& i1=get<name>(es4);
|
||||
i1=get<1>(es2);
|
||||
|
||||
BOOST_CHECK(es4==es2);
|
||||
|
||||
employee_set es5;
|
||||
employee_set_by_age& i2=get<age>(es5);
|
||||
i2=get<2>(es2);
|
||||
|
||||
BOOST_CHECK(i2==get<2>(es2));
|
||||
|
||||
employee_set es6;
|
||||
employee_set_as_inserted& i3=get<as_inserted>(es6);
|
||||
i3=get<3>(es2);
|
||||
|
||||
BOOST_CHECK(i3==get<3>(es2));
|
||||
|
||||
std::list<employee> l;
|
||||
l.push_back(employee(3,"Anna",31,5388));
|
||||
l.push_back(employee(1,"Rachel",27,9012));
|
||||
l.push_back(employee(2,"Agatha",40,1520));
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
employee_set es7;
|
||||
es7.insert(l.begin(),l.end());
|
||||
#else
|
||||
employee_set es7(l.begin(),l.end());
|
||||
#endif
|
||||
|
||||
l.sort();
|
||||
|
||||
BOOST_CHECK(es7.size()==l.size()&&
|
||||
std::equal(es7.begin(),es7.end(),l.begin()));
|
||||
|
||||
multi_index_container<int,indexed_by<sequenced<> > > ss;
|
||||
|
||||
int a[]={0,1,2,3,4,5};
|
||||
std::size_t sa=sizeof(a)/sizeof(a[0]);
|
||||
|
||||
ss.assign(&a[0],&a[sa]);
|
||||
|
||||
BOOST_CHECK(ss.size()==sa&&std::equal(ss.begin(),ss.end(),&a[0]));
|
||||
|
||||
ss.assign(&a[0],&a[sa]);
|
||||
|
||||
BOOST_CHECK(ss.size()==sa&&std::equal(ss.begin(),ss.end(),&a[0]));
|
||||
|
||||
ss.assign((std::size_t)18,37);
|
||||
BOOST_CHECK(ss.size()==18&&std::accumulate(ss.begin(),ss.end(),0)==666);
|
||||
|
||||
ss.assign((std::size_t)12,167);
|
||||
BOOST_CHECK(ss.size()==12&&std::accumulate(ss.begin(),ss.end(),0)==2004);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for copying and assignment.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_copy_assignment();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for copying and assignment.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_copy_assignment.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_copy_assignment();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/* Boost.MultiIndex test for standard hash operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_hash_ops.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <iterator>
|
||||
#include "pre_multi_index.hpp"
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/test/floating_point_comparison.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
template<typename HashedContainer>
|
||||
void check_load_factor(const HashedContainer& hc)
|
||||
{
|
||||
float lf=(float)hc.size()/hc.bucket_count();
|
||||
BOOST_CHECK_CLOSE(lf,hc.load_factor(),1.E-6f);
|
||||
BOOST_CHECK(lf<=hc.max_load_factor()+1.E-6);
|
||||
}
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
hashed_unique<identity<int> >
|
||||
>
|
||||
> hash_container;
|
||||
|
||||
void test_hash_ops()
|
||||
{
|
||||
hash_container hc;
|
||||
|
||||
BOOST_CHECK(hc.max_load_factor()==1.0f);
|
||||
BOOST_CHECK(hc.bucket_count()<=hc.max_bucket_count());
|
||||
|
||||
hc.insert(1000);
|
||||
hash_container::size_type buc=hc.bucket(1000);
|
||||
hash_container::local_iterator it0=hc.begin(buc);
|
||||
hash_container::local_iterator it1=hc.end(buc);
|
||||
BOOST_CHECK(
|
||||
(hash_container::size_type)std::distance(it0,it1)==hc.bucket_size(buc)&&
|
||||
hc.bucket_size(buc)==1&&*it0==1000);
|
||||
|
||||
hc.clear();
|
||||
|
||||
for(hash_container::size_type s=2*hc.bucket_count();s--;){
|
||||
hc.insert((int)s);
|
||||
}
|
||||
check_load_factor(hc);
|
||||
|
||||
hc.max_load_factor(0.5f);
|
||||
BOOST_CHECK(hc.max_load_factor()==0.5f);
|
||||
hc.insert(-1);
|
||||
check_load_factor(hc);
|
||||
|
||||
hc.rehash(1);
|
||||
BOOST_CHECK(hc.bucket_count()>=1);
|
||||
check_load_factor(hc);
|
||||
|
||||
hc.max_load_factor(0.25f);
|
||||
hc.rehash(1);
|
||||
BOOST_CHECK(hc.bucket_count()>=1);
|
||||
check_load_factor(hc);
|
||||
|
||||
hash_container::size_type bc=4*hc.bucket_count();
|
||||
hc.max_load_factor(0.125f);
|
||||
hc.rehash(bc);
|
||||
BOOST_CHECK(hc.bucket_count()>=bc);
|
||||
check_load_factor(hc);
|
||||
|
||||
bc=2*hc.bucket_count();
|
||||
hc.rehash(bc);
|
||||
BOOST_CHECK(hc.bucket_count()>=bc);
|
||||
check_load_factor(hc);
|
||||
|
||||
hc.clear();
|
||||
hc.insert(0);
|
||||
hc.rehash(1);
|
||||
BOOST_CHECK(hc.bucket_count()>=1);
|
||||
check_load_factor(hc);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for standard hash operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_hash_ops();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for standard hash operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_hash_ops.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_hash_ops();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/* Boost.MultiIndex test for iterators.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_iterators.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
template<typename Index>
|
||||
void test_non_const_iterators(Index& i,int target)
|
||||
{
|
||||
typedef typename Index::iterator iterator;
|
||||
typedef typename Index::reverse_iterator reverse_iterator;
|
||||
|
||||
int n=0;
|
||||
for(iterator it=i.begin();it!=i.end();++it){
|
||||
n+=it->id;
|
||||
}
|
||||
int m=0;
|
||||
for(reverse_iterator rit=i.rbegin();rit!=i.rend();++rit){
|
||||
m+=rit->id;
|
||||
}
|
||||
int p=0;
|
||||
for(iterator it2=i.end();it2!=i.begin();){
|
||||
--it2;
|
||||
p+=it2->id;
|
||||
}
|
||||
int q=0;
|
||||
for(reverse_iterator rit2=i.rend();rit2!=i.rbegin();){
|
||||
--rit2;
|
||||
q+=rit2->id;
|
||||
}
|
||||
|
||||
BOOST_CHECK(n==target&&n==m&&n==p&&n==q);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
void test_const_iterators(const Index& i,int target)
|
||||
{
|
||||
typedef typename Index::const_iterator const_iterator;
|
||||
typedef typename Index::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
int n=0;
|
||||
for(const_iterator it=i.begin();it!=i.end();++it){
|
||||
n+=it->id;
|
||||
}
|
||||
int m=0;
|
||||
for(const_reverse_iterator rit=i.rbegin();rit!=i.rend();++rit){
|
||||
m+=rit->id;
|
||||
}
|
||||
int p=0;
|
||||
for(const_iterator it2=i.end();it2!=i.begin();){
|
||||
--it2;
|
||||
p+=it2->id;
|
||||
}
|
||||
int q=0;
|
||||
for(const_reverse_iterator rit2=i.rend();rit2!=i.rbegin();){
|
||||
--rit2;
|
||||
q+=rit2->id;
|
||||
}
|
||||
|
||||
BOOST_CHECK(n==target&&n==m&&n==p&&n==q);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
void test_non_const_hashed_iterators(Index& i,int target)
|
||||
{
|
||||
typedef typename Index::iterator iterator;
|
||||
typedef typename Index::local_iterator local_iterator;
|
||||
typedef typename Index::size_type size_type;
|
||||
|
||||
int n=0;
|
||||
for(iterator it=i.begin();it!=i.end();++it){
|
||||
n+=it->id;
|
||||
}
|
||||
int m=0;
|
||||
for(size_type buc=0;buc<i.bucket_count();++buc){
|
||||
for(local_iterator it=i.begin(buc);it!=i.end(buc);++it){
|
||||
m+=it->id;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CHECK(n==target&&n==m);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
void test_const_hashed_iterators(Index& i,int target)
|
||||
{
|
||||
typedef typename Index::const_iterator const_iterator;
|
||||
typedef typename Index::const_local_iterator const_local_iterator;
|
||||
typedef typename Index::size_type size_type;
|
||||
|
||||
int n=0;
|
||||
for(const_iterator it=i.begin();it!=i.end();++it){
|
||||
n+=it->id;
|
||||
}
|
||||
int m=0;
|
||||
for(size_type buc=0;buc<i.bucket_count();++buc){
|
||||
for(const_local_iterator it=i.begin(buc);it!=i.end(buc);++it){
|
||||
m+=it->id;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CHECK(n==target&&n==m);
|
||||
}
|
||||
|
||||
void test_iterators()
|
||||
{
|
||||
employee_set es;
|
||||
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(1,"Robert",27,5601));
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
es.insert(employee(3,"Albert",20,9012));
|
||||
es.insert(employee(4,"John",57,1002));
|
||||
|
||||
int target=0+1+2+3+4;
|
||||
|
||||
test_non_const_iterators (es,target);
|
||||
test_const_iterators (es,target);
|
||||
test_non_const_hashed_iterators(get<1>(es),target);
|
||||
test_const_hashed_iterators (get<1>(es),target);
|
||||
test_non_const_iterators (get<2>(es),target);
|
||||
test_const_iterators (get<2>(es),target);
|
||||
test_non_const_iterators (get<3>(es),target);
|
||||
test_const_iterators (get<3>(es),target);
|
||||
test_non_const_hashed_iterators(get<4>(es),target);
|
||||
test_const_hashed_iterators (get<4>(es),target);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for iterators.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_iterators();
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Boost.MultiIndex test for iterators.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_iterators.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_iterators();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,221 +0,0 @@
|
||||
/* Boost.MultiIndex test for key extractors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_key_extractors.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include <boost/multi_index/key_extractors.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
using namespace boost::tuples;
|
||||
|
||||
struct test_class
|
||||
{
|
||||
int int_member;
|
||||
const int int_cmember;
|
||||
|
||||
bool bool_mem_fun_const()const{return true;}
|
||||
bool bool_mem_fun(){return false;}
|
||||
|
||||
test_class(int i=0):int_member(i),int_cmember(i){}
|
||||
test_class(int i,int j):int_member(i),int_cmember(j){}
|
||||
|
||||
test_class& operator=(const test_class& x)
|
||||
{
|
||||
int_member=x.int_member;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator<(const test_class& x)const
|
||||
{
|
||||
if(int_member<x.int_member)return true;
|
||||
if(x.int_member<int_member)return false;
|
||||
return int_cmember<x.int_cmember;
|
||||
}
|
||||
|
||||
bool operator==(const test_class& x)const
|
||||
{
|
||||
return int_member==x.int_member&&int_cmember==x.int_cmember;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(test_class)
|
||||
|
||||
typedef identity<test_class> idn;
|
||||
typedef identity<const test_class> cidn;
|
||||
typedef BOOST_MULTI_INDEX_MEMBER(test_class,int,int_member) key_m;
|
||||
typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_member) ckey_m;
|
||||
typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_cmember) key_cm;
|
||||
typedef BOOST_MULTI_INDEX_CONST_MEM_FUN(
|
||||
test_class,bool,bool_mem_fun_const) key_cmf;
|
||||
typedef BOOST_MULTI_INDEX_MEM_FUN(test_class,bool,bool_mem_fun) key_mf;
|
||||
typedef composite_key<
|
||||
test_class,
|
||||
idn,
|
||||
key_m,
|
||||
key_cm,
|
||||
key_cmf
|
||||
> compkey;
|
||||
typedef composite_key<
|
||||
test_class,
|
||||
cidn,
|
||||
ckey_m
|
||||
> ccompkey;
|
||||
typedef composite_key<
|
||||
boost::reference_wrapper<test_class>,
|
||||
key_mf
|
||||
> ccompw_key;
|
||||
|
||||
void test_key_extractors()
|
||||
{
|
||||
idn id;
|
||||
cidn cid;
|
||||
key_m k_m;
|
||||
ckey_m ck_m;
|
||||
key_cm k_cm;
|
||||
key_cmf k_cmf;
|
||||
key_mf k_mf;
|
||||
compkey cmpk;
|
||||
ccompkey ccmpk;
|
||||
ccompw_key ccmpk_w;
|
||||
|
||||
test_class t;
|
||||
const test_class& ctr=t;
|
||||
|
||||
test_class* tp=&t;
|
||||
const test_class* ctp=&t;
|
||||
|
||||
test_class** tpp=&tp;
|
||||
const test_class** ctpp=&ctp;
|
||||
|
||||
std::auto_ptr<test_class*> tap(new test_class*(tp));
|
||||
std::auto_ptr<const test_class*> ctap(new const test_class*(ctp));
|
||||
|
||||
boost::reference_wrapper<test_class> tw(t);
|
||||
boost::reference_wrapper<const test_class> ctw(t);
|
||||
|
||||
id(t).int_member=0;
|
||||
BOOST_CHECK(id(t).int_member==0);
|
||||
BOOST_CHECK(cid(t).int_member==0);
|
||||
BOOST_CHECK(k_m(t)==0);
|
||||
BOOST_CHECK(ck_m(t)==0);
|
||||
BOOST_CHECK(cmpk(t)==make_tuple(test_class(0,0),0,0,true));
|
||||
BOOST_CHECK(ccmpk(t)==make_tuple(test_class(0,0),0));
|
||||
BOOST_CHECK(id(ctr).int_member==0);
|
||||
BOOST_CHECK(cid(ctr).int_member==0);
|
||||
BOOST_CHECK(k_m(ctr)==0);
|
||||
BOOST_CHECK(ck_m(ctr)==0);
|
||||
BOOST_CHECK(cmpk(ctr)==make_tuple(test_class(0,0),0,0,true));
|
||||
BOOST_CHECK(ccmpk(ctr)==make_tuple(test_class(0,0),0));
|
||||
|
||||
k_m(t)=1;
|
||||
BOOST_CHECK(id(tp).int_member==1);
|
||||
BOOST_CHECK(cid(tp).int_member==1);
|
||||
BOOST_CHECK(k_m(tp)==1);
|
||||
BOOST_CHECK(ck_m(tp)==1);
|
||||
BOOST_CHECK(cmpk(tp)==make_tuple(test_class(1,0),1,0,true));
|
||||
BOOST_CHECK(ccmpk(tp)==make_tuple(test_class(1,0),1));
|
||||
BOOST_CHECK(cid(ctp).int_member==1);
|
||||
BOOST_CHECK(ck_m(ctp)==1);
|
||||
BOOST_CHECK(cmpk(ctp)==make_tuple(test_class(1,0),1,0,true));
|
||||
BOOST_CHECK(ccmpk(ctp)==make_tuple(test_class(1,0),1));
|
||||
|
||||
k_m(tp)=2;
|
||||
BOOST_CHECK(id(tpp).int_member==2);
|
||||
BOOST_CHECK(cid(tpp).int_member==2);
|
||||
BOOST_CHECK(k_m(tpp)==2);
|
||||
BOOST_CHECK(ck_m(tpp)==2);
|
||||
BOOST_CHECK(cmpk(tpp)==make_tuple(test_class(2,0),2,0,true));
|
||||
BOOST_CHECK(ccmpk(tpp)==make_tuple(test_class(2,0),2));
|
||||
BOOST_CHECK(cid(ctpp).int_member==2);
|
||||
BOOST_CHECK(ck_m(ctpp)==2);
|
||||
BOOST_CHECK(cmpk(ctpp)==make_tuple(test_class(2,0),2,0,true));
|
||||
BOOST_CHECK(ccmpk(ctpp)==make_tuple(test_class(2,0),2));
|
||||
|
||||
k_m(tpp)=3;
|
||||
BOOST_CHECK(id(tap).int_member==3);
|
||||
BOOST_CHECK(cid(tap).int_member==3);
|
||||
BOOST_CHECK(k_m(tap)==3);
|
||||
BOOST_CHECK(ck_m(tap)==3);
|
||||
BOOST_CHECK(cmpk(tap)==make_tuple(test_class(3,0),3,0,true));
|
||||
BOOST_CHECK(ccmpk(tap)==make_tuple(test_class(3,0),3));
|
||||
BOOST_CHECK(cid(ctap).int_member==3);
|
||||
BOOST_CHECK(ck_m(ctap)==3);
|
||||
BOOST_CHECK(cmpk(ctap)==make_tuple(test_class(3,0),3,0,true));
|
||||
BOOST_CHECK(ccmpk(ctap)==make_tuple(test_class(3,0),3));
|
||||
|
||||
k_m(tap)=4;
|
||||
BOOST_CHECK(id(tw).int_member==4);
|
||||
BOOST_CHECK(cid(tw).int_member==4);
|
||||
BOOST_CHECK(k_m(tw)==4);
|
||||
BOOST_CHECK(ck_m(tw)==4);
|
||||
BOOST_CHECK(cmpk(tw)==make_tuple(test_class(4,0),4,0,true));
|
||||
BOOST_CHECK(ccmpk(tw)==make_tuple(test_class(4,0),4));
|
||||
|
||||
k_m(tw)=5;
|
||||
BOOST_CHECK(id(ctw).int_member==5);
|
||||
BOOST_CHECK(cid(ctw).int_member==5);
|
||||
BOOST_CHECK(k_m(ctw)==5);
|
||||
BOOST_CHECK(ck_m(ctw)==5);
|
||||
BOOST_CHECK(cmpk(ctw)==make_tuple(test_class(5,0),5,0,true));
|
||||
BOOST_CHECK(ccmpk(ctw)==make_tuple(test_class(5,0),5));
|
||||
|
||||
BOOST_CHECK(k_cm(t)==0);
|
||||
|
||||
BOOST_CHECK(k_cm(tp)==0);
|
||||
BOOST_CHECK(k_cm(ctp)==0);
|
||||
BOOST_CHECK(k_cm(tpp)==0);
|
||||
BOOST_CHECK(k_cm(ctpp)==0);
|
||||
BOOST_CHECK(k_cm(tap)==0);
|
||||
BOOST_CHECK(k_cm(ctap)==0);
|
||||
|
||||
BOOST_CHECK(k_cm(tw)==0);
|
||||
BOOST_CHECK(k_cm(ctw)==0);
|
||||
|
||||
BOOST_CHECK(k_cmf(t));
|
||||
|
||||
BOOST_CHECK(k_cmf(tp));
|
||||
BOOST_CHECK(k_cmf(ctp));
|
||||
BOOST_CHECK(k_cmf(tpp));
|
||||
BOOST_CHECK(k_cmf(ctpp));
|
||||
BOOST_CHECK(k_cmf(tap));
|
||||
BOOST_CHECK(k_cmf(ctap));
|
||||
|
||||
BOOST_CHECK(k_cmf(tw));
|
||||
BOOST_CHECK(k_cmf(ctw));
|
||||
|
||||
BOOST_CHECK(!k_mf(t));
|
||||
|
||||
BOOST_CHECK(!k_mf(tp));
|
||||
BOOST_CHECK(!k_mf(tpp));
|
||||
BOOST_CHECK(!k_mf(tap));
|
||||
BOOST_CHECK(!k_mf(tw));
|
||||
BOOST_CHECK(ccmpk_w(tw)==make_tuple(false));
|
||||
|
||||
std::list<test_class> tl;
|
||||
for(int i=0;i<20;++i)tl.push_back(test_class(i));
|
||||
|
||||
int j=0;
|
||||
for(std::list<test_class>::iterator it=tl.begin();it!=tl.end();++it){
|
||||
BOOST_CHECK(k_m(it)==j);
|
||||
BOOST_CHECK(k_cm(it)==j);
|
||||
BOOST_CHECK(k_cmf(it));
|
||||
BOOST_CHECK(!k_mf(it));
|
||||
BOOST_CHECK(cmpk(it)==make_tuple(test_class(j),j,j,true));
|
||||
BOOST_CHECK(ccmpk(it)==make_tuple(test_class(j),j));
|
||||
++j;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for key extractors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_key_extractors();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for key extractors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_key_extractors.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_key_extractors();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/* Boost.MultiIndex test for standard list operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_list_ops.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "pre_multi_index.hpp"
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
#undef _
|
||||
#define _ ,
|
||||
|
||||
#undef CHECK_EQUAL
|
||||
#define CHECK_EQUAL(p,check_range) \
|
||||
{\
|
||||
int v[]=check_range;\
|
||||
std::size_t size_v=sizeof(v)/sizeof(int);\
|
||||
BOOST_CHECK(std::size_t(std::distance((p).begin(),(p).end()))==size_v);\
|
||||
BOOST_CHECK(std::equal((p).begin(),(p).end(),v));\
|
||||
}
|
||||
|
||||
#undef CHECK_VOID_RANGE
|
||||
#define CHECK_VOID_RANGE(p) BOOST_CHECK((p).first==(p).second)
|
||||
|
||||
struct is_even
|
||||
{
|
||||
bool operator()(int x)const{return x%2==0;}
|
||||
};
|
||||
|
||||
template <int m>
|
||||
struct same_integral_div
|
||||
{
|
||||
bool operator()(int x,int y)const{return (x/m)==(y/m);}
|
||||
};
|
||||
|
||||
template <typename Container,typename Compare>
|
||||
bool is_sorted(
|
||||
const Container& c,const Compare& comp=Compare())
|
||||
{
|
||||
if(c.empty())return true;
|
||||
|
||||
typedef typename Container::const_iterator const_iterator;
|
||||
for(const_iterator it(c.begin());;){
|
||||
const_iterator it2=it;
|
||||
++it2;
|
||||
if(it2==c.end())return true;
|
||||
if(comp(*it2,*it))return false;
|
||||
it=it2;
|
||||
}
|
||||
}
|
||||
|
||||
void test_list_ops()
|
||||
{
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
ordered_unique<identity<int> >,
|
||||
sequenced<>
|
||||
>
|
||||
> sequenced_set;
|
||||
typedef nth_index<sequenced_set,1>::type sequenced_index;
|
||||
|
||||
sequenced_set ss,ss2;
|
||||
sequenced_index &si=get<1>(ss),&si2=get<1>(ss2);
|
||||
|
||||
si.push_front(0); /* 0 */
|
||||
si.push_front(4); /* 40 */
|
||||
ss.insert(2); /* 402 */
|
||||
ss.insert(5); /* 4025 */
|
||||
si.push_front(3); /* 34025 */
|
||||
si.push_back(6); /* 340256 */
|
||||
si.push_back(1); /* 3402561 */
|
||||
si.insert(project<1>(ss,ss.find(2)),8); /* 34082561 */
|
||||
si2=si;
|
||||
|
||||
CHECK_EQUAL(si,{3 _ 4 _ 0 _ 8 _ 2 _ 5 _ 6 _ 1});
|
||||
|
||||
si.remove(8);
|
||||
CHECK_EQUAL(si,{3 _ 4 _ 0 _ 2 _ 5 _ 6 _ 1});
|
||||
|
||||
si.remove_if(is_even());
|
||||
|
||||
CHECK_EQUAL(si,{3 _ 5 _ 1});
|
||||
|
||||
si.splice(si.end(),si2);
|
||||
CHECK_EQUAL(si,{3 _ 5 _ 1 _ 4 _ 0 _ 8 _ 2 _ 6});
|
||||
CHECK_EQUAL(si2,{3 _ 5 _ 1});
|
||||
|
||||
si.splice(project<1>(ss,ss.find(4)),si,project<1>(ss,ss.find(8)));
|
||||
CHECK_EQUAL(si,{3 _ 5 _ 1 _ 8 _ 4 _ 0 _ 2 _ 6});
|
||||
si2.clear();
|
||||
si2.splice(si2.begin(),si,si.begin());
|
||||
|
||||
si.splice(si.end(),si2,si2.begin());
|
||||
CHECK_EQUAL(si,{5 _ 1 _ 8 _ 4 _ 0 _ 2 _ 6 _ 3});
|
||||
BOOST_CHECK(si2.empty());
|
||||
|
||||
si2.splice(si2.end(),si,project<1>(ss,ss.find(0)),project<1>(ss,ss.find(6)));
|
||||
CHECK_EQUAL(si,{5 _ 1 _ 8 _ 4 _ 6 _ 3});
|
||||
CHECK_EQUAL(si2,{0 _ 2});
|
||||
|
||||
si.splice(si.begin(),si,si.begin(),si.begin());
|
||||
CHECK_EQUAL(si,{5 _ 1 _ 8 _ 4 _ 6 _ 3});
|
||||
|
||||
si.splice(project<1>(ss,ss.find(8)),si,project<1>(ss,ss.find(4)),si.end());
|
||||
CHECK_EQUAL(si,{5 _ 1 _ 4 _ 6 _ 3 _ 8});
|
||||
|
||||
si.sort();
|
||||
si2.sort();
|
||||
BOOST_CHECK(is_sorted(si,std::less<int>()));
|
||||
BOOST_CHECK(is_sorted(si2,std::less<int>()));
|
||||
|
||||
si.merge(si2);
|
||||
BOOST_CHECK(is_sorted(si,std::less<int>()));
|
||||
BOOST_CHECK(si2.empty());
|
||||
|
||||
{
|
||||
sequenced_set ss3(ss);
|
||||
sequenced_index &si3=get<1>(ss3);
|
||||
|
||||
si3.sort(std::greater<int>());
|
||||
si.reverse();
|
||||
BOOST_CHECK(si==si3);
|
||||
}
|
||||
|
||||
si2.splice(si2.end(),si,project<1>(ss,ss.find(6)),project<1>(ss,ss.find(3)));
|
||||
CHECK_EQUAL(si2,{6 _ 5 _ 4});
|
||||
|
||||
si.merge(si2,std::greater<int>());
|
||||
BOOST_CHECK(is_sorted(si,std::greater<int>()));
|
||||
BOOST_CHECK(si2.empty());
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<sequenced<> >
|
||||
> int_list;
|
||||
|
||||
int_list il;
|
||||
for(int i=0;i<10;++i){
|
||||
il.push_back(i);
|
||||
il.push_back(i);
|
||||
il.push_front(i);
|
||||
il.push_front(i);
|
||||
} /* 9988776655443322110000112233445566778899 */
|
||||
|
||||
il.unique();
|
||||
CHECK_EQUAL(
|
||||
il,
|
||||
{9 _ 8 _ 7 _ 6 _ 5 _ 4 _ 3 _ 2 _ 1 _ 0 _
|
||||
1 _ 2 _ 3 _ 4 _ 5 _ 6 _ 7 _ 8 _ 9});
|
||||
|
||||
int_list::iterator it=il.begin();
|
||||
for(int j=0;j<9;++j,++it){} /* it points to o */
|
||||
|
||||
int_list il2;
|
||||
il2.splice(il2.end(),il,il.begin(),it);
|
||||
il2.reverse();
|
||||
il.merge(il2);
|
||||
CHECK_EQUAL(
|
||||
il,
|
||||
{0 _ 1 _ 1 _ 2 _ 2 _ 3 _ 3 _ 4 _ 4 _ 5 _ 5 _
|
||||
6 _ 6 _ 7 _ 7 _ 8 _ 8 _ 9 _ 9});
|
||||
|
||||
il.unique(same_integral_div<3>());
|
||||
CHECK_EQUAL(il,{0 _ 3 _ 6 _ 9});
|
||||
|
||||
il.unique(same_integral_div<1>());
|
||||
CHECK_EQUAL(il,{0 _ 3 _ 6 _ 9});
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for standard list operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_list_ops();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for standard list operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_list_ops.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_list_ops();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/* Boost.MultiIndex test for modifier memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_modifiers.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <vector>
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
void test_modifiers()
|
||||
{
|
||||
employee_set es;
|
||||
employee_set_by_name& i1=get<name>(es);
|
||||
employee_set_by_age& i2=get<age>(es);
|
||||
employee_set_as_inserted& i3=get<as_inserted>(es);
|
||||
employee_set_by_ssn& i4=get<ssn>(es);
|
||||
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
BOOST_CHECK(es.insert(employee(0,"Joe",31,1123)).second==false);
|
||||
BOOST_CHECK(i1.insert(employee(0,"Joe Jr.",5,2563)).second==false);
|
||||
BOOST_CHECK(i2.insert(employee(1,"Victor",5,1123)).second==false);
|
||||
BOOST_CHECK(i3.insert(i3.begin(),employee(1,"Victor",5,1123)).second
|
||||
==false);
|
||||
BOOST_CHECK(i3.push_front(employee(0,"Joe Jr.",5,2563)).second==false);
|
||||
BOOST_CHECK(i3.push_back(employee(0,"Joe Jr.",5,2563)).second==false);
|
||||
|
||||
employee_set_by_name::iterator it1=i1.find("Joe");
|
||||
i1.insert(it1,employee(1,"Joe Jr.",5,2563));
|
||||
BOOST_CHECK(es.size()==2);
|
||||
|
||||
employee_set_by_age::iterator it2=i2.find(31);
|
||||
i2.insert(it2,employee(2,"Grandda Joe",64,7881));
|
||||
BOOST_CHECK(es.size()==3);
|
||||
|
||||
employee_set_as_inserted::iterator it3=i3.begin();
|
||||
i3.insert(it3,100,employee(3,"Judy",39,6201));
|
||||
BOOST_CHECK(es.size()==4);
|
||||
|
||||
es.erase(employee(1,"Joe Jr.",5,2563));
|
||||
BOOST_CHECK(i2.size()==3&&i3.size()==3);
|
||||
|
||||
BOOST_CHECK(i1.erase("Judy")==1);
|
||||
BOOST_CHECK(es.size()==2&&i2.size()==2);
|
||||
|
||||
BOOST_CHECK(i2.erase(it2)->age==64);
|
||||
BOOST_CHECK(es.size()==1&&i1.size()==1);
|
||||
|
||||
i3.pop_front();
|
||||
BOOST_CHECK(es.size()==0&&i2.size()==0);
|
||||
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
BOOST_CHECK(i1.erase(i1.begin())==i1.end());
|
||||
BOOST_CHECK(i1.size()==0);
|
||||
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(1,"Jack",31,5032));
|
||||
BOOST_CHECK(i2.erase(31)==2);
|
||||
BOOST_CHECK(i2.size()==0);
|
||||
|
||||
i3.push_front(employee(1,"Jack",31,5032));
|
||||
i3.push_back(employee(0,"Joe",31,1123));
|
||||
BOOST_CHECK(i3.front()==employee(1,"Jack",31,5032));
|
||||
BOOST_CHECK(i3.back()==employee(0,"Joe",31,1123));
|
||||
|
||||
i3.pop_back();
|
||||
BOOST_CHECK(i3.back()==employee(1,"Jack",31,5032));
|
||||
BOOST_CHECK(es.size()==1);
|
||||
|
||||
i3.pop_front();
|
||||
BOOST_CHECK(es.size()==0);
|
||||
|
||||
std::vector<employee> ve;
|
||||
ve.push_back(employee(3,"Anna",31,5388));
|
||||
ve.push_back(employee(1,"Rachel",27,9012));
|
||||
ve.push_back(employee(2,"Agatha",40,1520));
|
||||
|
||||
i1.insert(ve.begin(),ve.end());
|
||||
BOOST_CHECK(i2.size()==3);
|
||||
|
||||
BOOST_CHECK(i4.erase(i4.begin(),i4.end())==i4.end());
|
||||
BOOST_CHECK(es.size()==0);
|
||||
|
||||
i2.insert(ve.begin(),ve.end());
|
||||
BOOST_CHECK(i3.size()==3);
|
||||
|
||||
BOOST_CHECK(*(i3.erase(i3.begin()))==employee(1,"Rachel",27,9012));
|
||||
BOOST_CHECK(i3.erase(i3.begin(),i3.end())==i3.end());
|
||||
BOOST_CHECK(es.size()==0);
|
||||
|
||||
i3.insert(i3.end(),ve.begin(),ve.end());
|
||||
BOOST_CHECK(es.size()==3);
|
||||
|
||||
BOOST_CHECK(es.erase(es.begin(),es.end())==es.end());
|
||||
BOOST_CHECK(i2.size()==0);
|
||||
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(1,"Robert",27,5601));
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
es.insert(employee(3,"Albert",20,9012));
|
||||
es.insert(employee(4,"John",57,1002));
|
||||
|
||||
employee_set es_backup(es);
|
||||
|
||||
employee_set es2;
|
||||
es2.insert(employee(3,"Anna",31,5388));
|
||||
es2.insert(employee(1,"Rachel",27,9012));
|
||||
es2.insert(employee(2,"Agatha",40,1520));
|
||||
|
||||
employee_set es2_backup(es2);
|
||||
|
||||
i1.swap(get<1>(es2));
|
||||
BOOST_CHECK(es==es2_backup&&es2==es_backup);
|
||||
|
||||
i2.swap(get<2>(es2));
|
||||
BOOST_CHECK(es==es_backup&&es2==es2_backup);
|
||||
|
||||
i3.swap(get<3>(es2));
|
||||
BOOST_CHECK(es==es2_backup&&es2==es_backup);
|
||||
|
||||
#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
|
||||
::boost::multi_index::detail::swap(i1,get<1>(es2));
|
||||
#else
|
||||
using std::swap;
|
||||
swap(i1,get<1>(es2));
|
||||
#endif
|
||||
|
||||
BOOST_CHECK(es==es_backup&&es2==es2_backup);
|
||||
|
||||
#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
|
||||
::boost::multi_index::detail::swap(i2,get<2>(es2));
|
||||
#else
|
||||
using std::swap;
|
||||
swap(i2,get<2>(es2));
|
||||
#endif
|
||||
|
||||
BOOST_CHECK(es==es2_backup&&es2==es_backup);
|
||||
|
||||
#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
|
||||
::boost::multi_index::detail::swap(i3,get<3>(es2));
|
||||
#else
|
||||
using std::swap;
|
||||
swap(i3,get<3>(es2));
|
||||
#endif
|
||||
|
||||
BOOST_CHECK(es==es_backup&&es2==es2_backup);
|
||||
|
||||
i3.clear();
|
||||
BOOST_CHECK(i3.size()==0);
|
||||
|
||||
es=es2;
|
||||
i4.clear();
|
||||
BOOST_CHECK(i4.size()==0);
|
||||
|
||||
es2.clear();
|
||||
BOOST_CHECK(es2.size()==0);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for modifier memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_modifiers();
|
||||
@@ -1,20 +0,0 @@
|
||||
/* Boost.MultiIndex test for modifier memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_modifiers.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_modifiers();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/* Boost.MultiIndex test for MPL operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_mpl_ops.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
void test_mpl_ops()
|
||||
{
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
ordered_unique<identity<int> >,
|
||||
ordered_non_unique<identity<int> >
|
||||
>
|
||||
> indexed_t1;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
boost::mpl::at_c<indexed_t1::index_specifier_type_list,0>::type,
|
||||
ordered_unique<identity<int> > >::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
boost::mpl::at_c<indexed_t1::index_specifier_type_list,1>::type,
|
||||
ordered_non_unique<identity<int> > >::value));
|
||||
|
||||
typedef boost::mpl::push_front<
|
||||
indexed_t1::index_specifier_type_list,
|
||||
sequenced<>
|
||||
>::type index_list_t;
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
index_list_t
|
||||
> indexed_t2;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
boost::mpl::at_c<indexed_t2::index_specifier_type_list,0>::type,
|
||||
sequenced<> >::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
boost::mpl::at_c<indexed_t2::index_specifier_type_list,1>::type,
|
||||
boost::mpl::at_c<indexed_t1::index_specifier_type_list,0>::type>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
boost::mpl::at_c<indexed_t2::index_specifier_type_list,2>::type,
|
||||
boost::mpl::at_c<indexed_t1::index_specifier_type_list,1>::type>::value));
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
boost::mpl::list<
|
||||
ordered_unique<identity<int> >,
|
||||
ordered_non_unique<identity<int> >
|
||||
>
|
||||
> indexed_t3;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
boost::mpl::at_c<indexed_t3::index_specifier_type_list,0>::type,
|
||||
boost::mpl::at_c<indexed_t1::index_specifier_type_list,0>::type>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
boost::mpl::at_c<indexed_t3::index_specifier_type_list,1>::type,
|
||||
boost::mpl::at_c<indexed_t1::index_specifier_type_list,1>::type>::value));
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for for MPL operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_mpl_ops();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for for MPL operations.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_mpl_ops.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_mpl_ops();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/* Boost.MultiIndex test for observer memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_observers.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
void test_observers()
|
||||
{
|
||||
employee_set es;
|
||||
const employee_set_by_name& i1=get<by_name>(es);
|
||||
const employee_set_by_age& i2=get<age>(es);
|
||||
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(1,"Robert",27,5601));
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
es.insert(employee(3,"Albert",20,9012));
|
||||
es.insert(employee(4,"John",57,1002));
|
||||
|
||||
{
|
||||
employee_set_by_name::key_from_value k=i1.key_extractor();
|
||||
employee_set_by_name::hasher h=i1.hash_function();
|
||||
employee_set_by_name::key_equal eq=i1.key_eq();
|
||||
|
||||
employee_set_by_name::const_iterator it0=i1.equal_range("John").first;
|
||||
employee_set_by_name::const_iterator it1=it0;++it1;
|
||||
BOOST_CHECK(k(*it0)=="John"&&k(*it1)=="John");
|
||||
BOOST_CHECK(h(k(*it0))==h(k(*it1)));
|
||||
BOOST_CHECK(eq(k(*it0),k(*it1))==true);
|
||||
}
|
||||
{
|
||||
employee_set_by_age::key_from_value k=i2.key_extractor();
|
||||
employee_set_by_age::key_compare c=i2.key_comp();
|
||||
employee_set_by_age::value_compare vc=i2.value_comp();
|
||||
|
||||
employee_set_by_age::const_iterator it0=i2.find(31);
|
||||
employee_set_by_age::const_iterator it1=i2.find(40);
|
||||
BOOST_CHECK(k(*it0)==31&&k(*it1)==40);
|
||||
BOOST_CHECK(c(k(*it0),k(*it1))==true);
|
||||
BOOST_CHECK(vc(*it0,*it1)==true);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for observer memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_observers();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for observer memfuns.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_observers.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_observers();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/* Boost.MultiIndex test for projection capabilities.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_projection.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
void test_projection()
|
||||
{
|
||||
employee_set es;
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
es.insert(employee(1,"Robert",27,5601));
|
||||
es.insert(employee(2,"John",40,7889));
|
||||
es.insert(employee(3,"Albert",20,9012));
|
||||
es.insert(employee(4,"John",57,1002));
|
||||
|
||||
employee_set::iterator it,itbis;
|
||||
employee_set_by_name::iterator it1;
|
||||
employee_set_by_age::iterator it2;
|
||||
employee_set_as_inserted::iterator it3;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set::iterator,
|
||||
nth_index_iterator<employee_set,0>::type >::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set_by_name::iterator,
|
||||
nth_index_iterator<employee_set,1>::type >::value));
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set_by_age::iterator,
|
||||
index_iterator<employee_set,age>::type >::value));
|
||||
#else
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set_by_age::iterator,
|
||||
employee_set::index_iterator<age>::type >::value));
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set_as_inserted::iterator,
|
||||
nth_index_iterator<employee_set,3>::type >::value));
|
||||
|
||||
it= es.find(employee(1,"Robert",27,5601));
|
||||
it1= project<name>(es,it);
|
||||
it2= project<age>(es,it1);
|
||||
it3= project<as_inserted>(es,it2);
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
itbis=project<0>(es,it3);
|
||||
#else
|
||||
itbis=es.project<0>(it3);
|
||||
#endif
|
||||
|
||||
BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it3&&itbis==it);
|
||||
|
||||
const employee_set& ces=es;
|
||||
|
||||
employee_set::const_iterator cit,citbis;
|
||||
employee_set_by_name::const_iterator cit1;
|
||||
employee_set_by_age::const_iterator cit2;
|
||||
employee_set_as_inserted::const_iterator cit3;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set::const_iterator,
|
||||
nth_index_const_iterator<employee_set,0>::type >::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set_by_name::const_iterator,
|
||||
nth_index_const_iterator<employee_set,1>::type >::value));
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set_by_age::const_iterator,
|
||||
index_const_iterator<employee_set,age>::type >::value));
|
||||
#else
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set_by_age::const_iterator,
|
||||
employee_set::index_const_iterator<age>::type >::value));
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT((boost::is_same<
|
||||
employee_set_as_inserted::const_iterator,
|
||||
nth_index_const_iterator<employee_set,3>::type >::value));
|
||||
|
||||
BOOST_CHECK(project<name>(es,es.end())==get<name>(es).end());
|
||||
BOOST_CHECK(project<age>(es,es.end())==get<age>(es).end());
|
||||
BOOST_CHECK(project<as_inserted>(es,es.end())==get<as_inserted>(es).end());
|
||||
|
||||
cit= ces.find(employee(4,"John",57,1002));
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
cit1= project<by_name>(ces,cit);
|
||||
#else
|
||||
cit1= ces.project<by_name>(cit);
|
||||
#endif
|
||||
cit2= project<age>(ces,cit1);
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
cit3= project<as_inserted>(ces,cit2);
|
||||
#else
|
||||
cit3= ces.project<as_inserted>(cit2);
|
||||
#endif
|
||||
citbis=project<0>(ces,cit3);
|
||||
|
||||
BOOST_CHECK(*cit==*cit1&&*cit1==*cit2&&*cit2==*cit3&&citbis==cit);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for projection capabilities.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_projection();
|
||||
@@ -1,20 +0,0 @@
|
||||
/* Boost.MultiIndex test for projection capabilities.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_projection.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_projection();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/* Boost.MultiIndex test for range().
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_range.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include "pre_multi_index.hpp"
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
typedef multi_index_container<int> int_set;
|
||||
typedef int_set::iterator int_set_iterator;
|
||||
|
||||
#undef _
|
||||
#define _ ,
|
||||
|
||||
#undef CHECK_RANGE
|
||||
#define CHECK_RANGE(p,check_range) \
|
||||
{\
|
||||
int v[]=check_range;\
|
||||
std::size_t size_v=sizeof(v)/sizeof(int);\
|
||||
BOOST_CHECK(std::size_t(std::distance((p).first,(p).second))==size_v);\
|
||||
BOOST_CHECK(std::equal((p).first,(p).second,v));\
|
||||
}
|
||||
|
||||
#undef CHECK_VOID_RANGE
|
||||
#define CHECK_VOID_RANGE(p) BOOST_CHECK((p).first==(p).second)
|
||||
|
||||
void test_range()
|
||||
{
|
||||
int_set is;
|
||||
|
||||
for(int i=1;i<=10;++i)is.insert(i);
|
||||
|
||||
std::pair<int_set::iterator,int_set::iterator> p;
|
||||
|
||||
p=is.range(unbounded,unbounded);
|
||||
CHECK_RANGE(p,{1 _ 2 _ 3 _ 4 _ 5 _ 6 _ 7 _ 8 _ 9 _ 10});
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less<int>(),5), /* 5 < x */
|
||||
unbounded);
|
||||
CHECK_RANGE(p,{6 _ 7 _ 8 _ 9 _ 10});
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less_equal<int>(),8), /* 8 <= x */
|
||||
unbounded);
|
||||
CHECK_RANGE(p,{8 _ 9 _ 10});
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less_equal<int>(),11), /* 11 <= x */
|
||||
unbounded);
|
||||
CHECK_VOID_RANGE(p);
|
||||
|
||||
p=is.range(
|
||||
unbounded,
|
||||
std::bind2nd(std::less<int>(),8)); /* x < 8 */
|
||||
CHECK_RANGE(p,{1 _ 2 _ 3 _ 4 _ 5 _ 6 _ 7});
|
||||
|
||||
p=is.range(
|
||||
unbounded,
|
||||
std::bind2nd(std::less_equal<int>(),4)); /* x <= 4 */
|
||||
CHECK_RANGE(p,{1 _ 2 _ 3 _ 4});
|
||||
|
||||
p=is.range(
|
||||
unbounded,
|
||||
std::bind2nd(std::less_equal<int>(),0)); /* x <= 0 */
|
||||
CHECK_VOID_RANGE(p);
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less<int>(),6), /* 6 < x */
|
||||
std::bind2nd(std::less_equal<int>(),9)); /* x <= 9 */
|
||||
CHECK_RANGE(p,{7 _ 8 _ 9});
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less_equal<int>(),4), /* 4 <= x */
|
||||
std::bind2nd(std::less<int>(),5)); /* x < 5 */
|
||||
CHECK_RANGE(p,{4});
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less_equal<int>(),10), /* 10 <= x */
|
||||
std::bind2nd(std::less_equal<int>(),10)); /* x <= 10 */
|
||||
CHECK_RANGE(p,{10});
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less<int>(),0), /* 0 < x */
|
||||
std::bind2nd(std::less<int>(),11)); /* x < 11 */
|
||||
CHECK_RANGE(p,{1 _ 2 _ 3 _ 4 _ 5 _ 6 _ 7 _ 8 _ 9 _ 10});
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less<int>(),7), /* 7 < x */
|
||||
std::bind2nd(std::less_equal<int>(),7)); /* x <= 7 */
|
||||
CHECK_VOID_RANGE(p);
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less_equal<int>(),8), /* 8 <= x */
|
||||
std::bind2nd(std::less<int>(),2)); /* x < 2 */
|
||||
CHECK_VOID_RANGE(p);
|
||||
|
||||
p=is.range(
|
||||
std::bind1st(std::less<int>(),4), /* 4 < x */
|
||||
std::bind2nd(std::less<int>(),5)); /* x < 5 */
|
||||
CHECK_VOID_RANGE(p);
|
||||
BOOST_CHECK(p.first!=is.end()&&p.second!=is.end());
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for range().
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_range();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for range().
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_range.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_range();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,353 +0,0 @@
|
||||
/* Boost.MultiIndex test for safe_mode.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_safe_mode.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include "pre_multi_index.hpp"
|
||||
#include "employee.hpp"
|
||||
#include "pair_of_ints.hpp"
|
||||
#include <stdexcept>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
#define TRY_SAFE_MODE \
|
||||
try{
|
||||
|
||||
#define CATCH_SAFE_MODE(err) \
|
||||
throw std::runtime_error("safe mode violation not detected");\
|
||||
}catch(const safe_mode_exception& e){\
|
||||
if(e.error_code!=(err))throw std::runtime_error(\
|
||||
"safe mode violation not expected");\
|
||||
}
|
||||
|
||||
struct change_id
|
||||
{
|
||||
change_id(int new_id_):new_id(new_id_){}
|
||||
void operator()(employee& e){e.id=new_id;}
|
||||
|
||||
private:
|
||||
int new_id;
|
||||
};
|
||||
|
||||
struct change_ssn
|
||||
{
|
||||
change_ssn(int new_ssn_):new_ssn(new_ssn_){}
|
||||
void operator()(employee& e){e.ssn=new_ssn;}
|
||||
|
||||
private:
|
||||
int new_ssn;
|
||||
};
|
||||
|
||||
typedef multi_index_container<
|
||||
pair_of_ints,
|
||||
indexed_by<
|
||||
ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
|
||||
ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> > >
|
||||
int_int_set;
|
||||
|
||||
void test_safe_mode()
|
||||
{
|
||||
employee_set es,es2;
|
||||
employee_set_by_name& i1=get<name>(es);
|
||||
employee_set_by_name& i2=get<name>(es2);
|
||||
employee_set_as_inserted& ii=get<as_inserted>(es);
|
||||
es.insert(employee(0,"Joe",31,1123));
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it;
|
||||
employee_set::iterator it2=es.begin();
|
||||
it2=it;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it;
|
||||
employee_set_by_name::iterator it2=i1.begin();
|
||||
it2=it;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it;
|
||||
employee e=*it;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it;
|
||||
employee e=*it;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.end();
|
||||
employee e=*it;
|
||||
CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=i1.end();
|
||||
employee e=*it;
|
||||
CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.end();
|
||||
++it;
|
||||
CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=i1.end();
|
||||
++it;
|
||||
CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.begin();
|
||||
--it;
|
||||
CATCH_SAFE_MODE(safe_mode::not_decrementable_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it;
|
||||
employee_set::iterator it2;
|
||||
bool b=(it==it2);
|
||||
b=true; /* avoid warning about unused var */
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it;
|
||||
employee_set_by_name::iterator it2;
|
||||
bool b=(it==it2);
|
||||
b=true; /* avoid warning about unused var */
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.begin();
|
||||
employee_set::iterator it2;
|
||||
bool b=(it==it2);
|
||||
b=true; /* avoid warning about unused var */
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=i1.begin();
|
||||
employee_set_by_name::iterator it2;
|
||||
bool b=(it==it2);
|
||||
b=true; /* avoid warning about unused var */
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.begin();
|
||||
employee_set::iterator it2=es2.begin();
|
||||
bool b=(it==it2);
|
||||
b=true; /* avoid warning about unused var */
|
||||
CATCH_SAFE_MODE(safe_mode::not_same_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=i1.begin();
|
||||
employee_set_by_name::iterator it2=i2.begin();
|
||||
bool b=(it==it2);
|
||||
b=true; /* avoid warning about unused var */
|
||||
CATCH_SAFE_MODE(safe_mode::not_same_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
es.erase(es.end(),es.begin());
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_range)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
i1.erase(i1.end(),i1.begin());
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_range)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it;
|
||||
es.insert(it,employee(0,"Joe",31,1123));
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it;
|
||||
i1.insert(it,employee(0,"Joe",31,1123));
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
es.erase(es.end());
|
||||
CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
i1.erase(i1.end());
|
||||
CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.begin();
|
||||
es2.insert(it,employee(0,"Joe",31,1123));
|
||||
CATCH_SAFE_MODE(safe_mode::not_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=i1.begin();
|
||||
i2.insert(it,employee(0,"Joe",31,1123));
|
||||
CATCH_SAFE_MODE(safe_mode::not_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.begin();
|
||||
employee_set::iterator it2=es2.end();
|
||||
es2.erase(it,it2);
|
||||
CATCH_SAFE_MODE(safe_mode::not_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=i1.begin();
|
||||
employee_set_by_name::iterator it2=i2.end();
|
||||
i2.erase(it,it2);
|
||||
CATCH_SAFE_MODE(safe_mode::not_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.insert(employee(1,"Robert",27,5601)).first;
|
||||
es.erase(it);
|
||||
es.erase(it);
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=
|
||||
i1.insert(employee(1,"Robert",27,5601)).first;
|
||||
i1.erase(it);
|
||||
i1.erase(it);
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set es3(es);
|
||||
employee_set::iterator it=es3.insert(employee(1,"Robert",27,5601)).first;
|
||||
es3.clear();
|
||||
es3.erase(it);
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set es3(es);
|
||||
employee_set_by_name::iterator it=
|
||||
get<name>(es3).insert(employee(1,"Robert",27,5601)).first;
|
||||
get<name>(es3).clear();
|
||||
get<name>(es3).erase(it);
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it;
|
||||
{
|
||||
employee_set es3;
|
||||
it=es3.insert(employee(0,"Joe",31,1123)).first;
|
||||
}
|
||||
employee e=*it;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it;
|
||||
{
|
||||
employee_set es3;
|
||||
it=get<name>(es3).insert(employee(0,"Joe",31,1123)).first;
|
||||
}
|
||||
employee e=*it;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it;
|
||||
{
|
||||
employee_set es3;
|
||||
it=es3.insert(employee(0,"Joe",31,1123)).first;
|
||||
}
|
||||
employee_set::iterator it2;
|
||||
it2=it;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it;
|
||||
{
|
||||
employee_set es3;
|
||||
it=get<name>(es3).insert(employee(0,"Joe",31,1123)).first;
|
||||
}
|
||||
employee_set_by_name::iterator it2;
|
||||
it2=it;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set es3(es);
|
||||
employee_set es4;
|
||||
employee_set::iterator it=es3.begin();
|
||||
es3.swap(es4);
|
||||
es3.erase(it);
|
||||
CATCH_SAFE_MODE(safe_mode::not_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set es3(es);
|
||||
employee_set es4;
|
||||
employee_set_by_name::iterator it=get<name>(es3).begin();
|
||||
es3.swap(es4);
|
||||
get<name>(es3).erase(it);
|
||||
CATCH_SAFE_MODE(safe_mode::not_owner)
|
||||
|
||||
/* these, unlike the previous case, are indeed correct, test safe mode
|
||||
* gets it right
|
||||
*/
|
||||
{
|
||||
employee_set es3(es);
|
||||
employee_set es4;
|
||||
employee_set::iterator it=es3.begin();
|
||||
es3.swap(es4);
|
||||
es4.erase(it);
|
||||
}
|
||||
|
||||
{
|
||||
employee_set es3(es);
|
||||
employee_set es4;
|
||||
employee_set_by_name::iterator it=get<name>(es3).begin();
|
||||
es3.swap(es4);
|
||||
get<name>(es4).erase(it);
|
||||
}
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.insert(employee(1,"Robert",27,5601)).first;
|
||||
employee_set_by_name::iterator it2=project<name>(es,it);
|
||||
es.modify_key(it,change_id(0));
|
||||
employee e=*it2;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=
|
||||
i1.insert(employee(1,"Robert",27,5601)).first;
|
||||
employee_set::iterator it2=project<0>(es,it);
|
||||
i1.modify(it,change_ssn(1123));
|
||||
employee e=*it2;
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
int_int_set iis;
|
||||
int_int_set::iterator it=iis.insert(pair_of_ints(0,0)).first;
|
||||
iis.insert(pair_of_ints(1,1));
|
||||
iis.modify(it,increment_first);
|
||||
pair_of_ints p=*it;
|
||||
p.first=0; /* avoid warning about unused var */
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
int_int_set iis;
|
||||
int_int_set::iterator it=iis.insert(pair_of_ints(0,0)).first;
|
||||
iis.insert(pair_of_ints(1,1));
|
||||
iis.modify(it,increment_second);
|
||||
pair_of_ints p=*it;
|
||||
p.first=0; /* avoid warning about unused var */
|
||||
CATCH_SAFE_MODE(safe_mode::invalid_iterator)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set::iterator it=es.end();
|
||||
employee_set_by_name::iterator it2=project<name>(es2,it);
|
||||
CATCH_SAFE_MODE(safe_mode::not_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
employee_set_by_name::iterator it=get<name>(es).end();
|
||||
employee_set::iterator it2=project<0>(es2,it);
|
||||
CATCH_SAFE_MODE(safe_mode::not_owner)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
ii.splice(ii.begin(),ii,ii.begin(),ii.end());
|
||||
CATCH_SAFE_MODE(safe_mode::inside_range)
|
||||
|
||||
TRY_SAFE_MODE
|
||||
ii.splice(ii.begin(),ii);
|
||||
CATCH_SAFE_MODE(safe_mode::same_container)
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test for safe mode.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_safe_mode();
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Boost.MultiIndex test for safe mode.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_safe_mode.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_safe_mode();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
/* Boost.MultiIndex test for serialization.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_serialization.hpp"
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include "pre_multi_index.hpp"
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/multi_index/key_extractors.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "pair_of_ints.hpp"
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
template<int N>
|
||||
struct all_indices_equal_helper
|
||||
{
|
||||
template<class MultiIndexContainer>
|
||||
static bool compare(
|
||||
const MultiIndexContainer& m1,const MultiIndexContainer& m2)
|
||||
{
|
||||
if(!(get<N>(m1)==get<N>(m2))){
|
||||
return false;
|
||||
}
|
||||
return all_indices_equal_helper<N-1>::compare(m1,m2);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct all_indices_equal_helper<0>
|
||||
{
|
||||
template<class MultiIndexContainer>
|
||||
static bool compare(
|
||||
const MultiIndexContainer& m1,const MultiIndexContainer& m2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<class MultiIndexContainer>
|
||||
bool all_indices_equal(
|
||||
const MultiIndexContainer& m1,const MultiIndexContainer& m2)
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int,
|
||||
N=boost::mpl::size<
|
||||
BOOST_DEDUCED_TYPENAME MultiIndexContainer::index_type_list>::type::value);
|
||||
|
||||
return all_indices_equal_helper<N-1>::compare(m1,m2);
|
||||
}
|
||||
|
||||
template<class MultiIndexContainer>
|
||||
void test_serialization(const MultiIndexContainer& m)
|
||||
{
|
||||
typedef typename MultiIndexContainer::iterator iterator;
|
||||
typedef typename MultiIndexContainer::const_iterator const_iterator;
|
||||
|
||||
std::ostringstream oss;
|
||||
{
|
||||
boost::archive::text_oarchive oa(oss);
|
||||
oa<<m;
|
||||
|
||||
std::vector<const_iterator> its(m.size());
|
||||
const_iterator it_end=m.end();
|
||||
for(const_iterator it=m.begin();it!=it_end;++it){
|
||||
its.push_back(it);
|
||||
oa<<const_cast<const const_iterator&>(its.back());
|
||||
}
|
||||
oa<<const_cast<const const_iterator&>(it_end);
|
||||
}
|
||||
|
||||
MultiIndexContainer m2;
|
||||
std::istringstream iss(oss.str());
|
||||
boost::archive::text_iarchive ia(iss);
|
||||
ia>>m2;
|
||||
BOOST_CHECK(all_indices_equal(m,m2));
|
||||
|
||||
iterator it_end=m2.end();
|
||||
for(iterator it=m2.begin();it!=it_end;++it){
|
||||
iterator it2;
|
||||
ia>>it2;
|
||||
BOOST_CHECK(it==it2);
|
||||
|
||||
/* exercise safe mode with this (unchecked) iterator */
|
||||
BOOST_CHECK(*it==*it2);
|
||||
m2.erase(it,it2);
|
||||
m2.erase(it2,it2);
|
||||
m2.erase(it2,it);
|
||||
iterator it3(++it2);
|
||||
iterator it4;
|
||||
it4=--it2;
|
||||
BOOST_CHECK(it==it4);
|
||||
BOOST_CHECK(it==project<0>(m2,it4));
|
||||
}
|
||||
iterator it2;
|
||||
ia>>it2;
|
||||
BOOST_CHECK(it_end==it2);
|
||||
BOOST_CHECK(it_end==project<0>(m2,it2));
|
||||
}
|
||||
|
||||
void test_hashed_index_serialization()
|
||||
{
|
||||
const int N=100;
|
||||
const int SHUFFLE=10232;
|
||||
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
hashed_unique<identity<int> >,
|
||||
sequenced<>
|
||||
>
|
||||
> hashed_set;
|
||||
|
||||
typedef hashed_set::iterator iterator;
|
||||
typedef hashed_set::local_iterator local_iterator;
|
||||
|
||||
hashed_set hs;
|
||||
|
||||
for(int i=0;i<N;++i){
|
||||
hs.insert(i*SHUFFLE);
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
{
|
||||
boost::archive::text_oarchive oa(oss);
|
||||
oa<<const_cast<const hashed_set&>(hs);
|
||||
|
||||
std::vector<iterator> its(N);
|
||||
for(int i=0;i<N;++i){
|
||||
iterator it=hs.find(i*SHUFFLE);
|
||||
its.push_back(it);
|
||||
oa<<const_cast<const iterator&>(its.back());
|
||||
}
|
||||
iterator it=hs.end();
|
||||
oa<<const_cast<const iterator&>(it);
|
||||
|
||||
std::vector<local_iterator> lits(2*N);
|
||||
for(std::size_t buc=0;buc<hs.bucket_count();++buc){
|
||||
for(local_iterator lit=hs.begin(buc),lit_end=hs.end(buc);
|
||||
lit!=lit_end;++lit){
|
||||
oa<<*lit;
|
||||
lits.push_back(lit);
|
||||
oa<<const_cast<const local_iterator&>(lits.back());
|
||||
}
|
||||
local_iterator lit2=hs.end(buc);
|
||||
lits.push_back(lit2);
|
||||
oa<<const_cast<const local_iterator&>(lits.back());
|
||||
}
|
||||
}
|
||||
|
||||
hashed_set hs2;
|
||||
std::istringstream iss(oss.str());
|
||||
boost::archive::text_iarchive ia(iss);
|
||||
ia>>hs2;
|
||||
BOOST_CHECK(get<1>(hs)==get<1>(hs2));
|
||||
|
||||
for(int j=0;j<N;++j){
|
||||
iterator it;
|
||||
ia>>it;
|
||||
BOOST_CHECK(*it==j*SHUFFLE);
|
||||
}
|
||||
iterator it;
|
||||
ia>>it;
|
||||
BOOST_CHECK(it==hs2.end());
|
||||
|
||||
for(std::size_t buc=0;buc<hs2.bucket_count();++buc){
|
||||
for(std::size_t k=0;k<hs2.bucket_size(buc);++k){
|
||||
int n;
|
||||
local_iterator it;
|
||||
ia>>n;
|
||||
ia>>it;
|
||||
BOOST_CHECK(*it==n);
|
||||
}
|
||||
local_iterator it2;
|
||||
ia>>it2;
|
||||
BOOST_CHECK(it2==hs2.end(buc));
|
||||
}
|
||||
}
|
||||
|
||||
void test_serialization()
|
||||
{
|
||||
{
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
sequenced<>,
|
||||
sequenced<>
|
||||
>
|
||||
> multi_index_t;
|
||||
|
||||
multi_index_t m;
|
||||
for(int i=0;i<100;++i)m.push_back(i);
|
||||
m.reverse();
|
||||
test_serialization(m);
|
||||
|
||||
m.clear();
|
||||
for(int j=50;j<100;++j)m.push_back(j);
|
||||
for(int k=0;k<50;++k)m.push_back(k);
|
||||
m.sort();
|
||||
test_serialization(m);
|
||||
}
|
||||
{
|
||||
typedef multi_index_container<
|
||||
int,
|
||||
indexed_by<
|
||||
sequenced<>,
|
||||
ordered_non_unique<identity<int> >
|
||||
>
|
||||
> multi_index_t;
|
||||
|
||||
multi_index_t m;
|
||||
for(int i=0;i<100;++i){
|
||||
m.push_back(i);
|
||||
m.push_back(i);
|
||||
m.push_back(i);
|
||||
}
|
||||
m.reverse();
|
||||
test_serialization(m);
|
||||
}
|
||||
{
|
||||
typedef multi_index_container<
|
||||
pair_of_ints,
|
||||
indexed_by<
|
||||
ordered_unique<
|
||||
BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)
|
||||
>,
|
||||
ordered_non_unique<
|
||||
BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)
|
||||
>,
|
||||
sequenced<>
|
||||
>
|
||||
> multi_index_t;
|
||||
|
||||
multi_index_t m;
|
||||
test_serialization(m);
|
||||
|
||||
m.insert(pair_of_ints(4,0));
|
||||
test_serialization(m);
|
||||
|
||||
m.insert(pair_of_ints(3,1));
|
||||
m.insert(pair_of_ints(2,1));
|
||||
test_serialization(m);
|
||||
|
||||
m.insert(pair_of_ints(1,1));
|
||||
test_serialization(m);
|
||||
|
||||
m.insert(pair_of_ints(0,0));
|
||||
test_serialization(m);
|
||||
|
||||
m.insert(pair_of_ints(5,1));
|
||||
m.insert(pair_of_ints(7,1));
|
||||
m.insert(pair_of_ints(6,1));
|
||||
test_serialization(m);
|
||||
|
||||
m.insert(pair_of_ints(8,1));
|
||||
m.insert(pair_of_ints(9,1));
|
||||
m.insert(pair_of_ints(12,1));
|
||||
m.insert(pair_of_ints(11,1));
|
||||
m.insert(pair_of_ints(10,1));
|
||||
test_serialization(m);
|
||||
}
|
||||
test_hashed_index_serialization();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Boost.MultiIndex test test for serialization.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void test_serialization();
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Boost.MultiIndex test for serialization.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include "test_serialization.hpp"
|
||||
|
||||
int test_main(int,char *[])
|
||||
{
|
||||
test_serialization();
|
||||
return 0;
|
||||
}
|
||||